@swiftbrowser/web 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +600 -0
  2. package/app/index.html +125 -0
  3. package/index.html +56 -0
  4. package/node/dist/node/apps.d.ts +58 -0
  5. package/node/dist/node/apps.d.ts.map +1 -0
  6. package/node/dist/node/apps.js +60 -0
  7. package/node/dist/node/apps.js.map +1 -0
  8. package/node/dist/node/config.d.ts +42 -0
  9. package/node/dist/node/config.d.ts.map +1 -0
  10. package/node/dist/node/config.js +99 -0
  11. package/node/dist/node/config.js.map +1 -0
  12. package/node/dist/node/examples.d.ts +39 -0
  13. package/node/dist/node/examples.d.ts.map +1 -0
  14. package/node/dist/node/examples.js +116 -0
  15. package/node/dist/node/examples.js.map +1 -0
  16. package/node/dist/node/index.d.ts +47 -0
  17. package/node/dist/node/index.d.ts.map +1 -0
  18. package/node/dist/node/index.js +52 -0
  19. package/node/dist/node/index.js.map +1 -0
  20. package/node/dist/plugins/app-manifests.d.ts +61 -0
  21. package/node/dist/plugins/app-manifests.d.ts.map +1 -0
  22. package/node/dist/plugins/app-manifests.js +168 -0
  23. package/node/dist/plugins/app-manifests.js.map +1 -0
  24. package/node/dist/plugins/asset-catalogs.d.ts +119 -0
  25. package/node/dist/plugins/asset-catalogs.d.ts.map +1 -0
  26. package/node/dist/plugins/asset-catalogs.js +488 -0
  27. package/node/dist/plugins/asset-catalogs.js.map +1 -0
  28. package/node/dist/plugins/bundle-resources.d.ts +49 -0
  29. package/node/dist/plugins/bundle-resources.d.ts.map +1 -0
  30. package/node/dist/plugins/bundle-resources.js +172 -0
  31. package/node/dist/plugins/bundle-resources.js.map +1 -0
  32. package/node/dist/plugins/swift-wasm.d.ts +33 -0
  33. package/node/dist/plugins/swift-wasm.d.ts.map +1 -0
  34. package/node/dist/plugins/swift-wasm.js +241 -0
  35. package/node/dist/plugins/swift-wasm.js.map +1 -0
  36. package/node/dist/src/assets.d.ts +60 -0
  37. package/node/dist/src/assets.d.ts.map +1 -0
  38. package/node/dist/src/assets.js +54 -0
  39. package/node/dist/src/assets.js.map +1 -0
  40. package/node/dist/src/devEvents.d.ts +31 -0
  41. package/node/dist/src/devEvents.d.ts.map +1 -0
  42. package/node/dist/src/devEvents.js +9 -0
  43. package/node/dist/src/devEvents.js.map +1 -0
  44. package/package.json +56 -0
  45. package/plugins/app-manifests.ts +192 -0
  46. package/plugins/asset-catalogs.ts +558 -0
  47. package/plugins/bundle-resources.ts +195 -0
  48. package/plugins/swift-wasm.ts +259 -0
  49. package/public/_headers +23 -0
  50. package/public/apple-touch-icon.png +0 -0
  51. package/public/icon.svg +14 -0
  52. package/public/manifest.webmanifest +14 -0
  53. package/src/animation.ts +521 -0
  54. package/src/assets.ts +86 -0
  55. package/src/chartDom.ts +481 -0
  56. package/src/devEvents.ts +35 -0
  57. package/src/deviceMode.ts +80 -0
  58. package/src/ghost.ts +25 -0
  59. package/src/interaction.ts +1113 -0
  60. package/src/landing.css +261 -0
  61. package/src/landing.ts +141 -0
  62. package/src/layout/chart.ts +477 -0
  63. package/src/layout/controls.ts +116 -0
  64. package/src/layout/engine.ts +3581 -0
  65. package/src/layout/index.ts +91 -0
  66. package/src/layout/measure.ts +86 -0
  67. package/src/layout/text.ts +124 -0
  68. package/src/layout/types.ts +153 -0
  69. package/src/layout/typography.ts +188 -0
  70. package/src/layoutDom.ts +549 -0
  71. package/src/layoutEvents.ts +110 -0
  72. package/src/locale.ts +64 -0
  73. package/src/main.ts +554 -0
  74. package/src/mock.ts +752 -0
  75. package/src/nodeQueries.ts +60 -0
  76. package/src/protocol.ts +1421 -0
  77. package/src/renderer.ts +2882 -0
  78. package/src/styles.css +2834 -0
  79. package/src/styles.ts +373 -0
  80. package/src/swipe.ts +110 -0
  81. package/src/symbols.ts +595 -0
  82. package/src/typography.ts +76 -0
  83. package/src/vite-env.d.ts +26 -0
  84. package/src/wasm.ts +400 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * The app's resource files (the Xcode target's Copy Bundle Resources phase,
3
+ * or `resources` in swiftbrowser.json) as one manifest at `/bundle/<App>.json`
4
+ * (`{ files: [{ path, size }] }`) plus the files at `/bundle/<App>/<path>`,
5
+ * dev server and `vite build` alike. The page fetches them before loading the
6
+ * module and mounts them at `/bundle` in the WASI filesystem, where the shim's
7
+ * `Bundle.main` finds them (docs/ops-protocol.md, "Phase 11").
8
+ *
9
+ * A resource entry that is a file is published under its base name, like
10
+ * Xcode copies it; a directory keeps its name and structure (a folder
11
+ * reference). Asset catalogs are not resources here: plugins/asset-catalogs.ts
12
+ * turns them into the catalog manifest.
13
+ */
14
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
15
+ import path from 'node:path';
16
+ export const BUNDLE_DIR = 'bundle';
17
+ const PUBLISHED = /^[A-Za-z0-9_.\-]+$/;
18
+ /** URL path of an app's bundle manifest. */
19
+ export function bundleManifestPath(app) {
20
+ return `/${BUNDLE_DIR}/${app}.json`;
21
+ }
22
+ /** URL path of a file inside an app's bundle. */
23
+ export function bundleFilePath(app, file) {
24
+ return `/${BUNDLE_DIR}/${app}/${file.split('/').map(encodeURIComponent).join('/')}`;
25
+ }
26
+ function walk(dir, prefix, into) {
27
+ for (const entry of readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
28
+ if (entry.name.startsWith('.'))
29
+ continue;
30
+ const full = path.join(dir, entry.name);
31
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
32
+ if (entry.isDirectory())
33
+ walk(full, relative, into);
34
+ else if (entry.isFile())
35
+ into(relative, full);
36
+ }
37
+ }
38
+ /** Lists the resources of a spec as published paths and sources. */
39
+ export function buildBundle(app, resources) {
40
+ const files = new Map();
41
+ const manifest = { files: [] };
42
+ const warnings = [];
43
+ const add = (relative, source) => {
44
+ if (!relative.split('/').every((part) => PUBLISHED.test(part))) {
45
+ warnings.push(`${relative}: resource names may use letters, digits, ".", "_" and "-" only; skipped`);
46
+ return;
47
+ }
48
+ if (manifest.files.some((f) => f.path === relative)) {
49
+ warnings.push(`${relative}: two resources publish under the same name; the first one wins`);
50
+ return;
51
+ }
52
+ manifest.files.push({ path: relative, size: statSync(source).size });
53
+ files.set(`${BUNDLE_DIR}/${app}/${relative}`, source);
54
+ };
55
+ for (const resource of resources ?? []) {
56
+ if (!existsSync(resource)) {
57
+ warnings.push(`${resource}: not found`);
58
+ continue;
59
+ }
60
+ if (statSync(resource).isDirectory())
61
+ walk(resource, path.basename(resource), add);
62
+ else
63
+ add(path.basename(resource), resource);
64
+ }
65
+ return { manifest, files, warnings };
66
+ }
67
+ export function bundleManifestJson(manifest) {
68
+ return JSON.stringify(manifest, null, 2) + '\n';
69
+ }
70
+ /** The app named by a manifest request URL (`/bundle/<App>.json`), or null. */
71
+ export function bundleRequestApp(url) {
72
+ const match = new RegExp(`^/${BUNDLE_DIR}/([A-Za-z0-9_-]+)\\.json(?:\\?|$)`).exec(url);
73
+ return match?.[1] ?? null;
74
+ }
75
+ /** The app and published path of a resource request (`/bundle/<App>/<path>`), or null. */
76
+ export function bundleRequestFile(url) {
77
+ const match = new RegExp(`^/${BUNDLE_DIR}/([A-Za-z0-9_-]+)/([^?]+)(?:\\?|$)`).exec(url);
78
+ if (!match?.[1] || !match[2])
79
+ return null;
80
+ let relative;
81
+ try {
82
+ relative = match[2].split('/').map(decodeURIComponent).join('/');
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ if (!relative.split('/').every((part) => PUBLISHED.test(part) && part !== '.' && part !== '..'))
88
+ return null;
89
+ return { app: match[1], fileName: `${BUNDLE_DIR}/${match[1]}/${relative}` };
90
+ }
91
+ const CONTENT_TYPES = {
92
+ '.json': 'application/json',
93
+ '.txt': 'text/plain; charset=utf-8',
94
+ '.md': 'text/markdown; charset=utf-8',
95
+ '.csv': 'text/csv; charset=utf-8',
96
+ '.xml': 'application/xml',
97
+ '.plist': 'application/xml',
98
+ '.strings': 'text/plain; charset=utf-8',
99
+ '.png': 'image/png',
100
+ '.jpg': 'image/jpeg',
101
+ '.jpeg': 'image/jpeg',
102
+ '.gif': 'image/gif',
103
+ '.svg': 'image/svg+xml',
104
+ '.pdf': 'application/pdf',
105
+ '.mp3': 'audio/mpeg',
106
+ '.m4a': 'audio/mp4',
107
+ '.wav': 'audio/wav',
108
+ '.mp4': 'video/mp4',
109
+ };
110
+ export function bundleContentType(file) {
111
+ return CONTENT_TYPES[path.extname(file).toLowerCase()] ?? 'application/octet-stream';
112
+ }
113
+ export function bundleResources(specs) {
114
+ const byName = new Map(specs.map((spec) => [spec.name, spec]));
115
+ return {
116
+ name: 'swiftbrowser:bundle-resources',
117
+ configureServer(server) {
118
+ const warned = new Set();
119
+ const build = (spec) => {
120
+ const built = buildBundle(spec.name, spec.resources);
121
+ for (const warning of built.warnings) {
122
+ if (warned.has(warning))
123
+ continue;
124
+ warned.add(warning);
125
+ server.config.logger.warn(`[bundle-resources] ${spec.name}: ${warning}`, { timestamp: true });
126
+ }
127
+ return built;
128
+ };
129
+ server.middlewares.use((req, res, next) => {
130
+ const url = req.url ?? '';
131
+ const app = bundleRequestApp(url);
132
+ if (app !== null) {
133
+ const spec = byName.get(app);
134
+ if (!spec) {
135
+ res.statusCode = 404;
136
+ res.end();
137
+ return;
138
+ }
139
+ res.setHeader('Content-Type', 'application/json');
140
+ res.setHeader('Cache-Control', 'no-cache');
141
+ res.end(bundleManifestJson(build(spec).manifest));
142
+ return;
143
+ }
144
+ const file = bundleRequestFile(url);
145
+ if (file === null)
146
+ return next();
147
+ const spec = byName.get(file.app);
148
+ const source = spec ? build(spec).files.get(file.fileName) : undefined;
149
+ if (!source) {
150
+ res.statusCode = 404;
151
+ res.end();
152
+ return;
153
+ }
154
+ res.setHeader('Content-Type', bundleContentType(source));
155
+ res.setHeader('Cache-Control', 'no-cache');
156
+ res.end(readFileSync(source));
157
+ });
158
+ },
159
+ generateBundle() {
160
+ for (const spec of specs) {
161
+ const built = buildBundle(spec.name, spec.resources);
162
+ for (const warning of built.warnings)
163
+ this.warn(`${spec.name}: ${warning}`);
164
+ this.emitFile({ type: 'asset', fileName: `${BUNDLE_DIR}/${spec.name}.json`, source: bundleManifestJson(built.manifest) });
165
+ for (const [fileName, source] of built.files) {
166
+ this.emitFile({ type: 'asset', fileName, source: readFileSync(source) });
167
+ }
168
+ }
169
+ },
170
+ };
171
+ }
172
+ //# sourceMappingURL=bundle-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-resources.js","sourceRoot":"","sources":["../../../plugins/bundle-resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Vite plugin for the registered apps' Wasm modules.
3
+ *
4
+ * Dev server:
5
+ * - Serves `/<name>.wasm` from each spec's `wasm` file (`application/wasm`,
6
+ * never cached). When the file is missing, or its sources changed since the
7
+ * server started, and the spec has a `build`, the request builds it first.
8
+ * - Watches every spec's `watch` directories through the dev server's own
9
+ * chokidar watcher, debounces changes (300ms) and runs `spec.build()` for
10
+ * every app whose sources changed among those the page has requested since
11
+ * the server started (`/<name>.wasm` requests register an app). Builds run
12
+ * one at a time.
13
+ * - Sends `sb:build-start` / `sb:build-end` websocket events so the page can
14
+ * show a "Rebuilding…" indicator, then a `full-reload` on success or an
15
+ * `sb:build-error` with the compiler output on failure. The page stashes the
16
+ * app's `@State` snapshot before the reload and feeds it back through the
17
+ * `SB_STATE` WASI environment variable (see src/main.ts).
18
+ *
19
+ * `vite build`: copies each spec's `wasm` into the output directory as
20
+ * `<name>.wasm` (building it first when it is missing and the spec can), so
21
+ * nothing has to ride along in `public/`. Files that are there anyway are
22
+ * still copied by Vite as before.
23
+ */
24
+ import type { Plugin } from 'vite';
25
+ import type { AppSpec } from '../node/apps.js';
26
+ export interface SwiftWasmOptions {
27
+ /** Debounce window for bursts of file changes, in ms. */
28
+ debounceMs?: number;
29
+ }
30
+ /** The app named by a module request URL (`/<name>.wasm`), or null. */
31
+ export declare function wasmRequestApp(url: string): string | null;
32
+ export declare function swiftWasm(specs: readonly AppSpec[], options?: SwiftWasmOptions): Plugin;
33
+ //# sourceMappingURL=swift-wasm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-wasm.d.ts","sourceRoot":"","sources":["../../../plugins/swift-wasm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,MAAM,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzD;AAcD,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,OAAO,GAAE,gBAAqB,GAAG,MAAM,CA6M3F"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Vite plugin for the registered apps' Wasm modules.
3
+ *
4
+ * Dev server:
5
+ * - Serves `/<name>.wasm` from each spec's `wasm` file (`application/wasm`,
6
+ * never cached). When the file is missing, or its sources changed since the
7
+ * server started, and the spec has a `build`, the request builds it first.
8
+ * - Watches every spec's `watch` directories through the dev server's own
9
+ * chokidar watcher, debounces changes (300ms) and runs `spec.build()` for
10
+ * every app whose sources changed among those the page has requested since
11
+ * the server started (`/<name>.wasm` requests register an app). Builds run
12
+ * one at a time.
13
+ * - Sends `sb:build-start` / `sb:build-end` websocket events so the page can
14
+ * show a "Rebuilding…" indicator, then a `full-reload` on success or an
15
+ * `sb:build-error` with the compiler output on failure. The page stashes the
16
+ * app's `@State` snapshot before the reload and feeds it back through the
17
+ * `SB_STATE` WASI environment variable (see src/main.ts).
18
+ *
19
+ * `vite build`: copies each spec's `wasm` into the output directory as
20
+ * `<name>.wasm` (building it first when it is missing and the spec can), so
21
+ * nothing has to ride along in `public/`. Files that are there anyway are
22
+ * still copied by Vite as before.
23
+ */
24
+ import { copyFileSync, createReadStream, existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'node:fs';
25
+ import path from 'node:path';
26
+ /** The app named by a module request URL (`/<name>.wasm`), or null. */
27
+ export function wasmRequestApp(url) {
28
+ const match = /^\/([A-Za-z0-9_-]+)\.wasm(?:\?|$)/.exec(url);
29
+ return match?.[1] ?? null;
30
+ }
31
+ /** The message of a rejected `build()`: the compiler output. */
32
+ function failureOutput(error) {
33
+ if (error instanceof Error)
34
+ return error.message;
35
+ return String(error);
36
+ }
37
+ export function swiftWasm(specs, options = {}) {
38
+ const debounceMs = options.debounceMs ?? 300;
39
+ const byName = new Map(specs.map((spec) => [spec.name, spec]));
40
+ let config;
41
+ let server;
42
+ const log = (message) => {
43
+ config?.logger.info(`[swift-wasm] ${message}`, { timestamp: true });
44
+ };
45
+ // -------------------------------------------------------------------------
46
+ // Dev server: build queue
47
+ // -------------------------------------------------------------------------
48
+ /** Apps requested since the server started; their sources trigger rebuilds. */
49
+ const tracked = new Set();
50
+ /** Tracked apps whose sources changed since their last build. */
51
+ const dirty = new Set();
52
+ /** Untracked apps whose sources changed: rebuilt before the first request serves them. */
53
+ const stale = new Set();
54
+ /** The build in flight or queued for an app, so a request can wait for it instead of starting another. */
55
+ const queued = new Map();
56
+ /** Builds run one at a time (SwiftPM shares one `.build` directory). */
57
+ let queue = Promise.resolve();
58
+ let timer;
59
+ const runBatch = async (targets) => {
60
+ const started = Date.now();
61
+ log(`building ${targets.join(', ')}…`);
62
+ server?.ws.send('sb:build-start', { apps: targets });
63
+ const result = { ok: true };
64
+ for (const app of targets) {
65
+ const spec = byName.get(app);
66
+ if (!spec?.build)
67
+ continue;
68
+ try {
69
+ await spec.build();
70
+ }
71
+ catch (error) {
72
+ const output = failureOutput(error);
73
+ result.ok = false;
74
+ result.failure = { app, output };
75
+ log(`build failed for ${app}`);
76
+ for (const line of output.split('\n'))
77
+ if (line.trim())
78
+ log(` ${line}`);
79
+ server?.ws.send('sb:build-error', { app, output });
80
+ break;
81
+ }
82
+ }
83
+ const durationMs = Date.now() - started;
84
+ server?.ws.send('sb:build-end', { apps: targets, ok: result.ok, durationMs });
85
+ if (result.ok) {
86
+ log(`built ${targets.join(', ')} in ${(durationMs / 1000).toFixed(1)}s; reloading`);
87
+ server?.ws.send({ type: 'full-reload', path: '*' });
88
+ }
89
+ return result;
90
+ };
91
+ const enqueue = (targets) => {
92
+ const batch = queue.then(() => runBatch(targets));
93
+ queue = batch.catch(() => undefined);
94
+ for (const app of targets) {
95
+ queued.set(app, batch);
96
+ void batch.finally(() => {
97
+ if (queued.get(app) === batch)
98
+ queued.delete(app);
99
+ });
100
+ }
101
+ return batch;
102
+ };
103
+ /** Waits for the build of `app` if one is queued, else queues one. */
104
+ const ensureBuilt = (app) => queued.get(app) ?? enqueue([app]);
105
+ const flushDirty = () => {
106
+ const targets = Array.from(dirty).filter((app) => !queued.has(app));
107
+ dirty.clear();
108
+ if (targets.length === 0)
109
+ return;
110
+ void enqueue(targets);
111
+ };
112
+ const schedule = () => {
113
+ if (timer)
114
+ clearTimeout(timer);
115
+ timer = setTimeout(() => {
116
+ timer = undefined;
117
+ flushDirty();
118
+ }, debounceMs);
119
+ };
120
+ // -------------------------------------------------------------------------
121
+ // Dev server: serving `/<name>.wasm`
122
+ // -------------------------------------------------------------------------
123
+ const serveWasm = async (spec, res, method) => {
124
+ if (spec.build && (!existsSync(spec.wasm) || stale.has(spec.name))) {
125
+ if (!existsSync(spec.wasm))
126
+ log(`${spec.name}: ${path.basename(spec.wasm)} is missing; building it first`);
127
+ stale.delete(spec.name);
128
+ const result = await ensureBuilt(spec.name);
129
+ if (!result.ok && !existsSync(spec.wasm)) {
130
+ res.statusCode = 500;
131
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
132
+ res.end(`Build failed for ${spec.name}:\n${result.failure?.output ?? ''}`);
133
+ return;
134
+ }
135
+ }
136
+ if (!existsSync(spec.wasm)) {
137
+ res.statusCode = 404;
138
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
139
+ res.end(`${spec.name}: ${spec.wasm} does not exist`);
140
+ return;
141
+ }
142
+ res.statusCode = 200;
143
+ res.setHeader('Content-Type', 'application/wasm');
144
+ res.setHeader('Cache-Control', 'no-cache');
145
+ res.setHeader('Content-Length', String(statSync(spec.wasm).size));
146
+ if (method === 'HEAD') {
147
+ res.end();
148
+ return;
149
+ }
150
+ createReadStream(spec.wasm).pipe(res);
151
+ };
152
+ // -------------------------------------------------------------------------
153
+ // `vite build`: copy the modules into the bundle
154
+ // -------------------------------------------------------------------------
155
+ const copyModules = async (outDir) => {
156
+ for (const spec of specs) {
157
+ if (!existsSync(spec.wasm) && spec.build) {
158
+ log(`${spec.name}: ${spec.wasm} is missing; building it`);
159
+ await spec.build();
160
+ }
161
+ if (!existsSync(spec.wasm)) {
162
+ if (spec.build)
163
+ throw new Error(`[swift-wasm] ${spec.name}: ${spec.wasm} still does not exist after building it`);
164
+ config?.logger.warn(`[swift-wasm] ${spec.name}: ${spec.wasm} does not exist; the site has no module for it`);
165
+ continue;
166
+ }
167
+ mkdirSync(outDir, { recursive: true });
168
+ const dest = path.join(outDir, `${spec.name}.wasm`);
169
+ if (path.resolve(spec.wasm) !== path.resolve(dest))
170
+ copyFileSync(spec.wasm, dest);
171
+ }
172
+ // Modules of apps outside the registry (the examples' `public/*.wasm`,
173
+ // copied with the public dir) are not part of this site.
174
+ const known = new Set(specs.map((spec) => `${spec.name}.wasm`));
175
+ for (const entry of readdirSync(outDir)) {
176
+ if (entry.endsWith('.wasm') && !known.has(entry))
177
+ rmSync(path.join(outDir, entry), { force: true });
178
+ }
179
+ };
180
+ return {
181
+ name: 'swiftbrowser:swift-wasm',
182
+ configResolved(resolved) {
183
+ config = resolved;
184
+ },
185
+ configureServer(devServer) {
186
+ server = devServer;
187
+ const watched = specs.flatMap((spec) => (spec.watch ?? []).map((dir) => ({ app: spec.name, root: path.resolve(dir) })));
188
+ const appsOf = (file) => file.endsWith('.swift')
189
+ ? watched.filter(({ root }) => file.startsWith(root + path.sep)).map(({ app }) => app)
190
+ : [];
191
+ devServer.middlewares.use((req, res, next) => {
192
+ const name = wasmRequestApp(req.url ?? '');
193
+ const spec = name === null ? undefined : byName.get(name);
194
+ // Unknown names fall through to Vite (a stray file in `public/`, or a 404).
195
+ if (!spec)
196
+ return next();
197
+ if (!tracked.has(spec.name)) {
198
+ tracked.add(spec.name);
199
+ log(`tracking ${spec.name} for rebuilds`);
200
+ }
201
+ serveWasm(spec, res, req.method).catch((error) => {
202
+ config?.logger.error(`[swift-wasm] ${spec.name}: ${failureOutput(error)}`);
203
+ if (!res.headersSent)
204
+ res.statusCode = 500;
205
+ res.end();
206
+ });
207
+ });
208
+ const roots = Array.from(new Set(watched.map(({ root }) => root))).filter((root) => existsSync(root));
209
+ if (roots.length > 0)
210
+ devServer.watcher.add(roots);
211
+ devServer.watcher.on('all', (event, file) => {
212
+ if (event === 'addDir' || event === 'unlinkDir')
213
+ return;
214
+ const apps = appsOf(file);
215
+ if (apps.length === 0)
216
+ return;
217
+ log(`${event} ${file}`);
218
+ for (const app of new Set(apps)) {
219
+ if (!byName.get(app)?.build)
220
+ continue;
221
+ if (tracked.has(app))
222
+ dirty.add(app);
223
+ else
224
+ stale.add(app);
225
+ }
226
+ if (dirty.size > 0)
227
+ schedule();
228
+ });
229
+ if (roots.length > 0) {
230
+ log(`watching ${roots.join(', ')} for .swift changes (apps: ${specs.map((spec) => spec.name).join(', ')})`);
231
+ }
232
+ },
233
+ async writeBundle(outputOptions) {
234
+ if (!config)
235
+ return;
236
+ const outDir = outputOptions.dir ?? path.resolve(config.root, config.build.outDir);
237
+ await copyModules(outDir);
238
+ },
239
+ };
240
+ }
241
+ //# sourceMappingURL=swift-wasm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-wasm.js","sourceRoot":"","sources":["../../../plugins/swift-wasm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Asset catalog manifest (docs/ops-protocol.md, "Phase 5 additions").
3
+ *
4
+ * An Xcode asset catalog (`Examples/<App>/Assets.xcassets`) holds the images
5
+ * and colors a SwiftUI app refers to by name (`Image("dough/plain-full")`,
6
+ * `Color("dough/plain-bg")`). The Swift side only ever sends the name; the
7
+ * dev server and the build turn every catalog into one JSON manifest plus the
8
+ * image files (plugins/asset-catalogs.ts), and the page fetches the manifest
9
+ * before loading the app. The layout engine reads intrinsic sizes from it,
10
+ * the renderer resolves `src` and color values.
11
+ *
12
+ * This module is shared by the browser code and the Node plugin, so it must
13
+ * stay free of DOM and Node APIs.
14
+ */
15
+ export type AssetImageKind = 'image' | 'symbol';
16
+ export interface AssetImage {
17
+ /** Absolute URL path of the image file (`/catalog/<App>/<file>`). */
18
+ src: string;
19
+ /** Intrinsic size in points (pixel size ÷ `scale`). Irrelevant for `symbol`. */
20
+ width: number;
21
+ height: number;
22
+ /** Scale of the file the manifest picked (2 for `@2x`), so pixels = points × scale. */
23
+ scale: number;
24
+ /** `image` for an `.imageset`; `symbol` for an `.symbolset` (an SVG drawn as a template). */
25
+ kind: AssetImageKind;
26
+ }
27
+ export interface AssetColor {
28
+ /** CSS color for the light appearance (`rgba(r, g, b, a)`). */
29
+ light: string;
30
+ /** CSS color for the dark appearance; absent when the colorset has none. */
31
+ dark?: string;
32
+ }
33
+ export interface AssetCatalog {
34
+ /** Keyed by catalog name, namespaced with `/` (`dough/plain-full`). */
35
+ images: Record<string, AssetImage>;
36
+ colors: Record<string, AssetColor>;
37
+ }
38
+ /** The catalog of an app without one (and of the mock app). */
39
+ export declare const EMPTY_CATALOG: Readonly<AssetCatalog>;
40
+ /** URL directory under which manifests and files are served. */
41
+ export declare const CATALOG_DIR = "catalog";
42
+ /** URL path of an app's manifest (`/catalog/<App>.json`). */
43
+ export declare function catalogPath(app: string): string;
44
+ /**
45
+ * File name an asset is served under: the namespaced name with every `/`
46
+ * replaced by `__`, plus the extension (`dough__plain-full.png`). Flattening
47
+ * keeps every file of a catalog in one directory.
48
+ */
49
+ export declare function assetFileName(name: string, ext: string): string;
50
+ /** URL path of an asset file (`/catalog/<App>/dough__plain-full.png`). */
51
+ export declare function assetFilePath(app: string, name: string, ext: string): string;
52
+ /**
53
+ * CSS custom property that carries a catalog color: `--sb-asset-color-<slug>`.
54
+ * The slug keeps letters, digits, `-` and `_`; `/` becomes `__` (like file
55
+ * names) and anything else `_`.
56
+ */
57
+ export declare function assetColorVar(name: string): string;
58
+ /** Cheap structural check for a fetched manifest; anything else is treated as empty. */
59
+ export declare function isAssetCatalog(value: unknown): value is AssetCatalog;
60
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,KAAK,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACpC;AAED,+DAA+D;AAC/D,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,YAAY,CAA6C,CAAC;AAE/F,gEAAgE;AAChE,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAIpE"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Asset catalog manifest (docs/ops-protocol.md, "Phase 5 additions").
3
+ *
4
+ * An Xcode asset catalog (`Examples/<App>/Assets.xcassets`) holds the images
5
+ * and colors a SwiftUI app refers to by name (`Image("dough/plain-full")`,
6
+ * `Color("dough/plain-bg")`). The Swift side only ever sends the name; the
7
+ * dev server and the build turn every catalog into one JSON manifest plus the
8
+ * image files (plugins/asset-catalogs.ts), and the page fetches the manifest
9
+ * before loading the app. The layout engine reads intrinsic sizes from it,
10
+ * the renderer resolves `src` and color values.
11
+ *
12
+ * This module is shared by the browser code and the Node plugin, so it must
13
+ * stay free of DOM and Node APIs.
14
+ */
15
+ /** The catalog of an app without one (and of the mock app). */
16
+ export const EMPTY_CATALOG = Object.freeze({ images: {}, colors: {} });
17
+ /** URL directory under which manifests and files are served. */
18
+ export const CATALOG_DIR = 'catalog';
19
+ /** URL path of an app's manifest (`/catalog/<App>.json`). */
20
+ export function catalogPath(app) {
21
+ return `/${CATALOG_DIR}/${app}.json`;
22
+ }
23
+ /**
24
+ * File name an asset is served under: the namespaced name with every `/`
25
+ * replaced by `__`, plus the extension (`dough__plain-full.png`). Flattening
26
+ * keeps every file of a catalog in one directory.
27
+ */
28
+ export function assetFileName(name, ext) {
29
+ // `/` becomes `__`; spaces and anything else outside [A-Za-z0-9_.-] become
30
+ // `_`, so the served path needs no URL encoding and matches the request
31
+ // pattern the dev middleware accepts.
32
+ return `${name.replace(/\//g, '__').replace(/[^A-Za-z0-9_.-]/g, '_')}.${ext}`;
33
+ }
34
+ /** URL path of an asset file (`/catalog/<App>/dough__plain-full.png`). */
35
+ export function assetFilePath(app, name, ext) {
36
+ return `/${CATALOG_DIR}/${app}/${assetFileName(name, ext)}`;
37
+ }
38
+ /**
39
+ * CSS custom property that carries a catalog color: `--sb-asset-color-<slug>`.
40
+ * The slug keeps letters, digits, `-` and `_`; `/` becomes `__` (like file
41
+ * names) and anything else `_`.
42
+ */
43
+ export function assetColorVar(name) {
44
+ const slug = name.replace(/\//g, '__').replace(/[^A-Za-z0-9_-]/g, '_');
45
+ return `--sb-asset-color-${slug}`;
46
+ }
47
+ /** Cheap structural check for a fetched manifest; anything else is treated as empty. */
48
+ export function isAssetCatalog(value) {
49
+ if (typeof value !== 'object' || value === null)
50
+ return false;
51
+ const { images, colors } = value;
52
+ return typeof images === 'object' && images !== null && typeof colors === 'object' && colors !== null;
53
+ }
54
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/assets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA6BH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAA2B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAE/F,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,IAAI,WAAW,IAAI,GAAG,OAAO,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAW;IACrD,2EAA2E;IAC3E,wEAAwE;IACxE,sCAAsC;IACtC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;AAChF,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY,EAAE,GAAW;IAClE,OAAO,IAAI,WAAW,IAAI,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;IACvE,OAAO,oBAAoB,IAAI,EAAE,CAAC;AACpC,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAA+C,CAAC;IAC3E,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AACxG,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Custom Vite websocket events exchanged between the dev-server plugin
3
+ * (plugins/swift-wasm.ts) and the page (src/main.ts) for hot reload.
4
+ *
5
+ * This file is imported by both sides, so it must stay free of DOM and Node
6
+ * types.
7
+ */
8
+ import 'vite/types/customEvent.d.ts';
9
+ export interface BuildStartPayload {
10
+ /** Products being rebuilt, e.g. `["Counter", "Todos"]`. */
11
+ apps: string[];
12
+ }
13
+ export interface BuildEndPayload {
14
+ apps: string[];
15
+ ok: boolean;
16
+ durationMs: number;
17
+ }
18
+ export interface BuildErrorPayload {
19
+ /** The product whose build failed. */
20
+ app: string;
21
+ /** Combined stdout + stderr of `scripts/build-wasm.sh`. */
22
+ output: string;
23
+ }
24
+ declare module 'vite/types/customEvent.d.ts' {
25
+ interface CustomEventMap {
26
+ 'sb:build-start': BuildStartPayload;
27
+ 'sb:build-end': BuildEndPayload;
28
+ 'sb:build-error': BuildErrorPayload;
29
+ }
30
+ }
31
+ //# sourceMappingURL=devEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devEvents.d.ts","sourceRoot":"","sources":["../../../src/devEvents.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,6BAA6B,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,OAAO,QAAQ,6BAA6B,CAAC;IAC3C,UAAU,cAAc;QACtB,gBAAgB,EAAE,iBAAiB,CAAC;QACpC,cAAc,EAAE,eAAe,CAAC;QAChC,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;CACF"}