@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.
- package/LICENSE +10 -0
- package/README.md +148 -0
- package/dist/cache.d.ts +70 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +0 -0
- package/dist/cache.js.map +1 -0
- package/dist/host-api.d.ts +81 -0
- package/dist/host-api.d.ts.map +1 -0
- package/dist/host-api.js +46 -0
- package/dist/host-api.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/locale.d.ts +32 -0
- package/dist/locale.d.ts.map +1 -0
- package/dist/locale.js +64 -0
- package/dist/locale.js.map +1 -0
- package/dist/patches.d.ts +38 -0
- package/dist/patches.d.ts.map +1 -0
- package/dist/patches.js +76 -0
- package/dist/patches.js.map +1 -0
- package/dist/shims/sockets.d.ts +130 -0
- package/dist/shims/sockets.d.ts.map +1 -0
- package/dist/shims/sockets.js +128 -0
- package/dist/shims/sockets.js.map +1 -0
- package/dist/shims/wasi-http-internal.d.ts +7 -0
- package/dist/shims/wasi-http-internal.d.ts.map +1 -0
- package/dist/shims/wasi-http-internal.js +19 -0
- package/dist/shims/wasi-http-internal.js.map +1 -0
- package/dist/shims/wasi-http.d.ts +83 -0
- package/dist/shims/wasi-http.d.ts.map +1 -0
- package/dist/shims/wasi-http.js +452 -0
- package/dist/shims/wasi-http.js.map +1 -0
- package/dist/streaming-fallback.d.ts +16 -0
- package/dist/streaming-fallback.d.ts.map +1 -0
- package/dist/streaming-fallback.js +52 -0
- package/dist/streaming-fallback.js.map +1 -0
- package/dist/timing.d.ts +22 -0
- package/dist/timing.d.ts.map +1 -0
- package/dist/timing.js +48 -0
- package/dist/timing.js.map +1 -0
- package/dist/transpile.d.ts +10 -0
- package/dist/transpile.d.ts.map +1 -0
- package/dist/transpile.js +277 -0
- package/dist/transpile.js.map +1 -0
- package/dist/transpile.worker.d.ts +36 -0
- package/dist/transpile.worker.d.ts.map +1 -0
- package/dist/transpile.worker.js +43 -0
- package/dist/transpile.worker.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/dist/webmcp.d.ts +92 -0
- package/dist/webmcp.d.ts.map +1 -0
- package/dist/webmcp.js +189 -0
- package/dist/webmcp.js.map +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -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"}
|
package/dist/webmcp.d.ts
ADDED
|
@@ -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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"}
|