@czap/worker 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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/compositor-script.d.ts +19 -0
  4. package/dist/compositor-script.d.ts.map +1 -0
  5. package/dist/compositor-script.js +374 -0
  6. package/dist/compositor-script.js.map +1 -0
  7. package/dist/compositor-startup.d.ts +200 -0
  8. package/dist/compositor-startup.d.ts.map +1 -0
  9. package/dist/compositor-startup.js +490 -0
  10. package/dist/compositor-startup.js.map +1 -0
  11. package/dist/compositor-types.d.ts +135 -0
  12. package/dist/compositor-types.d.ts.map +1 -0
  13. package/dist/compositor-types.js +7 -0
  14. package/dist/compositor-types.js.map +1 -0
  15. package/dist/compositor-worker.d.ts +65 -0
  16. package/dist/compositor-worker.d.ts.map +1 -0
  17. package/dist/compositor-worker.js +454 -0
  18. package/dist/compositor-worker.js.map +1 -0
  19. package/dist/evaluate-inline.d.ts +22 -0
  20. package/dist/evaluate-inline.d.ts.map +1 -0
  21. package/dist/evaluate-inline.js +42 -0
  22. package/dist/evaluate-inline.js.map +1 -0
  23. package/dist/host.d.ts +97 -0
  24. package/dist/host.d.ts.map +1 -0
  25. package/dist/host.js +115 -0
  26. package/dist/host.js.map +1 -0
  27. package/dist/index.d.ts +40 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +40 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/messages.d.ts +254 -0
  32. package/dist/messages.d.ts.map +1 -0
  33. package/dist/messages.js +55 -0
  34. package/dist/messages.js.map +1 -0
  35. package/dist/render-worker.d.ts +77 -0
  36. package/dist/render-worker.d.ts.map +1 -0
  37. package/dist/render-worker.js +396 -0
  38. package/dist/render-worker.js.map +1 -0
  39. package/dist/spsc-ring.d.ts +171 -0
  40. package/dist/spsc-ring.d.ts.map +1 -0
  41. package/dist/spsc-ring.js +240 -0
  42. package/dist/spsc-ring.js.map +1 -0
  43. package/package.json +51 -0
  44. package/src/compositor-script.ts +374 -0
  45. package/src/compositor-startup.ts +666 -0
  46. package/src/compositor-types.ts +175 -0
  47. package/src/compositor-worker.ts +613 -0
  48. package/src/evaluate-inline.ts +42 -0
  49. package/src/host.ts +189 -0
  50. package/src/index.ts +49 -0
  51. package/src/messages.ts +343 -0
  52. package/src/render-worker.ts +454 -0
  53. package/src/spsc-ring.ts +309 -0
@@ -0,0 +1,65 @@
1
+ /**
2
+ * CompositorWorker -- off-main-thread compositor running in a Web Worker.
3
+ *
4
+ * The worker maintains a simplified compositor that:
5
+ * - Tracks quantizer definitions (name maps to boundary plus current state)
6
+ * - Evaluates threshold-based quantization
7
+ * - Maintains blend weight overrides
8
+ * - Produces CompositeState on `compute` commands
9
+ * - Uses DirtyFlags for selective recomputation
10
+ *
11
+ * The worker script is inlined as a Blob URL to avoid bundler complexity
12
+ * with separate worker entry files.
13
+ *
14
+ * @module
15
+ */
16
+ import type { WorkerConfig } from './messages.js';
17
+ export type { CompositorWorkerStartupStage, CompositorWorkerStartupTelemetry } from './compositor-types.js';
18
+ import type { CompositorWorkerStartupStage, CompositorWorkerShape, CompositorWorkerStartupTelemetry } from './compositor-types.js';
19
+ declare function _createCompositorWorker(config?: WorkerConfig, startupTelemetry?: CompositorWorkerStartupTelemetry): CompositorWorkerShape;
20
+ /**
21
+ * Factory namespace for the compositor worker.
22
+ *
23
+ * Call {@link CompositorWorker.create} on the main thread to spin up a
24
+ * worker that evaluates quantizer boundaries and emits
25
+ * {@link CompositorWorkerState} snapshots. The returned
26
+ * {@link CompositorWorkerShape} owns the underlying `Worker` -- call
27
+ * `dispose()` (or park via the lease pool) when finished.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { CompositorWorker } from '@czap/worker';
32
+ *
33
+ * const compositor = CompositorWorker.create({ poolCapacity: 64 });
34
+ * compositor.addQuantizer('brightness', {
35
+ * id: 'boundary:brightness',
36
+ * states: ['dim', 'bright'],
37
+ * thresholds: [0.5],
38
+ * });
39
+ * const unsub = compositor.onState((state) => {
40
+ * // state.discrete.brightness === 'bright' | 'dim'
41
+ * });
42
+ * compositor.evaluate('brightness', 0.7);
43
+ * compositor.requestCompute();
44
+ * // ...later:
45
+ * unsub();
46
+ * compositor.dispose();
47
+ * ```
48
+ */
49
+ export declare const CompositorWorker: {
50
+ /**
51
+ * Spin up a new compositor worker. Returns immediately; the worker
52
+ * posts `ready` asynchronously. Optionally provide startup telemetry
53
+ * to capture per-stage timings.
54
+ */
55
+ readonly create: typeof _createCompositorWorker;
56
+ };
57
+ export declare namespace CompositorWorker {
58
+ /** Public host-side surface returned by {@link CompositorWorker.create}. */
59
+ type Shape = CompositorWorkerShape;
60
+ /** Named startup stage reported to telemetry sinks. */
61
+ type StartupStage = CompositorWorkerStartupStage;
62
+ /** Telemetry sink accepted by {@link CompositorWorker.create}. */
63
+ type StartupTelemetry = CompositorWorkerStartupTelemetry;
64
+ }
65
+ //# sourceMappingURL=compositor-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositor-worker.d.ts","sourceRoot":"","sources":["../src/compositor-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAEV,YAAY,EAIb,MAAM,eAAe,CAAC;AAIvB,YAAY,EAAE,4BAA4B,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AAE5G,OAAO,KAAK,EAEV,4BAA4B,EAE5B,qBAAqB,EACrB,gCAAgC,EACjC,MAAM,uBAAuB,CAAC;AA8B/B,iBAAS,uBAAuB,CAC9B,MAAM,CAAC,EAAE,YAAY,EACrB,gBAAgB,CAAC,EAAE,gCAAgC,GAClD,qBAAqB,CA4evB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,4EAA4E;IAC5E,KAAY,KAAK,GAAG,qBAAqB,CAAC;IAC1C,uDAAuD;IACvD,KAAY,YAAY,GAAG,4BAA4B,CAAC;IACxD,kEAAkE;IAClE,KAAY,gBAAgB,GAAG,gCAAgC,CAAC;CACjE"}
@@ -0,0 +1,454 @@
1
+ /**
2
+ * CompositorWorker -- off-main-thread compositor running in a Web Worker.
3
+ *
4
+ * The worker maintains a simplified compositor that:
5
+ * - Tracks quantizer definitions (name maps to boundary plus current state)
6
+ * - Evaluates threshold-based quantization
7
+ * - Maintains blend weight overrides
8
+ * - Produces CompositeState on `compute` commands
9
+ * - Uses DirtyFlags for selective recomputation
10
+ *
11
+ * The worker script is inlined as a Blob URL to avoid bundler complexity
12
+ * with separate worker entry files.
13
+ *
14
+ * @module
15
+ */
16
+ import { Diagnostics } from '@czap/core';
17
+ import { makeResolvedStateEnvelope } from './messages.js';
18
+ // Import startup/lifecycle helpers
19
+ import { currentTimeNs, recordStartupDiagnosticStage, notifyResolvedStateSettled, createStartupPacketState, buildStartupComputePacket, getStartupPacketRuntimeSeed, runtimeMatchesStartupSeed, setStartupPacketRegistration, pushStartupPacketUpdate, setStartupPacketInitialState, setStartupPacketBlendWeights, removeStartupPacketEntries, resetStartupPacketTransientState, claimCompositorLease, parkOrDisposeCompositorLease, _send, prepareRegistrationForTransfer, sameBootstrapRegistration, evaluateRegistrationState, toResolvedStateEntriesFromAck, } from './compositor-startup.js';
20
+ // ---------------------------------------------------------------------------
21
+ // Factory
22
+ // ---------------------------------------------------------------------------
23
+ function _createCompositorWorker(config, startupTelemetry) {
24
+ const capacity = config?.poolCapacity ?? 64;
25
+ const { worker, runtime, bootstrapSnapshot } = claimCompositorLease(capacity, startupTelemetry);
26
+ const snapshotByName = new Map(bootstrapSnapshot.map((registration) => [registration.name, registration]));
27
+ const activeRegistrations = new Map();
28
+ const stateListeners = new Set();
29
+ const resolvedStateAckListeners = new Set();
30
+ const metricsListeners = new Set();
31
+ const confirmedSnapshotNames = new Set();
32
+ const preparedRegistrationCache = new Map();
33
+ const startupPacket = createStartupPacketState(bootstrapSnapshot.length > 0 ? 'warm-snapshot' : 'cold', bootstrapSnapshot);
34
+ let steadyStatePendingUpdates = [];
35
+ let flushScheduled = false;
36
+ let startupMode = true;
37
+ let startupDispatchCompletedNs = null;
38
+ let startupStatePending = false;
39
+ let resolvedStateDispatchCompletedNs = null;
40
+ let resolvedStateAckPending = false;
41
+ let lastMetrics = null;
42
+ let lastWorkerError = null;
43
+ const getPreparedRegistration = (registration) => {
44
+ const cached = preparedRegistrationCache.get(registration.name);
45
+ /* v8 ignore next — current call sites always delete the cache entry in the same
46
+ synchronous turn that sets it (see `consumePreparedRegistrations`), so this
47
+ cache-hit arm is reserved for a future pre-flight path that warms the cache
48
+ before dispatch; unreachable under today's code paths. */
49
+ if (cached && cached.source === registration && cached.buffer.byteLength > 0) {
50
+ return cached;
51
+ }
52
+ const { registration: transferRegistration, buffer } = prepareRegistrationForTransfer(registration);
53
+ const prepared = {
54
+ source: registration,
55
+ transferRegistration,
56
+ buffer,
57
+ };
58
+ preparedRegistrationCache.set(registration.name, prepared);
59
+ return prepared;
60
+ };
61
+ const consumePreparedRegistrations = (registrations) => {
62
+ const buffers = [];
63
+ const transferRegistrations = registrations.map((registration) => {
64
+ const prepared = getPreparedRegistration(registration);
65
+ preparedRegistrationCache.delete(registration.name);
66
+ buffers.push(prepared.buffer);
67
+ return prepared.transferRegistration;
68
+ });
69
+ return {
70
+ registrations: transferRegistrations,
71
+ buffers,
72
+ };
73
+ };
74
+ const flushPendingUpdates = () => {
75
+ flushScheduled = false;
76
+ if (steadyStatePendingUpdates.length === 0) {
77
+ return;
78
+ }
79
+ const updates = steadyStatePendingUpdates;
80
+ steadyStatePendingUpdates = [];
81
+ _send(worker, {
82
+ type: 'apply-updates',
83
+ updates,
84
+ });
85
+ };
86
+ const queueUpdate = (update) => {
87
+ if (startupMode) {
88
+ pushStartupPacketUpdate(startupPacket, update);
89
+ return;
90
+ }
91
+ steadyStatePendingUpdates.push(update);
92
+ if (flushScheduled) {
93
+ return;
94
+ }
95
+ flushScheduled = true;
96
+ queueMicrotask(flushPendingUpdates);
97
+ };
98
+ const markStartupBootstrapForRebuild = () => {
99
+ if (startupPacket.bootstrapMode === 'warm-snapshot') {
100
+ startupPacket.bootstrapMode = 'rebuild';
101
+ }
102
+ };
103
+ const applyResolvedStatesToRuntime = (states) => {
104
+ for (const entry of states) {
105
+ runtime.markDirty(entry.name);
106
+ runtime.applyState(entry.name, entry.state);
107
+ }
108
+ };
109
+ const ensureResolvedStateMode = () => {
110
+ if (!startupMode) {
111
+ flushPendingUpdates();
112
+ return;
113
+ }
114
+ startupMode = false;
115
+ startupStatePending = false;
116
+ startupDispatchCompletedNs = null;
117
+ flushScheduled = false;
118
+ steadyStatePendingUpdates = [];
119
+ const registrations = Array.from(activeRegistrations.values());
120
+ if (startupPacket.bootstrapMode !== 'cold') {
121
+ _send(worker, { type: 'init' });
122
+ }
123
+ if (registrations.length > 0) {
124
+ const { registrations: transferRegs, buffers } = consumePreparedRegistrations(registrations);
125
+ _send(worker, {
126
+ type: 'bootstrap-quantizers',
127
+ registrations: transferRegs,
128
+ }, buffers);
129
+ }
130
+ resetStartupPacketTransientState(startupPacket);
131
+ };
132
+ const sendResolvedStateMessage = (type, states) => {
133
+ if (states.length === 0) {
134
+ return;
135
+ }
136
+ ensureResolvedStateMode();
137
+ applyResolvedStatesToRuntime(states);
138
+ const expectAck = resolvedStateAckListeners.size > 0 || startupTelemetry !== undefined;
139
+ const dispatchStartNs = currentTimeNs();
140
+ _send(worker, makeResolvedStateEnvelope(type, states, expectAck));
141
+ resolvedStateDispatchCompletedNs = currentTimeNs();
142
+ resolvedStateAckPending = expectAck;
143
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:dispatch-send', resolvedStateDispatchCompletedNs - dispatchStartNs);
144
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:packet-finalize', 0);
145
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:post-send-bookkeeping', 0);
146
+ };
147
+ const handleMessage = (e) => {
148
+ const msg = e.data;
149
+ if (!msg || typeof msg.type !== 'string')
150
+ return;
151
+ switch (msg.type) {
152
+ case 'ready':
153
+ break;
154
+ case 'state':
155
+ if (startupStatePending) {
156
+ const eventStartNs = currentTimeNs();
157
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:message-receipt', eventStartNs - startupDispatchCompletedNs);
158
+ for (const [name, state] of Object.entries(msg.state.discrete ?? {})) {
159
+ runtime.applyState(name, state);
160
+ }
161
+ const callbackStartNs = currentTimeNs();
162
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:callback-queue-turn', callbackStartNs - eventStartNs);
163
+ for (const cb of stateListeners)
164
+ cb({ ...msg.state, resolvedStateGenerations: msg.resolvedStateGenerations });
165
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:host-callback-delivery', currentTimeNs() - callbackStartNs);
166
+ startupStatePending = false;
167
+ startupDispatchCompletedNs = null;
168
+ break;
169
+ }
170
+ for (const [name, state] of Object.entries(msg.state.discrete ?? {})) {
171
+ runtime.applyState(name, state);
172
+ }
173
+ for (const cb of stateListeners)
174
+ cb({ ...msg.state, resolvedStateGenerations: msg.resolvedStateGenerations });
175
+ break;
176
+ case 'resolved-state-ack':
177
+ if (!resolvedStateAckPending || resolvedStateDispatchCompletedNs === null) {
178
+ notifyResolvedStateSettled(startupTelemetry, toResolvedStateEntriesFromAck(msg));
179
+ break;
180
+ }
181
+ const eventStartNs = currentTimeNs();
182
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:message-receipt', eventStartNs - resolvedStateDispatchCompletedNs);
183
+ const callbackStartNs = currentTimeNs();
184
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:callback-queue-turn', callbackStartNs - eventStartNs);
185
+ notifyResolvedStateSettled(startupTelemetry, toResolvedStateEntriesFromAck(msg));
186
+ if (resolvedStateAckListeners.size > 0) {
187
+ for (const cb of resolvedStateAckListeners)
188
+ cb(msg);
189
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:host-callback-delivery', currentTimeNs() - callbackStartNs);
190
+ }
191
+ else {
192
+ recordStartupDiagnosticStage(startupTelemetry, 'state-delivery:host-callback-delivery', 0);
193
+ }
194
+ resolvedStateAckPending = false;
195
+ resolvedStateDispatchCompletedNs = null;
196
+ break;
197
+ case 'metrics':
198
+ lastMetrics = { fps: msg.fps, budgetUsed: msg.budgetUsed };
199
+ for (const cb of metricsListeners)
200
+ cb(msg.fps, msg.budgetUsed);
201
+ break;
202
+ case 'error':
203
+ lastWorkerError = msg.message;
204
+ Diagnostics.error({
205
+ source: 'czap/worker.compositor-worker',
206
+ code: 'worker-message-error',
207
+ message: 'Compositor worker reported an error.',
208
+ detail: msg.message,
209
+ });
210
+ break;
211
+ }
212
+ };
213
+ const handleError = (e) => {
214
+ Diagnostics.error({
215
+ source: 'czap/worker.compositor-worker',
216
+ code: 'worker-unhandled-error',
217
+ message: 'Compositor worker raised an unhandled error.',
218
+ detail: e.message,
219
+ });
220
+ };
221
+ const listenerBindStartNs = currentTimeNs();
222
+ worker.addEventListener('message', handleMessage);
223
+ worker.addEventListener('error', handleError);
224
+ startupTelemetry?.recordStage('listener-bind', currentTimeNs() - listenerBindStartNs);
225
+ if (startupPacket.bootstrapMode === 'cold') {
226
+ _send(worker, { type: 'init' });
227
+ }
228
+ void lastMetrics;
229
+ void lastWorkerError;
230
+ return {
231
+ get worker() {
232
+ return worker;
233
+ },
234
+ get runtime() {
235
+ return runtime;
236
+ },
237
+ addQuantizer(name, boundary) {
238
+ const registration = {
239
+ name,
240
+ boundaryId: boundary.id,
241
+ states: boundary.states,
242
+ thresholds: boundary.thresholds,
243
+ };
244
+ const previousRequested = activeRegistrations.get(name);
245
+ if (sameBootstrapRegistration(previousRequested, registration)) {
246
+ if (startupPacket.bootstrapMode === 'warm-snapshot' && snapshotByName.has(name)) {
247
+ confirmedSnapshotNames.add(name);
248
+ }
249
+ return;
250
+ }
251
+ preparedRegistrationCache.delete(name);
252
+ activeRegistrations.set(name, registration);
253
+ const snapshotRegistration = snapshotByName.get(name);
254
+ const isSnapshotMatch = sameBootstrapRegistration(snapshotRegistration, registration);
255
+ if (runtime.hasQuantizer(name) && !isSnapshotMatch) {
256
+ runtime.removeQuantizer(name);
257
+ }
258
+ if (!runtime.hasQuantizer(name)) {
259
+ runtime.registerQuantizer(name, boundary.states);
260
+ }
261
+ if (startupPacket.bootstrapMode === 'warm-snapshot' && isSnapshotMatch) {
262
+ confirmedSnapshotNames.add(name);
263
+ return;
264
+ }
265
+ confirmedSnapshotNames.delete(name);
266
+ if (snapshotRegistration || startupPacket.bootstrapMode === 'warm-snapshot') {
267
+ markStartupBootstrapForRebuild();
268
+ }
269
+ if (startupMode) {
270
+ setStartupPacketRegistration(startupPacket, registration);
271
+ return;
272
+ }
273
+ const { registrations: transferRegistrations, buffers } = consumePreparedRegistrations([registration]);
274
+ _send(worker, { type: 'add-quantizer', ...transferRegistrations[0] }, buffers);
275
+ },
276
+ removeQuantizer(name) {
277
+ preparedRegistrationCache.delete(name);
278
+ activeRegistrations.delete(name);
279
+ confirmedSnapshotNames.delete(name);
280
+ runtime.removeQuantizer(name);
281
+ if (snapshotByName.has(name)) {
282
+ markStartupBootstrapForRebuild();
283
+ }
284
+ if (startupMode) {
285
+ removeStartupPacketEntries(startupPacket, name);
286
+ return;
287
+ }
288
+ queueUpdate({ type: 'remove-quantizer', name });
289
+ },
290
+ evaluate(name, value) {
291
+ if (startupMode && snapshotByName.has(name) && !confirmedSnapshotNames.has(name)) {
292
+ markStartupBootstrapForRebuild();
293
+ }
294
+ if (startupMode) {
295
+ const activeRegistration = activeRegistrations.get(name);
296
+ if (activeRegistration) {
297
+ const nextState = evaluateRegistrationState(activeRegistration, value);
298
+ if (nextState !== activeRegistration.states[0]) {
299
+ confirmedSnapshotNames.delete(name);
300
+ }
301
+ setStartupPacketInitialState(startupPacket, activeRegistration, nextState);
302
+ runtime.markDirty(name);
303
+ return;
304
+ }
305
+ }
306
+ runtime.markDirty(name);
307
+ queueUpdate({ type: 'evaluate', name, value });
308
+ },
309
+ setBlendWeights(name, weights) {
310
+ if (startupMode && snapshotByName.has(name) && !confirmedSnapshotNames.has(name)) {
311
+ markStartupBootstrapForRebuild();
312
+ }
313
+ if (startupMode && setStartupPacketBlendWeights(startupPacket, name, weights)) {
314
+ confirmedSnapshotNames.delete(name);
315
+ runtime.markDirty(name);
316
+ return;
317
+ }
318
+ runtime.markDirty(name);
319
+ queueUpdate({ type: 'set-blend', name, weights });
320
+ },
321
+ bootstrapResolvedState(states) {
322
+ sendResolvedStateMessage('bootstrap-resolved-state', states);
323
+ },
324
+ applyResolvedState(states) {
325
+ sendResolvedStateMessage('apply-resolved-state', states);
326
+ },
327
+ requestCompute() {
328
+ const wasStartupMode = startupMode;
329
+ startupMode = false;
330
+ if (wasStartupMode) {
331
+ startupStatePending = true;
332
+ const runtimeSeed = getStartupPacketRuntimeSeed(startupPacket);
333
+ if (startupPacket.bootstrapMode === 'warm-snapshot' &&
334
+ activeRegistrations.size === snapshotByName.size &&
335
+ confirmedSnapshotNames.size === snapshotByName.size &&
336
+ runtimeMatchesStartupSeed(runtime, runtimeSeed)) {
337
+ const dispatchStartNs = currentTimeNs();
338
+ _send(worker, { type: 'warm-reset' });
339
+ _send(worker, { type: 'compute' });
340
+ startupDispatchCompletedNs = currentTimeNs();
341
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:dispatch-send', startupDispatchCompletedNs - dispatchStartNs);
342
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:packet-finalize', 0);
343
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:post-send-bookkeeping', 0);
344
+ return;
345
+ }
346
+ else {
347
+ const packetFinalizeStartNs = currentTimeNs();
348
+ const packet = buildStartupComputePacket(startupPacket);
349
+ if (startupPacket.bootstrapMode === 'rebuild') {
350
+ if (!runtimeMatchesStartupSeed(runtime, runtimeSeed)) {
351
+ runtime.reset(runtimeSeed);
352
+ }
353
+ }
354
+ const packetFinalizeEndNs = currentTimeNs();
355
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:packet-finalize', packetFinalizeEndNs - packetFinalizeStartNs);
356
+ flushScheduled = false;
357
+ const { registrations: transferRegs, buffers } = consumePreparedRegistrations(packet.registrations);
358
+ const transferPacket = { ...packet, registrations: transferRegs };
359
+ const dispatchStartNs = currentTimeNs();
360
+ _send(worker, {
361
+ type: 'startup-compute',
362
+ packet: transferPacket,
363
+ }, buffers);
364
+ startupDispatchCompletedNs = currentTimeNs();
365
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:dispatch-send', startupDispatchCompletedNs - dispatchStartNs);
366
+ recordStartupDiagnosticStage(startupTelemetry, 'request-compute:post-send-bookkeeping', 0);
367
+ return;
368
+ }
369
+ }
370
+ flushPendingUpdates();
371
+ _send(worker, { type: 'compute' });
372
+ },
373
+ onState(callback) {
374
+ stateListeners.add(callback);
375
+ return () => {
376
+ stateListeners.delete(callback);
377
+ };
378
+ },
379
+ onResolvedStateAck(callback) {
380
+ resolvedStateAckListeners.add(callback);
381
+ return () => {
382
+ resolvedStateAckListeners.delete(callback);
383
+ };
384
+ },
385
+ onMetrics(callback) {
386
+ metricsListeners.add(callback);
387
+ return () => {
388
+ metricsListeners.delete(callback);
389
+ };
390
+ },
391
+ dispose() {
392
+ resetStartupPacketTransientState(startupPacket);
393
+ steadyStatePendingUpdates = [];
394
+ flushScheduled = false;
395
+ stateListeners.clear();
396
+ resolvedStateAckListeners.clear();
397
+ metricsListeners.clear();
398
+ preparedRegistrationCache.clear();
399
+ lastMetrics = null;
400
+ lastWorkerError = null;
401
+ if (typeof worker.removeEventListener === 'function') {
402
+ worker.removeEventListener('message', handleMessage);
403
+ worker.removeEventListener('error', handleError);
404
+ }
405
+ parkOrDisposeCompositorLease({
406
+ worker,
407
+ runtime,
408
+ capacity,
409
+ bootstrapSnapshot: Array.from(activeRegistrations.values()),
410
+ });
411
+ },
412
+ };
413
+ }
414
+ // ---------------------------------------------------------------------------
415
+ // Export
416
+ // ---------------------------------------------------------------------------
417
+ /**
418
+ * Factory namespace for the compositor worker.
419
+ *
420
+ * Call {@link CompositorWorker.create} on the main thread to spin up a
421
+ * worker that evaluates quantizer boundaries and emits
422
+ * {@link CompositorWorkerState} snapshots. The returned
423
+ * {@link CompositorWorkerShape} owns the underlying `Worker` -- call
424
+ * `dispose()` (or park via the lease pool) when finished.
425
+ *
426
+ * @example
427
+ * ```ts
428
+ * import { CompositorWorker } from '@czap/worker';
429
+ *
430
+ * const compositor = CompositorWorker.create({ poolCapacity: 64 });
431
+ * compositor.addQuantizer('brightness', {
432
+ * id: 'boundary:brightness',
433
+ * states: ['dim', 'bright'],
434
+ * thresholds: [0.5],
435
+ * });
436
+ * const unsub = compositor.onState((state) => {
437
+ * // state.discrete.brightness === 'bright' | 'dim'
438
+ * });
439
+ * compositor.evaluate('brightness', 0.7);
440
+ * compositor.requestCompute();
441
+ * // ...later:
442
+ * unsub();
443
+ * compositor.dispose();
444
+ * ```
445
+ */
446
+ export const CompositorWorker = {
447
+ /**
448
+ * Spin up a new compositor worker. Returns immediately; the worker
449
+ * posts `ready` asynchronously. Optionally provide startup telemetry
450
+ * to capture per-stage timings.
451
+ */
452
+ create: _createCompositorWorker,
453
+ };
454
+ //# sourceMappingURL=compositor-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositor-worker.js","sourceRoot":"","sources":["../src/compositor-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Shared inline source for `evaluateThresholds` injected into worker blob scripts.
3
+ *
4
+ * Worker blob scripts cannot use ES module imports at runtime, so the
5
+ * threshold-evaluation logic must be inlined as a string. This module is the
6
+ * single source of truth for that string so both compositor-worker.ts and
7
+ * render-worker.ts stay in sync automatically.
8
+ *
9
+ * Canonical TypeScript implementation: `packages/quantizer/src/evaluate.ts`
10
+ * (`evaluate` / `Evaluate.evaluate` in `@czap/quantizer`).
11
+ *
12
+ * @module
13
+ */
14
+ /**
15
+ * Inline JavaScript source for the `evaluateThresholds` helper.
16
+ *
17
+ * This is a simplified (no-hysteresis) version of the canonical
18
+ * `Evaluate.evaluate` from `@czap/quantizer`, suitable for embedding in
19
+ * self-contained worker blob scripts.
20
+ */
21
+ export declare const EVALUATE_THRESHOLDS_SOURCE = "/**\n * Evaluate which discrete state a value falls into based on thresholds.\n * Thresholds are sorted ascending; the value maps to the state whose\n * threshold it first exceeds (or the first state if below all thresholds).\n *\n * Canonical TypeScript implementation: packages/quantizer/src/evaluate.ts\n *\n * @param {number[]} thresholds\n * @param {string[]} states\n * @param {number} value\n * @returns {string}\n */\nfunction evaluateThresholds(thresholds, states, value) {\n for (let i = thresholds.length - 1; i >= 0; i--) {\n if (value >= thresholds[i]) {\n return states[i] || states[0] || \"\";\n }\n }\n return states[0] || \"\";\n}";
22
+ //# sourceMappingURL=evaluate-inline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-inline.d.ts","sourceRoot":"","sources":["../src/evaluate-inline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,0pBAoBrC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared inline source for `evaluateThresholds` injected into worker blob scripts.
3
+ *
4
+ * Worker blob scripts cannot use ES module imports at runtime, so the
5
+ * threshold-evaluation logic must be inlined as a string. This module is the
6
+ * single source of truth for that string so both compositor-worker.ts and
7
+ * render-worker.ts stay in sync automatically.
8
+ *
9
+ * Canonical TypeScript implementation: `packages/quantizer/src/evaluate.ts`
10
+ * (`evaluate` / `Evaluate.evaluate` in `@czap/quantizer`).
11
+ *
12
+ * @module
13
+ */
14
+ /**
15
+ * Inline JavaScript source for the `evaluateThresholds` helper.
16
+ *
17
+ * This is a simplified (no-hysteresis) version of the canonical
18
+ * `Evaluate.evaluate` from `@czap/quantizer`, suitable for embedding in
19
+ * self-contained worker blob scripts.
20
+ */
21
+ export const EVALUATE_THRESHOLDS_SOURCE = `\
22
+ /**
23
+ * Evaluate which discrete state a value falls into based on thresholds.
24
+ * Thresholds are sorted ascending; the value maps to the state whose
25
+ * threshold it first exceeds (or the first state if below all thresholds).
26
+ *
27
+ * Canonical TypeScript implementation: packages/quantizer/src/evaluate.ts
28
+ *
29
+ * @param {number[]} thresholds
30
+ * @param {string[]} states
31
+ * @param {number} value
32
+ * @returns {string}
33
+ */
34
+ function evaluateThresholds(thresholds, states, value) {
35
+ for (let i = thresholds.length - 1; i >= 0; i--) {
36
+ if (value >= thresholds[i]) {
37
+ return states[i] || states[0] || "";
38
+ }
39
+ }
40
+ return states[0] || "";
41
+ }`;
42
+ //# sourceMappingURL=evaluate-inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-inline.js","sourceRoot":"","sources":["../src/evaluate-inline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;EAoBxC,CAAC"}