@actcore/web-runtime 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 (59) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +148 -0
  3. package/dist/cache.d.ts +70 -0
  4. package/dist/cache.d.ts.map +1 -0
  5. package/dist/cache.js +0 -0
  6. package/dist/cache.js.map +1 -0
  7. package/dist/host-api.d.ts +81 -0
  8. package/dist/host-api.d.ts.map +1 -0
  9. package/dist/host-api.js +46 -0
  10. package/dist/host-api.js.map +1 -0
  11. package/dist/index.d.ts +30 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +23 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/locale.d.ts +32 -0
  16. package/dist/locale.d.ts.map +1 -0
  17. package/dist/locale.js +64 -0
  18. package/dist/locale.js.map +1 -0
  19. package/dist/patches.d.ts +38 -0
  20. package/dist/patches.d.ts.map +1 -0
  21. package/dist/patches.js +76 -0
  22. package/dist/patches.js.map +1 -0
  23. package/dist/shims/sockets.d.ts +130 -0
  24. package/dist/shims/sockets.d.ts.map +1 -0
  25. package/dist/shims/sockets.js +128 -0
  26. package/dist/shims/sockets.js.map +1 -0
  27. package/dist/shims/wasi-http-internal.d.ts +7 -0
  28. package/dist/shims/wasi-http-internal.d.ts.map +1 -0
  29. package/dist/shims/wasi-http-internal.js +19 -0
  30. package/dist/shims/wasi-http-internal.js.map +1 -0
  31. package/dist/shims/wasi-http.d.ts +83 -0
  32. package/dist/shims/wasi-http.d.ts.map +1 -0
  33. package/dist/shims/wasi-http.js +452 -0
  34. package/dist/shims/wasi-http.js.map +1 -0
  35. package/dist/streaming-fallback.d.ts +16 -0
  36. package/dist/streaming-fallback.d.ts.map +1 -0
  37. package/dist/streaming-fallback.js +52 -0
  38. package/dist/streaming-fallback.js.map +1 -0
  39. package/dist/timing.d.ts +22 -0
  40. package/dist/timing.d.ts.map +1 -0
  41. package/dist/timing.js +48 -0
  42. package/dist/timing.js.map +1 -0
  43. package/dist/transpile.d.ts +10 -0
  44. package/dist/transpile.d.ts.map +1 -0
  45. package/dist/transpile.js +277 -0
  46. package/dist/transpile.js.map +1 -0
  47. package/dist/transpile.worker.d.ts +36 -0
  48. package/dist/transpile.worker.d.ts.map +1 -0
  49. package/dist/transpile.worker.js +43 -0
  50. package/dist/transpile.worker.js.map +1 -0
  51. package/dist/version.d.ts +2 -0
  52. package/dist/version.d.ts.map +1 -0
  53. package/dist/version.js +5 -0
  54. package/dist/version.js.map +1 -0
  55. package/dist/webmcp.d.ts +92 -0
  56. package/dist/webmcp.d.ts.map +1 -0
  57. package/dist/webmcp.js +189 -0
  58. package/dist/webmcp.js.map +1 -0
  59. package/package.json +69 -0
@@ -0,0 +1,277 @@
1
+ import { applyPatches, rewriteBareImports } from './patches.js';
2
+ import { fmtDuration, measurePhase } from './timing.js';
3
+ import { deriveTranspileCacheKey, getCachedFiles, putCachedFiles, } from './cache.js';
4
+ // The in-browser transpiler. jco 1.24.x moved transpile logic into the
5
+ // `@bytecodealliance/jco-transpile` package, whose high-level `transpileBytes`
6
+ // statically imports node: builtins (node:child_process / node:os / node:fs)
7
+ // and `terser`, so it cannot load under native ESM in a browser. jco's own
8
+ // `@bytecodealliance/jco/component` browser entry is also unusable in 1.24.3:
9
+ // it imports an `obj/` glue module that the published tarball omits
10
+ // (`files: ["lib","src","types"]`). The one browser-safe artifact jco ships is
11
+ // the vendored, componentized js-component-bindgen — the same `generate()` jco's
12
+ // browser entry called under the hood in earlier releases — which loads its
13
+ // core wasm via `fetch` + `import.meta.url` and only touches node:fs when
14
+ // `fetch` is absent. We call it directly (see the `import()` below). The
15
+ // specifier is exports-map-gated by jco-transpile (no `./vendor/*` export), so
16
+ // consumers map it via importmap (see examples/) or a bundler alias; tsc is
17
+ // satisfied by src/jco-bindgen.d.ts.
18
+ //
19
+ // The import below is written as a bare literal (no `@vite-ignore`) on purpose:
20
+ // bundlers must be allowed to resolve + bundle it (via the consumer's alias),
21
+ // and a no-bundler browser resolves the same literal through its importmap.
22
+ // `@vite-ignore` would suppress both, leaving an unresolvable runtime specifier.
23
+ //
24
+ // `generate()` is synchronous and CPU-heavy: a large component blocks for
25
+ // seconds. To keep the page responsive we run it in a Web Worker (see
26
+ // ./transpile.worker.ts) and fall back to a main-thread call only when a worker
27
+ // can't be created or load. And because its output is a pure function of the
28
+ // input bytes + options, we persist it in IndexedDB (see ./cache.ts) so repeat
29
+ // loads skip `generate()` altogether.
30
+ const DEFAULT_NAME = 'component';
31
+ /**
32
+ * Run jco transpile (cached / off-thread), patch the output, and return a blob:
33
+ * URL pointing at the entry ES module. Caller does `await import(url)` to load.
34
+ */
35
+ export async function transpileToBlobUrl(bytes, options) {
36
+ const shimBase = normalizeShimBase(options.shimBase);
37
+ const name = options.name ?? DEFAULT_NAME;
38
+ // Host-view exports wasi:http p3 from our own shim (see wit/host-view.wit
39
+ // and src/shims/wasi-http.ts). preview2-shim's http.js doesn't carry the
40
+ // `client` or p3-shaped `types` exports a wasip3 component imports, so
41
+ // wasi:http resolves to a separate URL than the rest of WASI. Defaults to
42
+ // the bundled shim sibling-to-dist/index.js; callers can override (useful
43
+ // when dist/ is served from a different origin than preview2-shim).
44
+ const wasiHttpShimUrl = options.wasiHttpShimUrl
45
+ ?? new URL('./shims/wasi-http.js', import.meta.url).href;
46
+ // host-browser ships its own wasi:sockets shim: preview2-shim's browser build
47
+ // omits the resource-class constructors any wasi:http-importing component
48
+ // needs present at instantiation. Route wasi:sockets here, not at shimBase.
49
+ const wasiSocketsShimUrl = options.wasiSocketsShimUrl
50
+ ?? new URL('./shims/sockets.js', import.meta.url).href;
51
+ const useCache = options.cache !== false;
52
+ const generateOptions = buildGenerateOptions(name, shimBase, wasiHttpShimUrl, wasiSocketsShimUrl);
53
+ // 1. Cache lookup. The key spans HOST_VERSION + the SHA-256 of `bytes` + the
54
+ // output-affecting options, so a hit is byte-for-byte the right transpile.
55
+ let cacheKey = null;
56
+ if (useCache) {
57
+ try {
58
+ const t0 = performance.now();
59
+ cacheKey = await deriveTranspileCacheKey({ bytes, name, shimBase, wasiHttpShimUrl, wasiSocketsShimUrl });
60
+ const cached = await getCachedFiles(cacheKey);
61
+ if (cached) {
62
+ measurePhase('actcore:transpile-cache-hit', t0, { path: 'cache', component: name });
63
+ console.debug(`[@actcore/web-runtime] transpile cache hit in ${fmtDuration(performance.now() - t0)} — skipping generate()`);
64
+ return buildBlobModuleGraph(cached, name, shimBase);
65
+ }
66
+ }
67
+ catch {
68
+ cacheKey = null; // hashing unavailable — proceed without the cache.
69
+ }
70
+ }
71
+ // 2. Cache miss: transpile (worker, or main thread on fallback). Convert to
72
+ // Blobs once — this is the sole copy of the ~100MB core wasm, then reused
73
+ // by both the cache store and the module graph (no second `new Blob`).
74
+ const files = filesToBlobs(await generateFiles(bytes, generateOptions));
75
+ // 3. Populate the cache for next time. Best-effort and non-blocking.
76
+ if (cacheKey)
77
+ void putCachedFiles(cacheKey, files);
78
+ return buildBlobModuleGraph(files, name, shimBase);
79
+ }
80
+ /**
81
+ * Build the `generate()` options. The WASI specifier `map` (and thus the emitted
82
+ * import URLs) is a function of `name`/`shimBase`/`wasiHttpShimUrl` — the exact
83
+ * inputs the cache key spans, so a cache hit always matches the live output.
84
+ *
85
+ * We drive the low-level bindgen `generate()` directly so we own the WASI
86
+ * specifier map outright. This deliberately sidesteps jco-transpile's default
87
+ * `wasiShim` map, which (as of jco 1.24) over-populates p3-versioned WASI
88
+ * interfaces onto the Node-only `@bytecodealliance/preview3-shim` — useless in a
89
+ * browser. Our map routes p3 wasi:http at our browser shim and the rest at
90
+ * preview2-shim's browser builds; unversioned `wasi:foo/*` keys match every
91
+ * version the component imports (p2 0.2.x and p3 0.3.0 alike). The `#*`
92
+ * expansion preserves the trailing interface name jco emits per-interface.
93
+ */
94
+ function buildGenerateOptions(name, shimBase, wasiHttpShimUrl, wasiSocketsShimUrl) {
95
+ return {
96
+ name,
97
+ asyncMode: { tag: 'jspi', val: { imports: [], exports: [] } },
98
+ // No .d.ts is ever consumed at runtime (browser or the Node debug path in
99
+ // transpile.ts's header comment) — skipping its generation is a pure win.
100
+ noTypescript: true,
101
+ map: [
102
+ ['wasi:cli/*', shimBase + 'cli.js#*'],
103
+ ['wasi:clocks/*', shimBase + 'clocks.js#*'],
104
+ ['wasi:filesystem/*', shimBase + 'filesystem.js#*'],
105
+ ['wasi:http/*', wasiHttpShimUrl + '#*'],
106
+ ['wasi:io/*', shimBase + 'io.js#*'],
107
+ ['wasi:random/*', shimBase + 'random.js#*'],
108
+ ['wasi:sockets/*', wasiSocketsShimUrl + '#*'],
109
+ ],
110
+ };
111
+ }
112
+ /**
113
+ * Produce the transpile output for `bytes`. Prefers a Web Worker so the
114
+ * multi-second `generate()` call doesn't freeze the page; falls back to a
115
+ * main-thread transpile when a worker can't be created or fails to load (e.g.
116
+ * no-bundler importmap setups, where the worker can't resolve the bindgen).
117
+ */
118
+ async function generateFiles(bytes, options) {
119
+ const t0 = performance.now();
120
+ const viaWorker = await tryGenerateInWorker(bytes, options);
121
+ if (viaWorker) {
122
+ const totalMs = performance.now() - t0;
123
+ const { initMs, generateMs } = viaWorker.timings;
124
+ const overheadMs = Math.max(0, totalMs - initMs - generateMs);
125
+ measurePhase('actcore:transpile', t0, { path: 'web worker', component: options.name }, { initMs, generateMs, overheadMs });
126
+ console.debug(`[@actcore/web-runtime] transpiled in Web Worker in ${fmtDuration(totalMs)} — ` +
127
+ `$init ${fmtDuration(initMs)}, generate ${fmtDuration(generateMs)}, ` +
128
+ `worker+messaging ${fmtDuration(overheadMs)} (main thread free)`);
129
+ return viaWorker.files;
130
+ }
131
+ const files = await generateOnMainThread(bytes, options);
132
+ measurePhase('actcore:transpile', t0, { path: 'main thread', component: options.name });
133
+ console.debug(`[@actcore/web-runtime] transpiled on main thread in ${fmtDuration(performance.now() - t0)} (worker unavailable)`);
134
+ return files;
135
+ }
136
+ function tryGenerateInWorker(bytes, options) {
137
+ return new Promise((resolve, reject) => {
138
+ let worker;
139
+ try {
140
+ worker = new Worker(new URL('./transpile.worker.js', import.meta.url), {
141
+ type: 'module',
142
+ });
143
+ }
144
+ catch {
145
+ resolve(null);
146
+ return;
147
+ }
148
+ let settled = false;
149
+ const finish = (fn) => {
150
+ if (settled)
151
+ return;
152
+ settled = true;
153
+ worker.terminate();
154
+ fn();
155
+ };
156
+ worker.onmessage = (ev) => {
157
+ const msg = ev.data;
158
+ if (msg && msg.ok) {
159
+ finish(() => resolve({ files: msg.files, timings: msg.timings }));
160
+ }
161
+ else {
162
+ // The worker reached `generate()` but it (or the bindgen) failed. Recover
163
+ // on the main thread, which carries the streaming MIME fallback and is
164
+ // the proven path; if the component is genuinely bad it re-throws there.
165
+ console.debug('[@actcore/web-runtime] worker transpile failed, retrying on main thread:', msg?.error);
166
+ finish(() => resolve(null));
167
+ }
168
+ };
169
+ // Fires when the worker module fails to load/resolve (importmap-only setups
170
+ // can't resolve the bindgen specifier in worker scope). Recover on-thread.
171
+ worker.onerror = () => finish(() => resolve(null));
172
+ try {
173
+ // Don't transfer `bytes.buffer`: the main-thread fallback still needs the
174
+ // bytes intact. The clone cost is a memcpy — negligible next to generate().
175
+ worker.postMessage({ bytes, options });
176
+ }
177
+ catch (err) {
178
+ finish(() => reject(err));
179
+ }
180
+ });
181
+ }
182
+ /** Last-resort transpile in the page realm (blocks, but always works). */
183
+ async function generateOnMainThread(bytes, options) {
184
+ // Dynamic import keeps the bindgen (~9MB of wasm) out of the initial bundle
185
+ // for callers that lazy-load.
186
+ const { generate, $init } = await import('@bytecodealliance/jco-transpile/vendor/js-component-bindgen-component.js');
187
+ await $init;
188
+ return generate(bytes, options).files;
189
+ }
190
+ /**
191
+ * Take jco's `files` output and assemble a graph of blob: URLs so the
192
+ * entry module can be `import()`-ed. Each .js file has its bare-import
193
+ * specifiers rewritten to absolute URLs (blob: contexts have no importmap),
194
+ * each .wasm file becomes its own blob, and the entry module gets the
195
+ * runtime patches applied (STREAM_TABLES decl + custom lifts).
196
+ */
197
+ async function buildBlobModuleGraph(files, name, shimBase) {
198
+ const fileMap = new Map(files);
199
+ // 1. .wasm files → blob URLs directly. The Blobs are already disk-backed
200
+ // (from the cache or `filesToBlobs`), so this is a zero-copy
201
+ // `createObjectURL` — the ~100MB core wasm is never materialized in JS.
202
+ const wasmUrls = {};
203
+ for (const [path, blob] of files) {
204
+ if (path.endsWith('.wasm')) {
205
+ wasmUrls[path] = URL.createObjectURL(blob);
206
+ }
207
+ }
208
+ // 2. Sub-modules in interfaces/. Rewrite bare imports then blob-ify; index
209
+ // them by their relative path so the entry can refer to them.
210
+ const subUrls = {};
211
+ for (const [path, blob] of files) {
212
+ if (!path.endsWith('.js') || !path.includes('/'))
213
+ continue;
214
+ const src = rewriteBareImports(await blob.text(), shimBase);
215
+ subUrls[path] = URL.createObjectURL(new Blob([src], { type: 'application/javascript' }));
216
+ }
217
+ // 3. Entry .js — apply runtime patches (future/stream drop guard), bare-import
218
+ // and relative-import rewrites. Returns a single blob URL.
219
+ const entryFilename = `${name}.js`;
220
+ const entryBlob = fileMap.get(entryFilename);
221
+ if (!entryBlob) {
222
+ throw new Error(`jco transpile output missing entry module ${entryFilename}`);
223
+ }
224
+ let entrySrc = await entryBlob.text();
225
+ entrySrc = applyPatches(entrySrc);
226
+ entrySrc = rewriteBareImports(entrySrc, shimBase);
227
+ // jco emits `new URL('./X.core.wasm', import.meta.url)` for core wasm refs.
228
+ // When the entry module loads from a blob: URL, that URL constructor resolves
229
+ // to the page origin's root — which 404s. Rewrite the whole expression to
230
+ // the absolute blob URL of our core-wasm blob.
231
+ for (const [path, blobUrl] of Object.entries(wasmUrls)) {
232
+ const pattern = new RegExp(String.raw `new\s+URL\s*\(\s*(['"\`])\.\/` +
233
+ path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +
234
+ String.raw `\1\s*,\s*import\.meta\.url\s*\)`, 'g');
235
+ entrySrc = entrySrc.replace(pattern, JSON.stringify(blobUrl));
236
+ entrySrc = replaceAllSpec(entrySrc, `./${path}`, blobUrl);
237
+ }
238
+ // Final sanity check.
239
+ const stragglers = entrySrc.match(/['"`][^'"`]*\.core\.wasm['"`]/g);
240
+ if (stragglers) {
241
+ console.warn('[@actcore/web-runtime] unmatched .core.wasm references:', stragglers);
242
+ }
243
+ for (const [path, blobUrl] of Object.entries(subUrls)) {
244
+ entrySrc = replaceAllSpec(entrySrc, `./${path}`, blobUrl);
245
+ }
246
+ const entryUrl = URL.createObjectURL(new Blob([entrySrc], { type: 'application/javascript' }));
247
+ // Revoke every blob URL once the caller has imported the entry module: by
248
+ // then the wasm has been fetched + compiled and the sub-modules loaded, so
249
+ // holding these alive just leaks the (~100MB) core-wasm blob on every run.
250
+ const revoke = () => {
251
+ URL.revokeObjectURL(entryUrl);
252
+ for (const u of Object.values(wasmUrls))
253
+ URL.revokeObjectURL(u);
254
+ for (const u of Object.values(subUrls))
255
+ URL.revokeObjectURL(u);
256
+ };
257
+ return { url: entryUrl, revoke };
258
+ }
259
+ /**
260
+ * Convert raw `generate()` output (Uint8Array per file) into `Blob`s so the
261
+ * cache stores them by reference and the module graph replays them zero-copy.
262
+ * `.wasm` gets `application/wasm` (used directly as a blob URL); the JS files
263
+ * are re-blobbed after text rewriting, so their type here doesn't matter.
264
+ */
265
+ function filesToBlobs(files) {
266
+ return files.map(([path, bytes]) => [
267
+ path,
268
+ new Blob([bytes], path.endsWith('.wasm') ? { type: 'application/wasm' } : {}),
269
+ ]);
270
+ }
271
+ function replaceAllSpec(src, from, to) {
272
+ return src.replaceAll(`'${from}'`, `'${to}'`).replaceAll(`"${from}"`, `"${to}"`);
273
+ }
274
+ function normalizeShimBase(base) {
275
+ return base.endsWith('/') ? base : base + '/';
276
+ }
277
+ //# sourceMappingURL=transpile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpile.js","sourceRoot":"","sources":["../src/transpile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Web Worker that runs jco's `generate()` off the main thread.
3
+ *
4
+ * `generate()` is a single, synchronous wasm call that can block for several
5
+ * seconds on large components — long enough to freeze the page if run on the
6
+ * main thread. Hosting it in a worker keeps the UI responsive; the cheap parts
7
+ * (assembling blob: URLs, importing the module) stay on the main thread because
8
+ * blob URLs and module evaluation must happen in the page realm.
9
+ *
10
+ * The worker imports the same vendored, componentized bindgen the main-thread
11
+ * path uses (see ./transpile.ts for why this is the only browser-safe entry).
12
+ * Bundlers (Vite) resolve the specifier and bundle the worker. In no-bundler
13
+ * setups the page importmap does NOT apply to workers, so this import fails to
14
+ * resolve; the main thread detects the worker error and falls back to a
15
+ * main-thread transpile. Nothing here is load-bearing for correctness.
16
+ */
17
+ import type { GenerateOptions } from '@bytecodealliance/jco-transpile/vendor/js-component-bindgen-component.js';
18
+ /** Main thread → worker. */
19
+ export interface TranspileWorkerRequest {
20
+ bytes: Uint8Array;
21
+ options: GenerateOptions;
22
+ }
23
+ /** Worker → main thread. `timings` splits the worker's wall-clock so the main
24
+ * thread can attribute the total (which also spans worker startup + messaging). */
25
+ export type TranspileWorkerResponse = {
26
+ ok: true;
27
+ files: Array<[string, Uint8Array]>;
28
+ timings: {
29
+ initMs: number;
30
+ generateMs: number;
31
+ };
32
+ } | {
33
+ ok: false;
34
+ error: string;
35
+ };
36
+ //# sourceMappingURL=transpile.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpile.worker.d.ts","sourceRoot":"","sources":["../src/transpile.worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0EAA0E,CAAC;AAShH,4BAA4B;AAC5B,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED;mFACmF;AACnF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Web Worker that runs jco's `generate()` off the main thread.
3
+ *
4
+ * `generate()` is a single, synchronous wasm call that can block for several
5
+ * seconds on large components — long enough to freeze the page if run on the
6
+ * main thread. Hosting it in a worker keeps the UI responsive; the cheap parts
7
+ * (assembling blob: URLs, importing the module) stay on the main thread because
8
+ * blob URLs and module evaluation must happen in the page realm.
9
+ *
10
+ * The worker imports the same vendored, componentized bindgen the main-thread
11
+ * path uses (see ./transpile.ts for why this is the only browser-safe entry).
12
+ * Bundlers (Vite) resolve the specifier and bundle the worker. In no-bundler
13
+ * setups the page importmap does NOT apply to workers, so this import fails to
14
+ * resolve; the main thread detects the worker error and falls back to a
15
+ * main-thread transpile. Nothing here is load-bearing for correctness.
16
+ */
17
+ import { generate, $init, } from '@bytecodealliance/jco-transpile/vendor/js-component-bindgen-component.js';
18
+ import { installCompileStreamingFallback } from './streaming-fallback.js';
19
+ // The bindgen's `$init` compiles its ~9 MB core wasm via compileStreaming. In
20
+ // dev (Vite) the worker-scope fetch can report a non-`application/wasm` MIME, so
21
+ // install the same fallback the page uses — without it, `$init` rejects and the
22
+ // whole transpile fails in the worker. Must run before `$init` is awaited.
23
+ installCompileStreamingFallback();
24
+ const ctx = globalThis;
25
+ ctx.onmessage = (ev) => {
26
+ void handle(ev.data);
27
+ };
28
+ async function handle(req) {
29
+ try {
30
+ const t0 = performance.now();
31
+ await $init;
32
+ const t1 = performance.now();
33
+ const result = generate(req.bytes, req.options);
34
+ const t2 = performance.now();
35
+ // Transfer the output buffers back to avoid a second copy of large wasm.
36
+ const transfer = result.files.map(([, b]) => b.buffer);
37
+ ctx.postMessage({ ok: true, files: result.files, timings: { initMs: t1 - t0, generateMs: t2 - t1 } }, transfer);
38
+ }
39
+ catch (err) {
40
+ ctx.postMessage({ ok: false, error: String(err?.message ?? err) });
41
+ }
42
+ }
43
+ //# sourceMappingURL=transpile.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpile.worker.js","sourceRoot":"","sources":["../src/transpile.worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,QAAQ,EACR,KAAK,GACN,MAAM,0EAA0E,CAAC;AAElF,OAAO,EAAE,+BAA+B,EAAE,MAAM,yBAAyB,CAAC;AAE1E,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,2EAA2E;AAC3E,+BAA+B,EAAE,CAAC;AAqBlC,MAAM,GAAG,GAAG,UAA6C,CAAC;AAE1D,GAAG,CAAC,SAAS,GAAG,CAAC,EAAgB,EAAE,EAAE;IACnC,KAAK,MAAM,CAAC,EAAE,CAAC,IAA8B,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,KAAK,UAAU,MAAM,CAAC,GAA2B;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC;QACZ,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7B,yEAAyE;QACzE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvD,GAAG,CAAC,WAAW,CACb,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EACpF,QAA0B,CAC3B,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const HOST_VERSION = "0.1.0";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ // @generated by scripts/gen-version.mjs — do not edit by hand.
2
+ // Mirrors package.json "version". Part of the transpile-cache key, so a
3
+ // version bump deliberately invalidates all cached transpile output.
4
+ export const HOST_VERSION = "0.1.0";
5
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,wEAAwE;AACxE,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Bridge: expose an ACT component's tools on the browser's native WebMCP
3
+ * surface (`document.modelContext`). Native-only, feature-gated, opt-in.
4
+ *
5
+ * WebMCP is pre-standardization; we type only the slice we depend on
6
+ * (`registerTool` + `AbortSignal`) so upstream churn cannot break the build.
7
+ * Spec: https://webmachinelearning.github.io/webmcp/
8
+ */
9
+ import type { Metadata } from './generated/interfaces/act-core-types.js';
10
+ import type { ToolProvider } from './host-api.js';
11
+ import type { ToolDefinition } from './generated/interfaces/act-tools-types.js';
12
+ /** MCP-style result an `execute` handler returns. */
13
+ export interface WebmcpCallResult {
14
+ content: Array<{
15
+ type: 'text';
16
+ text: string;
17
+ }>;
18
+ isError?: boolean;
19
+ }
20
+ /** A single WebMCP tool descriptor passed to `registerTool`. */
21
+ export interface WebmcpToolDescriptor {
22
+ name: string;
23
+ description: string;
24
+ title?: string;
25
+ inputSchema?: object;
26
+ annotations?: {
27
+ readOnlyHint?: boolean;
28
+ untrustedContentHint?: boolean;
29
+ };
30
+ execute: (input: Record<string, unknown>) => Promise<WebmcpCallResult>;
31
+ }
32
+ interface RegisterToolOptions {
33
+ signal?: AbortSignal;
34
+ exposedTo?: string[];
35
+ }
36
+ /** The slice of the native `document.modelContext` surface we use. */
37
+ export interface ModelContext {
38
+ registerTool(tool: WebmcpToolDescriptor, options?: RegisterToolOptions): Promise<void>;
39
+ }
40
+ declare global {
41
+ interface Document {
42
+ modelContext?: ModelContext;
43
+ }
44
+ interface Navigator {
45
+ modelContext?: ModelContext;
46
+ }
47
+ }
48
+ /** Native WebMCP surface if present (canonical `document`, legacy `navigator`). */
49
+ export declare function getModelContext(): ModelContext | null;
50
+ /** True when the browser exposes a native WebMCP surface. */
51
+ export declare function isWebmcpAvailable(): boolean;
52
+ /** Coerce an ACT tool name to WebMCP's `[A-Za-z0-9_.-]`, ≤128, non-empty. */
53
+ export declare function sanitizeName(name: string): string;
54
+ /** ACT `parameters-schema` (a JSON Schema string) → a JSON Schema object. */
55
+ export declare function parseInputSchema(schemaStr: string): object;
56
+ /** Read the `std:read-only` boolean from ACT tool metadata, if present. */
57
+ export declare function readReadOnlyHint(metadata: Metadata): boolean | undefined;
58
+ /** WebMCP annotations for an ACT tool: readOnly from meta, untrusted by default. */
59
+ export declare function buildAnnotations(metadata: Metadata): {
60
+ readOnlyHint?: boolean;
61
+ untrustedContentHint: boolean;
62
+ };
63
+ /** Options for {@link exposeToWebmcp}. */
64
+ export interface ExposeWebmcpOptions {
65
+ /** Current session id, read per invocation; when set, forwarded as
66
+ * `std:session-id` metadata on every callTool. */
67
+ getSessionId?: () => string | null | undefined;
68
+ /** WebMCP `exposedTo` origin allowlist. Omit for default visibility. */
69
+ exposedTo?: string[];
70
+ }
71
+ /** Build the WebMCP `execute` handler that bridges to `ToolProvider.callTool`. */
72
+ export declare function buildExecute(provider: ToolProvider, def: ToolDefinition, options: ExposeWebmcpOptions): (input: Record<string, unknown>) => Promise<WebmcpCallResult>;
73
+ /** Map one ACT ToolDefinition to a WebMCP descriptor (execute included). */
74
+ export declare function toDescriptor(provider: ToolProvider, def: ToolDefinition, options: ExposeWebmcpOptions): WebmcpToolDescriptor;
75
+ /** Handle returned by {@link exposeToWebmcp}. */
76
+ export interface WebmcpExposure {
77
+ /** Number of tools successfully registered (0 when unavailable). */
78
+ count: number;
79
+ /** False when no native WebMCP surface was present. */
80
+ available: boolean;
81
+ /** Unregister all tools (aborts the registration signal). Idempotent. */
82
+ dispose(): void;
83
+ }
84
+ /**
85
+ * Register every tool of an ACT component on the native WebMCP surface.
86
+ * Opt-in and headless — the caller decides when to call it and renders any UI.
87
+ * No-ops (returns `available:false`) where `document.modelContext` is absent.
88
+ * Call `dispose()` before re-exposing a different component.
89
+ */
90
+ export declare function exposeToWebmcp(provider: ToolProvider, tools: ToolDefinition[], options?: ExposeWebmcpOptions): Promise<WebmcpExposure>;
91
+ export {};
92
+ //# sourceMappingURL=webmcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webmcp.d.ts","sourceRoot":"","sources":["../src/webmcp.ts"],"names":[],"mappings":"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"}