Skip to content

Commit cf87bd0

Browse files
committed
Build DisplayList Decoder
0 parents  commit cf87bd0

17 files changed

Lines changed: 3060 additions & 0 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
test-and-build:
12+
runs-on: ubuntu-latest
13+
container: swift:6.2
14+
steps:
15+
- uses: actions/checkout@v7
16+
- uses: actions/setup-node@v7
17+
with:
18+
node-version: 24
19+
cache: npm
20+
- uses: swiftwasm/setup-swiftwasm@v2
21+
id: swiftwasm
22+
with:
23+
target: wasm32-unknown-wasip1
24+
- name: Test converter
25+
run: swift test
26+
- name: Build SwiftWasm package
27+
run: swift package --swift-sdk "${{ steps.swiftwasm.outputs.swift-sdk-id }}" js -c release
28+
- name: Build site
29+
run: |
30+
npm ci
31+
npm run build

‎.github/workflows/deploy-pages.yml‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
container: swift:6.2
21+
steps:
22+
- uses: actions/checkout@v7
23+
- uses: actions/setup-node@v7
24+
with:
25+
node-version: 24
26+
cache: npm
27+
- uses: actions/configure-pages@v6
28+
id: pages
29+
- uses: swiftwasm/setup-swiftwasm@v2
30+
id: swiftwasm
31+
with:
32+
target: wasm32-unknown-wasip1
33+
- name: Test converter
34+
run: swift test
35+
- name: Build SwiftWasm package
36+
run: swift package --swift-sdk "${{ steps.swiftwasm.outputs.swift-sdk-id }}" js -c release
37+
- name: Build site
38+
run: |
39+
npm ci
40+
npm run build -- --base "${{ steps.pages.outputs.base_path }}/"
41+
- uses: actions/upload-pages-artifact@v5
42+
with:
43+
path: dist
44+
45+
deploy:
46+
environment:
47+
name: github-pages
48+
url: ${{ steps.deployment.outputs.page_url }}
49+
runs-on: ubuntu-latest
50+
needs: build
51+
steps:
52+
- name: Deploy to GitHub Pages
53+
id: deployment
54+
uses: actions/deploy-pages@v5

‎.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.build/
2+
.swiftpm/
3+
dist/
4+
node_modules/
5+
.DS_Store
6+
*.xcworkspace
7+
xcuserdata/

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Kyle-Ye
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎Package.resolved‎

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Package.swift‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// swift-tools-version: 6.2
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "DisplayListDescription",
7+
platforms: [
8+
.macOS(.v13),
9+
],
10+
products: [
11+
.library(
12+
name: "DisplayListDescription",
13+
targets: ["DisplayListDescription"]
14+
),
15+
.executable(
16+
name: "DisplayListWeb",
17+
targets: ["DisplayListWeb"]
18+
),
19+
],
20+
dependencies: [
21+
.package(
22+
url: "https://github.com/swiftwasm/JavaScriptKit.git",
23+
exact: "0.57.0"
24+
),
25+
],
26+
targets: [
27+
.target(
28+
name: "DisplayListDescription"
29+
),
30+
.executableTarget(
31+
name: "DisplayListWeb",
32+
dependencies: [
33+
"DisplayListDescription",
34+
.product(name: "JavaScriptKit", package: "JavaScriptKit"),
35+
]
36+
),
37+
.testTarget(
38+
name: "DisplayListDescriptionTests",
39+
dependencies: ["DisplayListDescription"]
40+
),
41+
],
42+
swiftLanguageModes: [.v5]
43+
)

‎README.md‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# DisplayList Decoder
2+
3+
DisplayList Decoder converts a SwiftUI `DisplayList.description` S-expression into its compact `minimalDescription` form and explains every encoding used by the result.
4+
5+
The parser and converter are written in Swift. [JavaScriptKit](https://github.com/swiftwasm/JavaScriptKit) compiles the browser executable to WebAssembly, Vite packages the static assets, and GitHub Actions deploys the result to GitHub Pages.
6+
7+
## Features
8+
9+
- Converts content, effects, nested flattened lists, effect children, and state variants.
10+
- Reproduces the single-line formatting emitted by `SExpPrinter`.
11+
- Highlights the encodings present in the current result.
12+
- Runs entirely in the browser; pasted descriptions are not uploaded.
13+
- Tests the conversion engine natively with SwiftPM before every deployment.
14+
15+
The mapping follows OpenSwiftUI's [`DisplayListPrinter.swift`](https://github.com/OpenSwiftUIProject/OpenSwiftUI/blob/main/Sources/OpenSwiftUICore/Render/DisplayList/DisplayListPrinter.swift), audited for SwiftUI 6.5.4. The interaction model is inspired by [SwiftFiddle/swiftregex](https://github.com/SwiftFiddle/swiftregex).
16+
17+
### Known ambiguity
18+
19+
`DisplayList.description` prints identity effects, empty property effects, and platform effects with the same empty `(effect …)` form, while `minimalDescription` encodes them differently. Because the source text has already discarded that distinction, the converter renders an empty effect as identity and calls out the ambiguity in the interface.
20+
21+
## Local development
22+
23+
Prerequisites:
24+
25+
- Swift 6.2 or newer
26+
- A matching `wasm32-unknown-wasip1` Swift SDK
27+
- Node.js 24 or newer
28+
29+
Build the Swift package for WebAssembly, install the web dependencies, and start Vite:
30+
31+
```sh
32+
swift package --swift-sdk "$SWIFT_SDK_ID" js
33+
npm ci
34+
npm run dev
35+
```
36+
37+
Run the native converter tests with:
38+
39+
```sh
40+
swift test
41+
```
42+
43+
## GitHub Pages
44+
45+
Pushes to `main` run the converter tests, build the SwiftWasm package, bundle the site with the repository's Pages base path, and deploy the `dist` artifact. The repository's Pages source must be set to **GitHub Actions**.
46+
47+
## License
48+
49+
DisplayList Decoder is available under the MIT License.

0 commit comments

Comments
 (0)