@invinite-org/chartlang-host-worker 1.0.1

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 (51) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/LICENSE +21 -0
  3. package/README.md +70 -0
  4. package/dist/createWorkerBoot.d.ts +45 -0
  5. package/dist/createWorkerBoot.d.ts.map +1 -0
  6. package/dist/createWorkerBoot.js +122 -0
  7. package/dist/createWorkerBoot.js.map +1 -0
  8. package/dist/createWorkerHost.d.ts +55 -0
  9. package/dist/createWorkerHost.d.ts.map +1 -0
  10. package/dist/createWorkerHost.js +167 -0
  11. package/dist/createWorkerHost.js.map +1 -0
  12. package/dist/defaultWorkerFactory.d.ts +19 -0
  13. package/dist/defaultWorkerFactory.d.ts.map +1 -0
  14. package/dist/defaultWorkerFactory.js +23 -0
  15. package/dist/defaultWorkerFactory.js.map +1 -0
  16. package/dist/filterEmissions.d.ts +21 -0
  17. package/dist/filterEmissions.d.ts.map +1 -0
  18. package/dist/filterEmissions.js +107 -0
  19. package/dist/filterEmissions.js.map +1 -0
  20. package/dist/idb.d.ts +2 -0
  21. package/dist/idb.d.ts.map +1 -0
  22. package/dist/idb.js +4 -0
  23. package/dist/idb.js.map +1 -0
  24. package/dist/idbStateStore.d.ts +22 -0
  25. package/dist/idbStateStore.d.ts.map +1 -0
  26. package/dist/idbStateStore.js +255 -0
  27. package/dist/idbStateStore.js.map +1 -0
  28. package/dist/index.d.ts +8 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/limits.d.ts +40 -0
  33. package/dist/limits.d.ts.map +1 -0
  34. package/dist/limits.js +48 -0
  35. package/dist/limits.js.map +1 -0
  36. package/dist/protocol.d.ts +70 -0
  37. package/dist/protocol.d.ts.map +1 -0
  38. package/dist/protocol.js +4 -0
  39. package/dist/protocol.js.map +1 -0
  40. package/dist/types.d.ts +164 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +4 -0
  43. package/dist/types.js.map +1 -0
  44. package/dist/worker-boot.d.ts +6 -0
  45. package/dist/worker-boot.js +14999 -0
  46. package/dist/worker-boot.js.map +7 -0
  47. package/dist/workerBoot.d.ts +2 -0
  48. package/dist/workerBoot.d.ts.map +1 -0
  49. package/dist/workerBoot.js +18 -0
  50. package/dist/workerBoot.js.map +1 -0
  51. package/package.json +57 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,228 @@
1
+ # @invinite-org/chartlang-host-worker
2
+
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d1de692: Fix end-user-blocking Node-ESM packaging bug. Every published `dist/index.js` previously failed to load under Node's strict ESM resolver because `tsc` had been configured with `moduleResolution: "Bundler"` and emitted relative specifiers verbatim, so `dist/index.js` carried `from "./api"` (extensionless) and Node rejected the resolution. Workspace consumers never saw this because tsx / vitest / Vite resolve loosely, but `npm install @invinite-org/chartlang-compiler` followed by `import` failed immediately for any Node consumer, and `examples/react-demo/vite.config.ts`'s server-side compile plugin broke at dev-config-load time.
8
+
9
+ This release switches `tsconfig.base.json` to `module: "NodeNext"` / `moduleResolution: "NodeNext"`, and rewrites every relative import / export / dynamic-import / `typeof import("…")` specifier across all packages' source to carry an explicit `.js` (or `/index.js`) suffix. The new resolution mode also surfaces this bug class as a compile error rather than runtime breakage, so it cannot regress.
10
+
11
+ No behavioural change for runtime consumers — the rewritten specifiers resolve to the same TypeScript sources at build time and the same `dist/<path>.js` files at consumer-load time.
12
+
13
+ - 4d44a9c: Three host-robustness fixes discovered during real end-user testing:
14
+
15
+ - **`host-worker`**: `createWorkerHost().load(...)` no longer hangs forever when the underlying `Worker` fails to boot (module fetch fails, exception during construction, OS-level crash). The host now subscribes to the worker's `error` event and rejects any in-flight (or subsequent) `load()` call with `worker failed to boot: <message>`. A new `HostLimits.maxLoadTimeoutMs` (default `30_000`) bounds the wait independently — a silently-dead worker that never fires `error` also can't hang a consumer. `MessagePort`-backed `WorkerLike` test seams remain compatible: the `error` subscription is silently ignored by ports that don't deliver that event.
16
+ - **`host-worker`**: Added a `./worker-boot` subpath export so Vite consumers can write `new Worker(new URL("@invinite-org/chartlang-host-worker/worker-boot", import.meta.url), { type: "module" })` instead of digging into `dist/`. The bundle is regenerated by `pnpm build` and now ships a minimal `.d.ts` next to it so NodeNext type-checking does not error on the bare specifier.
17
+ - **`host-quickjs`**: Added an in-process freshness gate (`dispatcherFreshness.test.ts`) that rebundles `src/dispatcher.ts` in memory via the same `bundleDispatcher()` function `pnpm build:dispatcher` uses, hashes both sides, and fails with a "run `pnpm build`" hint when the committed `dist/dispatcher.js` is stale. Prevents the "source fix landed but tests still pass against the old dispatcher" failure mode.
18
+
19
+ - Updated dependencies [4d44a9c]
20
+ - Updated dependencies [98599b2]
21
+ - Updated dependencies [d1de692]
22
+ - Updated dependencies [98599b2]
23
+ - @invinite-org/chartlang-adapter-kit@1.1.0
24
+ - @invinite-org/chartlang-runtime@1.0.1
25
+ - @invinite-org/chartlang-core@1.0.1
26
+
27
+ ## 1.0.0
28
+
29
+ ### Major Changes
30
+
31
+ - chartlang `1.0.0` -- the `apiVersion: 1` standard.
32
+
33
+ - `apiVersion: 1` frozen: compiler accepts only the frozen language
34
+ version; `STATEFUL_PRIMITIVES` locked at 172 entries by exact
35
+ name-set; every shipping export `@stable`; pre-1.0 deprecations
36
+ removed (`PHASE_1_SCENARIOS`).
37
+ - Canonical language spec published (`docs/spec/`): grammar,
38
+ semantics, manifest, emissions, versioning -- self-contained for
39
+ alternate implementations. The `v1.0.0` tag is the frozen spec
40
+ snapshot.
41
+ - Public conformance reports: `pnpm conformance --report` emits
42
+ `CONFORMANCE.md` + `conformance-report.json`; canvas2d reference
43
+ report published and drift-gated.
44
+ - Adapter-author path proven end-to-end: scaffolded adapters ship a
45
+ wired conformance test; full writing-an-adapter tutorial +
46
+ Lightweight Charts porting walkthrough.
47
+ - Pine migration guide finalised with a pattern-coverage matrix
48
+ audited against the top ~50 Pine scripts.
49
+
50
+ ### Minor Changes
51
+
52
+ - d14a034: Add phase 5 server alerts, multi-timeframe request handling, runtime persistence, QuickJS hosting, expanded plot and table rendering, color helpers, alert conditions, and volume profile primitives.
53
+
54
+ ### Patch Changes
55
+
56
+ - Pre-1.0 surface cleanup: remove the deprecated `PHASE_1_SCENARIOS`
57
+ alias (use `ALL_SCENARIOS`) and promote every shipping export from
58
+ `@experimental` to `@stable` ahead of the `apiVersion: 1` freeze.
59
+ - Updated dependencies [d14a034]
60
+ - Updated dependencies [3cfff10]
61
+ - Updated dependencies [3cfff10]
62
+ - Updated dependencies [3cfff10]
63
+ - Updated dependencies [3cfff10]
64
+ - Updated dependencies [3cfff10]
65
+ - Updated dependencies [3cfff10]
66
+ - Updated dependencies
67
+ - Updated dependencies
68
+ - Updated dependencies
69
+ - @invinite-org/chartlang-adapter-kit@1.0.0
70
+ - @invinite-org/chartlang-core@1.0.0
71
+ - @invinite-org/chartlang-runtime@1.0.0
72
+
73
+ ## 0.5.0
74
+
75
+ ### Phase 5
76
+
77
+ #### Minor Changes
78
+
79
+ - Add the `@invinite-org/chartlang-host-worker/idb` subpath with an
80
+ IndexedDB-backed `PersistentStateStore` for browser warm starts, per PLAN.md
81
+ §6.9 and §8.2.
82
+ - Replace the Phase 4 `request.security` NaN-only path with real
83
+ multi-timeframe secondary stream alignment per PLAN.md §6.8 and §7.2.
84
+ Adapters can route tagged `CandleEvent.streamKey` candles, the worker
85
+ host dispatches them through `ScriptRunner.push`, conformance includes
86
+ MTF scenarios, and the private canvas2d reference adapter now declares
87
+ `multiTimeframe: true`.
88
+
89
+ #### Patch Changes
90
+
91
+ - Updated dependencies
92
+ - Updated dependencies
93
+ - Updated dependencies
94
+ - Updated dependencies
95
+ - Updated dependencies
96
+ - Updated dependencies
97
+ - Updated dependencies
98
+ - Updated dependencies
99
+ - Updated dependencies
100
+ - Updated dependencies
101
+ - Updated dependencies
102
+ - Updated dependencies
103
+ - Updated dependencies
104
+ - Updated dependencies
105
+ - Updated dependencies
106
+ - @invinite-org/chartlang-core@0.5.0
107
+ - @invinite-org/chartlang-adapter-kit@0.5.0
108
+ - @invinite-org/chartlang-runtime@0.5.0
109
+
110
+ ## 0.4.0
111
+
112
+ ### Minor Changes
113
+
114
+ - 3f3ce38: Phase-1 walking-skeleton: ship the canvas2d reference adapter
115
+ (`examples/canvas2d-adapter`). The private example package now
116
+ exports `createCanvas2dAdapter`, `runRendererLoop`,
117
+ `CANVAS2D_CAPABILITIES`, `DEFAULT_PALETTE`, plus a
118
+ `./testing` sub-path entry carrying `MockCanvas2DContext` +
119
+ `hashCallLog` for sibling-package conformance tests (Task 12).
120
+
121
+ Two cross-package adjustments rode along:
122
+
123
+ - `@invinite-org/chartlang-host-worker` adds `createWorkerBoot`
124
+ and `WorkerBootScope` to its public barrel so consumer-repo
125
+ tests (and Task 10's integration test) can pair the worker host
126
+ against a `MessageChannel`-backed scope. The boot factory was
127
+ always testable from within the package; this exposes it as a
128
+ stable surface.
129
+ - `@invinite-org/chartlang-runtime`'s `makeSeriesView` Proxy now
130
+ defines a `has` trap so `"current" in series` (and
131
+ `"length" in series`, `"<n>" in series`) returns `true`. This
132
+ unblocks `runtime/src/emit/plot.ts`'s `isSeriesNumber` check —
133
+ previously the Proxy reported `false` for `in`, so calls like
134
+ `plot(ta.ema(...))` with the real runtime Series threw the
135
+ "outside an active script step" sentinel. Discovered via Task
136
+ 10's end-to-end integration test driving an EMA-cross bundle
137
+ through the worker host into the canvas2d renderer.
138
+
139
+ - 3f3ce38: Land the Phase-1 browser-default `ScriptHost`. `createWorkerHost`
140
+ boots a Web Worker, loads a compiled chartlang bundle via a
141
+ `data:` URL dynamic import, and round-trips `CandleEvent` /
142
+ `RunnerEmissions` over a structured-clone-safe postMessage
143
+ protocol (`HostToWorker` / `WorkerToHost`). The `load` frame
144
+ carries the adapter's `Capabilities` bag and the host's
145
+ `HostLimits`; the worker boot is stateless about both. A
146
+ measurement-only watchdog times every `candleEvent` dispatch
147
+ against `maxCpuMsPerStep` and posts `step-overshoot` (no
148
+ preemption — real interrupt-based caps land with the QuickJS
149
+ host in Phase 5). Drains validate every plot / alert through
150
+ `adapter-kit`'s `validateEmission` before posting; malformed
151
+ emissions become `malformed-emission` diagnostics. Replaces the
152
+ Phase-0 `PACKAGE_VERSION` placeholder.
153
+ - Resolve runtime `input.*` overrides at mount, add adapter input resolver wiring, and audit universal `ta.*` offset support.
154
+
155
+ ### Patch Changes
156
+
157
+ - Updated dependencies [3f3ce38]
158
+ - Updated dependencies [3f3ce38]
159
+ - Updated dependencies [3f3ce38]
160
+ - Updated dependencies [3f3ce38]
161
+ - Updated dependencies [3f3ce38]
162
+ - Updated dependencies [3f3ce38]
163
+ - Updated dependencies [3f3ce38]
164
+ - Updated dependencies [38fb475]
165
+ - Updated dependencies [38fb475]
166
+ - Updated dependencies [38fb475]
167
+ - Updated dependencies [38fb475]
168
+ - Updated dependencies [38fb475]
169
+ - Updated dependencies [38fb475]
170
+ - Updated dependencies [38fb475]
171
+ - Updated dependencies [38fb475]
172
+ - Updated dependencies [38fb475]
173
+ - Updated dependencies [38fb475]
174
+ - Updated dependencies [38fb475]
175
+ - Updated dependencies [38fb475]
176
+ - Updated dependencies [38fb475]
177
+ - Updated dependencies [38fb475]
178
+ - Updated dependencies [38fb475]
179
+ - Updated dependencies [38fb475]
180
+ - Updated dependencies [38fb475]
181
+ - Updated dependencies [38fb475]
182
+ - Updated dependencies [38fb475]
183
+ - Updated dependencies [38fb475]
184
+ - Updated dependencies [38fb475]
185
+ - Updated dependencies [38fb475]
186
+ - Updated dependencies [38fb475]
187
+ - Updated dependencies [38fb475]
188
+ - Updated dependencies [38fb475]
189
+ - Updated dependencies [38fb475]
190
+ - Updated dependencies [38fb475]
191
+ - Updated dependencies [38fb475]
192
+ - Updated dependencies [38fb475]
193
+ - Updated dependencies [38fb475]
194
+ - Updated dependencies [38fb475]
195
+ - Updated dependencies [b0d296b]
196
+ - Updated dependencies [b0d296b]
197
+ - Updated dependencies [b0d296b]
198
+ - Updated dependencies [b0d296b]
199
+ - Updated dependencies [b0d296b]
200
+ - Updated dependencies [b0d296b]
201
+ - Updated dependencies [b0d296b]
202
+ - Updated dependencies [b0d296b]
203
+ - Updated dependencies [b0d296b]
204
+ - Updated dependencies [b0d296b]
205
+ - Updated dependencies [b0d296b]
206
+ - Updated dependencies [b0d296b]
207
+ - Updated dependencies [b0d296b]
208
+ - Updated dependencies [b0d296b]
209
+ - Updated dependencies [b0d296b]
210
+ - Updated dependencies [b0d296b]
211
+ - Updated dependencies [b0d296b]
212
+ - Updated dependencies [b0d296b]
213
+ - Updated dependencies [b0d296b]
214
+ - Updated dependencies
215
+ - Updated dependencies
216
+ - Updated dependencies
217
+ - Updated dependencies
218
+ - Updated dependencies
219
+ - Updated dependencies
220
+ - Updated dependencies
221
+ - Updated dependencies
222
+ - Updated dependencies
223
+ - Updated dependencies
224
+ - Updated dependencies
225
+ - Updated dependencies
226
+ - @invinite-org/chartlang-adapter-kit@0.4.0
227
+ - @invinite-org/chartlang-runtime@0.4.0
228
+ - @invinite-org/chartlang-core@0.4.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Invinite
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # @invinite-org/chartlang-host-worker
2
+
3
+ `experimental`
4
+
5
+ Browser-default `ScriptHost` for chartlang. Boots a Web Worker, loads a
6
+ compiled script bundle, and round-trips `CandleEvent` / `RunnerEmissions`
7
+ across a structured-clone-safe postMessage protocol.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @invinite-org/chartlang-host-worker
13
+ ```
14
+
15
+ ## Public surface
16
+
17
+ - `createWorkerHost(opts) → ScriptHost` — main-side factory; the canvas2d
18
+ reference adapter (Task 10) consumes the returned host.
19
+ - `DEFAULT_LIMITS` — Phase-1 `HostLimits` defaults
20
+ (`maxCpuMsPerStep: 50`, `maxHeapBytes: 64 MiB`, `maxRingBufferBars: 5000`,
21
+ `maxLoadTimeoutMs: 30000`).
22
+ - `idbStateStore(opts)` from `@invinite-org/chartlang-host-worker/idb` —
23
+ IndexedDB `PersistentStateStore` for browser warm starts.
24
+ - Persists one snapshot per `StateStoreKey`; default cap is 50 MiB.
25
+ - Oldest snapshots are evicted first when writes exceed the cap.
26
+ - `@invinite-org/chartlang-host-worker/worker-boot` — bundled worker entry
27
+ for Vite / bundler `new Worker(new URL(...))` patterns. Side-effect only.
28
+ - Types: `ScriptHost`, `HostLimits`, `WorkerLike`, `HostCompiledScript`,
29
+ `HostToWorker`, `WorkerToHost`, `CreateWorkerHostOpts`.
30
+
31
+ ## Minimum-viable API call
32
+
33
+ ```ts
34
+ import { createWorkerHost } from "@invinite-org/chartlang-host-worker";
35
+ // host: ScriptHost — passed to an adapter at construction time.
36
+ ```
37
+
38
+ ### Vite worker URL
39
+
40
+ ```ts
41
+ const url = new URL(
42
+ "@invinite-org/chartlang-host-worker/worker-boot",
43
+ import.meta.url,
44
+ );
45
+ const worker = new Worker(url, { type: "module" });
46
+ const host = createWorkerHost({ capabilities, workerLike: worker });
47
+ ```
48
+
49
+ ## Stability
50
+
51
+ Phase 1 ships the postMessage wire protocol + a measurement-based CPU
52
+ watchdog (`step-overshoot` reports observed elapsed ms; no preemption).
53
+ Deferred to Phase 5 (per PLAN §19):
54
+
55
+ - Worker-side CSP enforcement.
56
+ - Hard heap caps (`maxHeapBytes` is advisory today — no browser API
57
+ exposes a reliable per-worker heap limit).
58
+ - Real preemption via `setInterruptHandler` (lands with the QuickJS
59
+ host).
60
+ - Fingerprint-only globals (`Math.random`, `Date.now`, …) — Phase 1
61
+ relies on the compiler's `forbiddenConstructs` pass to scrub these
62
+ from the bundle before it ever reaches a worker.
63
+
64
+ ## Docs
65
+
66
+ See [`docs/hosts/worker.md`](../../docs/hosts/worker.md).
67
+
68
+ ## License
69
+
70
+ MIT
@@ -0,0 +1,45 @@
1
+ import type { HostToWorker, WorkerToHost } from "./protocol.js";
2
+ /**
3
+ * Duck-typed slice of the worker global scope the boot factory needs. Lets
4
+ * tests drive `createWorkerBoot` against a `MessageChannel` port without
5
+ * faking the full `WorkerGlobalScope`.
6
+ *
7
+ * @since 0.1
8
+ * @stable
9
+ * @example
10
+ * const scope: WorkerBootScope = {
11
+ * addEventListener: () => {},
12
+ * postMessage: () => {},
13
+ * };
14
+ * void scope;
15
+ */
16
+ export type WorkerBootScope = {
17
+ addEventListener(type: "message", listener: (ev: MessageEvent<HostToWorker>) => void): void;
18
+ postMessage(msg: WorkerToHost): void;
19
+ };
20
+ /**
21
+ * Wire `scope` to the host-worker postMessage protocol. Lazily imports the
22
+ * compiled module via a `data:` URL so the same code path runs inside a real
23
+ * browser `Worker` and inside Node tests (`MessageChannel`-backed).
24
+ *
25
+ * Lifecycle:
26
+ *
27
+ * - `load` → dynamic import → `createScriptRunner(...)` → cache `limits`.
28
+ * Posts `loaded` on success or `loadError` on failure.
29
+ * - `candleEvent` → wrap dispatch in `watchStep(...)`; post `step-overshoot`
30
+ * when over budget. Errors map to `fatal`.
31
+ * - `drain` → validate every plot / alert emission; sink malformed ones into
32
+ * the diagnostics array; post `emissions` with the original nonce.
33
+ * - `dispose` → release the runner; subsequent messages map to `fatal`.
34
+ *
35
+ * @since 0.1
36
+ * @stable
37
+ * @example
38
+ * // import { createWorkerBoot } from "@invinite-org/chartlang-host-worker";
39
+ * // const scope = self;
40
+ * // createWorkerBoot(scope);
41
+ * const fn: typeof createWorkerBoot = createWorkerBoot;
42
+ * void fn;
43
+ */
44
+ export declare function createWorkerBoot(scope: WorkerBootScope): void;
45
+ //# sourceMappingURL=createWorkerBoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorkerBoot.d.ts","sourceRoot":"","sources":["../src/createWorkerBoot.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGhE;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG;IAC1B,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,YAAY,CAAC,YAAY,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5F,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC;CACxC,CAAC;AAiBF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAkF7D"}
@@ -0,0 +1,122 @@
1
+ // Copyright (c) 2026 Invinite. Licensed under the MIT License.
2
+ // See the LICENSE file in the repo root for full license text.
3
+ import { createScriptRunner } from "@invinite-org/chartlang-runtime";
4
+ import { filterEmissions } from "./filterEmissions.js";
5
+ import { watchStep } from "./limits.js";
6
+ async function importCompiledModule(moduleSource) {
7
+ // `encodeURIComponent` preserves multi-byte UTF-8 across the data URL
8
+ // without the Annex-B `unescape` round-trip. ESM `import("data:…")`
9
+ // accepts percent-encoded text/javascript directly in both browsers
10
+ // and Node 20+.
11
+ const url = `data:text/javascript;charset=utf-8,${encodeURIComponent(moduleSource)}`;
12
+ return (await import(/* @vite-ignore */ url));
13
+ }
14
+ function isFrame(value) {
15
+ if (value === null || typeof value !== "object")
16
+ return false;
17
+ const k = value.kind;
18
+ return typeof k === "string";
19
+ }
20
+ /**
21
+ * Wire `scope` to the host-worker postMessage protocol. Lazily imports the
22
+ * compiled module via a `data:` URL so the same code path runs inside a real
23
+ * browser `Worker` and inside Node tests (`MessageChannel`-backed).
24
+ *
25
+ * Lifecycle:
26
+ *
27
+ * - `load` → dynamic import → `createScriptRunner(...)` → cache `limits`.
28
+ * Posts `loaded` on success or `loadError` on failure.
29
+ * - `candleEvent` → wrap dispatch in `watchStep(...)`; post `step-overshoot`
30
+ * when over budget. Errors map to `fatal`.
31
+ * - `drain` → validate every plot / alert emission; sink malformed ones into
32
+ * the diagnostics array; post `emissions` with the original nonce.
33
+ * - `dispose` → release the runner; subsequent messages map to `fatal`.
34
+ *
35
+ * @since 0.1
36
+ * @stable
37
+ * @example
38
+ * // import { createWorkerBoot } from "@invinite-org/chartlang-host-worker";
39
+ * // const scope = self;
40
+ * // createWorkerBoot(scope);
41
+ * const fn: typeof createWorkerBoot = createWorkerBoot;
42
+ * void fn;
43
+ */
44
+ export function createWorkerBoot(scope) {
45
+ let runner = null;
46
+ let limits = null;
47
+ scope.addEventListener("message", async (ev) => {
48
+ const msg = ev.data;
49
+ if (!isFrame(msg)) {
50
+ scope.postMessage({
51
+ kind: "fatal",
52
+ message: "malformed host frame: not a plain object with a string 'kind'",
53
+ });
54
+ return;
55
+ }
56
+ if (msg.kind === "load") {
57
+ try {
58
+ const mod = await importCompiledModule(msg.compiled.moduleSource);
59
+ runner = createScriptRunner({
60
+ compiled: mod.default,
61
+ capabilities: msg.capabilities,
62
+ ...(msg.symInfo !== undefined ? { symInfo: msg.symInfo } : {}),
63
+ ...(msg.inputOverrides !== undefined
64
+ ? { inputOverrides: msg.inputOverrides }
65
+ : {}),
66
+ });
67
+ limits = msg.limits;
68
+ scope.postMessage({ kind: "loaded" });
69
+ }
70
+ catch (err) {
71
+ scope.postMessage({
72
+ kind: "loadError",
73
+ message: err instanceof Error ? err.message : String(err),
74
+ });
75
+ }
76
+ return;
77
+ }
78
+ try {
79
+ switch (msg.kind) {
80
+ case "candleEvent": {
81
+ if (runner === null || limits === null) {
82
+ throw new Error("candleEvent before load");
83
+ }
84
+ const r = runner;
85
+ const { overshoot } = await watchStep(() => r.push(msg.event), limits.maxCpuMsPerStep);
86
+ if (overshoot > 0) {
87
+ scope.postMessage({ kind: "step-overshoot", observedMs: overshoot });
88
+ }
89
+ break;
90
+ }
91
+ case "drain": {
92
+ if (runner === null) {
93
+ throw new Error("drain before load");
94
+ }
95
+ const cleaned = filterEmissions(runner.drain());
96
+ scope.postMessage({
97
+ kind: "emissions",
98
+ nonce: msg.nonce,
99
+ emissions: cleaned,
100
+ });
101
+ break;
102
+ }
103
+ case "dispose": {
104
+ await runner?.dispose();
105
+ runner = null;
106
+ limits = null;
107
+ break;
108
+ }
109
+ default: {
110
+ throw new Error(`unknown frame kind: ${msg.kind}`);
111
+ }
112
+ }
113
+ }
114
+ catch (err) {
115
+ scope.postMessage({
116
+ kind: "fatal",
117
+ message: err instanceof Error ? err.message : String(err),
118
+ });
119
+ }
120
+ });
121
+ }
122
+ //# sourceMappingURL=createWorkerBoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorkerBoot.js","sourceRoot":"","sources":["../src/createWorkerBoot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { AdapterSymInfo, Capabilities } from "@invinite-org/chartlang-adapter-kit";
2
+ import type { HostLimits, ScriptHost, WorkerLike } from "./types.js";
3
+ /**
4
+ * Constructor options for {@link createWorkerHost}.
5
+ *
6
+ * - `capabilities` — the adapter's declared capability bag. Bolted onto every
7
+ * `load` postMessage; the worker boot never falls back to a default.
8
+ * - `symInfo` — optional adapter-supplied metadata for runtime `syminfo.*`.
9
+ * - `resolveInputs` — optional adapter callback. The host resolves it during
10
+ * `load()` and sends the plain override record to the worker.
11
+ * - `workerLike` — injection seam for tests. Production callers omit it; the
12
+ * host then constructs a real `Worker` via {@link defaultWorkerFactory}.
13
+ * - `limits` — partial `HostLimits` overrides; missing fields fall through to
14
+ * {@link DEFAULT_LIMITS}.
15
+ * - `onWorkerError` — called when the worker posts `step-overshoot` or
16
+ * `fatal`. The host does not synthesize diagnostics into the next
17
+ * `drain()` — Phase 1 keeps overshoot surfacing on the adapter.
18
+ *
19
+ * @since 0.1
20
+ * @stable
21
+ * @example
22
+ * const opts: CreateWorkerHostOpts = {
23
+ * capabilities: {} as Capabilities,
24
+ * };
25
+ * void opts;
26
+ */
27
+ export type CreateWorkerHostOpts = {
28
+ readonly capabilities: Capabilities;
29
+ readonly symInfo?: AdapterSymInfo;
30
+ readonly resolveInputs?: (scriptId: string) => Readonly<Record<string, unknown>>;
31
+ readonly workerLike?: WorkerLike;
32
+ readonly limits?: Partial<HostLimits>;
33
+ readonly onWorkerError?: (message: string) => void;
34
+ };
35
+ /**
36
+ * Build a browser-default `ScriptHost` around a Web Worker. The host
37
+ * round-trips `load` / `push` / `drain` / `dispose` calls across the worker
38
+ * boundary via structured-clone-safe postMessage frames defined in
39
+ * {@link HostToWorker} / {@link WorkerToHost}.
40
+ *
41
+ * The host owns the `nonce` counter for `drain` correlation, the in-flight
42
+ * `load` promise, and the in-flight drain registry. `dispose` posts the
43
+ * tear-down message, calls `terminate()` when the underlying `WorkerLike`
44
+ * supports it, and clears the pending-drain map.
45
+ *
46
+ * @since 0.1
47
+ * @stable
48
+ * @example
49
+ * import { createWorkerHost } from "@invinite-org/chartlang-host-worker";
50
+ * // const host = createWorkerHost({ capabilities });
51
+ * const fn: typeof createWorkerHost = createWorkerHost;
52
+ * void fn;
53
+ */
54
+ export declare function createWorkerHost(opts: CreateWorkerHostOpts): ScriptHost;
55
+ //# sourceMappingURL=createWorkerHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createWorkerHost.d.ts","sourceRoot":"","sources":["../src/createWorkerHost.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACR,cAAc,EACd,YAAY,EAEf,MAAM,qCAAqC,CAAC;AAK7C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,oBAAoB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD,CAAC;AAaF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,UAAU,CA+IvE"}