@czap/astro 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 (159) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/Satellite.d.ts +42 -0
  4. package/dist/Satellite.d.ts.map +1 -0
  5. package/dist/Satellite.js +55 -0
  6. package/dist/Satellite.js.map +1 -0
  7. package/dist/client-directives/gpu.d.ts +3 -0
  8. package/dist/client-directives/gpu.d.ts.map +1 -0
  9. package/dist/client-directives/gpu.js +5 -0
  10. package/dist/client-directives/gpu.js.map +1 -0
  11. package/dist/client-directives/llm.d.ts +3 -0
  12. package/dist/client-directives/llm.d.ts.map +1 -0
  13. package/dist/client-directives/llm.js +5 -0
  14. package/dist/client-directives/llm.js.map +1 -0
  15. package/dist/client-directives/satellite.d.ts +3 -0
  16. package/dist/client-directives/satellite.d.ts.map +1 -0
  17. package/dist/client-directives/satellite.js +5 -0
  18. package/dist/client-directives/satellite.js.map +1 -0
  19. package/dist/client-directives/stream.d.ts +3 -0
  20. package/dist/client-directives/stream.d.ts.map +1 -0
  21. package/dist/client-directives/stream.js +5 -0
  22. package/dist/client-directives/stream.js.map +1 -0
  23. package/dist/client-directives/wasm.d.ts +3 -0
  24. package/dist/client-directives/wasm.d.ts.map +1 -0
  25. package/dist/client-directives/wasm.js +6 -0
  26. package/dist/client-directives/wasm.js.map +1 -0
  27. package/dist/client-directives/worker.d.ts +3 -0
  28. package/dist/client-directives/worker.d.ts.map +1 -0
  29. package/dist/client-directives/worker.js +5 -0
  30. package/dist/client-directives/worker.js.map +1 -0
  31. package/dist/detect-upgrade.d.ts +16 -0
  32. package/dist/detect-upgrade.d.ts.map +1 -0
  33. package/dist/detect-upgrade.js +105 -0
  34. package/dist/detect-upgrade.js.map +1 -0
  35. package/dist/headers.d.ts +45 -0
  36. package/dist/headers.d.ts.map +1 -0
  37. package/dist/headers.js +64 -0
  38. package/dist/headers.js.map +1 -0
  39. package/dist/index.d.ts +30 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +26 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/integration.d.ts +76 -0
  44. package/dist/integration.d.ts.map +1 -0
  45. package/dist/integration.js +240 -0
  46. package/dist/integration.js.map +1 -0
  47. package/dist/middleware.d.ts +69 -0
  48. package/dist/middleware.d.ts.map +1 -0
  49. package/dist/middleware.js +75 -0
  50. package/dist/middleware.js.map +1 -0
  51. package/dist/quantize.d.ts +50 -0
  52. package/dist/quantize.d.ts.map +1 -0
  53. package/dist/quantize.js +122 -0
  54. package/dist/quantize.js.map +1 -0
  55. package/dist/runtime/boundary.d.ts +123 -0
  56. package/dist/runtime/boundary.d.ts.map +1 -0
  57. package/dist/runtime/boundary.js +164 -0
  58. package/dist/runtime/boundary.js.map +1 -0
  59. package/dist/runtime/globals.d.ts +32 -0
  60. package/dist/runtime/globals.d.ts.map +1 -0
  61. package/dist/runtime/globals.js +45 -0
  62. package/dist/runtime/globals.js.map +1 -0
  63. package/dist/runtime/gpu.d.ts +15 -0
  64. package/dist/runtime/gpu.d.ts.map +1 -0
  65. package/dist/runtime/gpu.js +266 -0
  66. package/dist/runtime/gpu.js.map +1 -0
  67. package/dist/runtime/index.d.ts +7 -0
  68. package/dist/runtime/index.d.ts.map +1 -0
  69. package/dist/runtime/index.js +5 -0
  70. package/dist/runtime/index.js.map +1 -0
  71. package/dist/runtime/llm-receipt-tracker.d.ts +21 -0
  72. package/dist/runtime/llm-receipt-tracker.d.ts.map +1 -0
  73. package/dist/runtime/llm-receipt-tracker.js +60 -0
  74. package/dist/runtime/llm-receipt-tracker.js.map +1 -0
  75. package/dist/runtime/llm-render-pipeline.d.ts +89 -0
  76. package/dist/runtime/llm-render-pipeline.d.ts.map +1 -0
  77. package/dist/runtime/llm-render-pipeline.js +241 -0
  78. package/dist/runtime/llm-render-pipeline.js.map +1 -0
  79. package/dist/runtime/llm-session.d.ts +126 -0
  80. package/dist/runtime/llm-session.d.ts.map +1 -0
  81. package/dist/runtime/llm-session.js +385 -0
  82. package/dist/runtime/llm-session.js.map +1 -0
  83. package/dist/runtime/llm.d.ts +16 -0
  84. package/dist/runtime/llm.d.ts.map +1 -0
  85. package/dist/runtime/llm.js +273 -0
  86. package/dist/runtime/llm.js.map +1 -0
  87. package/dist/runtime/policy.d.ts +100 -0
  88. package/dist/runtime/policy.d.ts.map +1 -0
  89. package/dist/runtime/policy.js +147 -0
  90. package/dist/runtime/policy.js.map +1 -0
  91. package/dist/runtime/receipt-chain.d.ts +22 -0
  92. package/dist/runtime/receipt-chain.d.ts.map +1 -0
  93. package/dist/runtime/receipt-chain.js +80 -0
  94. package/dist/runtime/receipt-chain.js.map +1 -0
  95. package/dist/runtime/runtime-session.d.ts +34 -0
  96. package/dist/runtime/runtime-session.d.ts.map +1 -0
  97. package/dist/runtime/runtime-session.js +102 -0
  98. package/dist/runtime/runtime-session.js.map +1 -0
  99. package/dist/runtime/satellite.d.ts +13 -0
  100. package/dist/runtime/satellite.d.ts.map +1 -0
  101. package/dist/runtime/satellite.js +59 -0
  102. package/dist/runtime/satellite.js.map +1 -0
  103. package/dist/runtime/slots.d.ts +34 -0
  104. package/dist/runtime/slots.d.ts.map +1 -0
  105. package/dist/runtime/slots.js +108 -0
  106. package/dist/runtime/slots.js.map +1 -0
  107. package/dist/runtime/stream-session.d.ts +47 -0
  108. package/dist/runtime/stream-session.d.ts.map +1 -0
  109. package/dist/runtime/stream-session.js +82 -0
  110. package/dist/runtime/stream-session.js.map +1 -0
  111. package/dist/runtime/stream.d.ts +9 -0
  112. package/dist/runtime/stream.d.ts.map +1 -0
  113. package/dist/runtime/stream.js +308 -0
  114. package/dist/runtime/stream.js.map +1 -0
  115. package/dist/runtime/url-policy.d.ts +28 -0
  116. package/dist/runtime/url-policy.d.ts.map +1 -0
  117. package/dist/runtime/url-policy.js +87 -0
  118. package/dist/runtime/url-policy.js.map +1 -0
  119. package/dist/runtime/wasm.d.ts +20 -0
  120. package/dist/runtime/wasm.d.ts.map +1 -0
  121. package/dist/runtime/wasm.js +70 -0
  122. package/dist/runtime/wasm.js.map +1 -0
  123. package/dist/runtime/worker.d.ts +11 -0
  124. package/dist/runtime/worker.d.ts.map +1 -0
  125. package/dist/runtime/worker.js +249 -0
  126. package/dist/runtime/worker.js.map +1 -0
  127. package/package.json +106 -0
  128. package/src/Satellite.astro +39 -0
  129. package/src/Satellite.ts +84 -0
  130. package/src/client-directives/gpu.ts +5 -0
  131. package/src/client-directives/llm.ts +5 -0
  132. package/src/client-directives/satellite.ts +5 -0
  133. package/src/client-directives/stream.ts +5 -0
  134. package/src/client-directives/wasm.ts +6 -0
  135. package/src/client-directives/worker.ts +5 -0
  136. package/src/detect-upgrade.ts +105 -0
  137. package/src/headers.ts +84 -0
  138. package/src/index.ts +30 -0
  139. package/src/integration.ts +309 -0
  140. package/src/middleware.ts +133 -0
  141. package/src/quantize.ts +173 -0
  142. package/src/runtime/boundary.ts +263 -0
  143. package/src/runtime/globals.ts +57 -0
  144. package/src/runtime/gpu.ts +291 -0
  145. package/src/runtime/index.ts +12 -0
  146. package/src/runtime/llm-receipt-tracker.ts +88 -0
  147. package/src/runtime/llm-render-pipeline.ts +366 -0
  148. package/src/runtime/llm-session.ts +548 -0
  149. package/src/runtime/llm.ts +344 -0
  150. package/src/runtime/policy.ts +229 -0
  151. package/src/runtime/receipt-chain.ts +106 -0
  152. package/src/runtime/runtime-session.ts +139 -0
  153. package/src/runtime/satellite.ts +80 -0
  154. package/src/runtime/slots.ts +136 -0
  155. package/src/runtime/stream-session.ts +125 -0
  156. package/src/runtime/stream.ts +407 -0
  157. package/src/runtime/url-policy.ts +107 -0
  158. package/src/runtime/wasm.ts +85 -0
  159. package/src/runtime/worker.ts +307 -0
@@ -0,0 +1,307 @@
1
+ import { Diagnostics } from '@czap/core';
2
+ import { WorkerHost } from '@czap/worker';
3
+ import {
4
+ applyBoundaryState,
5
+ attachViewportObserver,
6
+ evaluateBoundary,
7
+ normalizeBoundaryState,
8
+ parseBoundary,
9
+ readSignalValue,
10
+ type BoundaryStateDetail,
11
+ } from './boundary.js';
12
+
13
+ function sameStringRecord(left: Record<string, string>, right: Record<string, string>): boolean {
14
+ const leftKeys = Object.keys(left);
15
+ const rightKeys = Object.keys(right);
16
+ if (leftKeys.length !== rightKeys.length) {
17
+ return false;
18
+ }
19
+
20
+ for (const key of leftKeys) {
21
+ if (left[key] !== right[key]) {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ return true;
27
+ }
28
+
29
+ function sameNumberRecord(left: Record<string, number>, right: Record<string, number>): boolean {
30
+ const leftKeys = Object.keys(left);
31
+ const rightKeys = Object.keys(right);
32
+ if (leftKeys.length !== rightKeys.length) {
33
+ return false;
34
+ }
35
+
36
+ for (const key of leftKeys) {
37
+ if (left[key] !== right[key]) {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ return true;
43
+ }
44
+
45
+ function sameBoundaryDetail(left: BoundaryStateDetail | null, right: BoundaryStateDetail): boolean {
46
+ if (!left) {
47
+ return false;
48
+ }
49
+
50
+ return (
51
+ sameStringRecord(left.discrete, right.discrete) &&
52
+ sameStringRecord(left.aria, right.aria) &&
53
+ sameStringRecord(
54
+ Object.fromEntries(Object.entries(left.css).map(([key, value]) => [key, String(value)])),
55
+ Object.fromEntries(Object.entries(right.css).map(([key, value]) => [key, String(value)])),
56
+ ) &&
57
+ sameNumberRecord(left.glsl, right.glsl)
58
+ );
59
+ }
60
+
61
+ function canUseWorkerRuntime(): boolean {
62
+ return typeof Worker !== 'undefined' && typeof SharedArrayBuffer !== 'undefined' && globalThis.crossOriginIsolated;
63
+ }
64
+
65
+ /**
66
+ * Entry point used by the `client:worker` directive.
67
+ *
68
+ * Parses the serialised boundary off `element`, spins up (or reuses)
69
+ * a {@link WorkerHost.Shape} from `@czap/worker`, bootstraps the
70
+ * boundary in the worker, and streams resolved state back into DOM
71
+ * via {@link applyBoundaryState}. Falls back to an inline evaluation
72
+ * when `SharedArrayBuffer` / cross-origin isolation is unavailable.
73
+ */
74
+ export function initWorkerDirective(load: () => Promise<unknown>, element: HTMLElement): void {
75
+ let runtimeBoundary = parseBoundary(element.getAttribute('data-czap-boundary'));
76
+ if (!runtimeBoundary) {
77
+ return;
78
+ }
79
+
80
+ let cleanupObserver: (() => void) | null = null;
81
+ let host: WorkerHost.Shape | null = null;
82
+ let unsubscribe: (() => void) | null = null;
83
+ let ackUnsubscribe: (() => void) | null = null;
84
+ let workerMessageHandler: ((event: MessageEvent<{ type?: string }>) => void) | null = null;
85
+ let workerRef: Worker | null = null;
86
+ let previousState = element.getAttribute('data-czap-state') ?? '';
87
+ let lastAppliedDetail: BoundaryStateDetail | null = null;
88
+ let seededGeneration = 0;
89
+ let lastAppliedGeneration = 0;
90
+ let pendingWorkerSeedAgreement = false;
91
+
92
+ const cleanup = (): void => {
93
+ cleanupObserver?.();
94
+ cleanupObserver = null;
95
+ unsubscribe?.();
96
+ unsubscribe = null;
97
+ ackUnsubscribe?.();
98
+ ackUnsubscribe = null;
99
+ if (workerMessageHandler && workerRef && typeof workerRef.removeEventListener === 'function') {
100
+ workerRef.removeEventListener('message', workerMessageHandler);
101
+ }
102
+ workerMessageHandler = null;
103
+ workerRef = null;
104
+ host?.dispose();
105
+ host = null;
106
+ };
107
+
108
+ const readValue = (): number | undefined => {
109
+ return readSignalValue(runtimeBoundary!.input);
110
+ };
111
+
112
+ const initFallback = (): void => {
113
+ const update = (reset = false): void => {
114
+ if (!runtimeBoundary) {
115
+ return;
116
+ }
117
+
118
+ const value = readValue();
119
+ if (value === undefined) {
120
+ return;
121
+ }
122
+
123
+ const nextState = reset
124
+ ? evaluateBoundary(runtimeBoundary, value)
125
+ : evaluateBoundary(runtimeBoundary, value, previousState);
126
+ if (nextState === previousState) {
127
+ return;
128
+ }
129
+
130
+ previousState = nextState;
131
+ applyBoundaryState(
132
+ element,
133
+ runtimeBoundary,
134
+ {
135
+ discrete: { [runtimeBoundary.name]: nextState },
136
+ },
137
+ 'czap:worker-state',
138
+ );
139
+ };
140
+
141
+ update(true);
142
+ if (runtimeBoundary) {
143
+ cleanupObserver = attachViewportObserver(runtimeBoundary.input, () => update(false));
144
+ }
145
+ };
146
+
147
+ const initWorkerHost = (): void => {
148
+ if (!runtimeBoundary) {
149
+ return;
150
+ }
151
+ const boundary = runtimeBoundary;
152
+ const workerHost = WorkerHost.create();
153
+ host = workerHost;
154
+
155
+ const syncResolvedState = (stateName: string, generation: number, bootstrap = false): void => {
156
+ const payload = [
157
+ {
158
+ name: boundary.name,
159
+ state: stateName,
160
+ generation,
161
+ },
162
+ ] as const;
163
+ pendingWorkerSeedAgreement = true;
164
+ seededGeneration = generation;
165
+ lastAppliedGeneration = generation;
166
+ if (bootstrap) {
167
+ workerHost.compositor.bootstrapResolvedState(payload);
168
+ return;
169
+ }
170
+
171
+ workerHost.compositor.applyResolvedState(payload);
172
+ };
173
+
174
+ const applyHostResolvedState = (stateName: string, generation: number): void => {
175
+ const payload = {
176
+ discrete: { [boundary.name]: stateName },
177
+ };
178
+ applyBoundaryState(element, boundary, payload, 'czap:worker-state');
179
+ previousState = stateName;
180
+ lastAppliedDetail = normalizeBoundaryState(payload);
181
+ lastAppliedGeneration = generation;
182
+ };
183
+
184
+ workerHost.compositor.addQuantizer(boundary.name, {
185
+ id: boundary.boundary.id,
186
+ states: boundary.boundary.states,
187
+ thresholds: boundary.boundary.thresholds,
188
+ });
189
+
190
+ const onWorkerMessage = (event: MessageEvent<{ type?: string }>): void => {
191
+ if (event.data?.type === 'ready') {
192
+ element.dispatchEvent(new CustomEvent('czap:worker-ready', { bubbles: true }));
193
+ }
194
+ };
195
+ workerMessageHandler = onWorkerMessage;
196
+ workerRef = workerHost.compositor.worker;
197
+ workerHost.compositor.worker.addEventListener('message', onWorkerMessage);
198
+
199
+ ackUnsubscribe = workerHost.compositor.onResolvedStateAck((ack) => {
200
+ if (host !== workerHost || runtimeBoundary !== boundary) {
201
+ return;
202
+ }
203
+
204
+ const ackState = ack.states.find((state) => state.name === boundary.name)?.state;
205
+ if (
206
+ pendingWorkerSeedAgreement &&
207
+ ack.additionalOutputsChanged === false &&
208
+ ack.generation === seededGeneration &&
209
+ ackState !== undefined &&
210
+ ackState === previousState
211
+ ) {
212
+ pendingWorkerSeedAgreement = false;
213
+ }
214
+ });
215
+
216
+ unsubscribe = workerHost.onState((state) => {
217
+ const currentState = state.discrete?.[boundary.name];
218
+ if (currentState) {
219
+ previousState = currentState;
220
+ }
221
+
222
+ const normalized = normalizeBoundaryState(state);
223
+ const workerGeneration = state.resolvedStateGenerations?.[boundary.name];
224
+ if (
225
+ pendingWorkerSeedAgreement &&
226
+ workerGeneration !== undefined &&
227
+ workerGeneration === seededGeneration &&
228
+ currentState === lastAppliedDetail?.discrete[boundary.name] &&
229
+ sameBoundaryDetail(lastAppliedDetail, normalized)
230
+ ) {
231
+ pendingWorkerSeedAgreement = false;
232
+ return;
233
+ }
234
+
235
+ applyBoundaryState(element, boundary, state, 'czap:worker-state');
236
+ lastAppliedDetail = normalized;
237
+ if (workerGeneration !== undefined) {
238
+ lastAppliedGeneration = workerGeneration;
239
+ pendingWorkerSeedAgreement = false;
240
+ }
241
+ });
242
+ const update = (): void => {
243
+ if (host !== workerHost || runtimeBoundary !== boundary) {
244
+ return;
245
+ }
246
+
247
+ const value = readValue();
248
+ if (value === undefined) {
249
+ return;
250
+ }
251
+
252
+ const nextState = evaluateBoundary(boundary, value, previousState || undefined);
253
+ if (nextState === previousState) {
254
+ return;
255
+ }
256
+
257
+ const nextGeneration = lastAppliedGeneration + 1;
258
+ applyHostResolvedState(nextState, nextGeneration);
259
+ syncResolvedState(nextState, nextGeneration);
260
+ };
261
+
262
+ const initialValue = readValue();
263
+ if (initialValue !== undefined) {
264
+ const initialState = evaluateBoundary(boundary, initialValue, previousState || undefined);
265
+ applyHostResolvedState(initialState, 1);
266
+ syncResolvedState(initialState, 1, true);
267
+ }
268
+ cleanupObserver = attachViewportObserver(boundary.input, update);
269
+ };
270
+
271
+ const init = (): void => {
272
+ if (canUseWorkerRuntime()) {
273
+ try {
274
+ initWorkerHost();
275
+ return;
276
+ } catch (error) {
277
+ Diagnostics.warn({
278
+ source: 'czap/astro.worker',
279
+ code: 'worker-host-fallback',
280
+ message: 'WorkerHost could not initialize, falling back to main-thread evaluation.',
281
+ detail: error instanceof Error ? error.message : String(error),
282
+ });
283
+ }
284
+ }
285
+
286
+ initFallback();
287
+ };
288
+
289
+ element.addEventListener('czap:reinit', () => {
290
+ cleanup();
291
+ runtimeBoundary = parseBoundary(element.getAttribute('data-czap-boundary'));
292
+ previousState = element.getAttribute('data-czap-state') ?? '';
293
+ lastAppliedDetail = null;
294
+ seededGeneration = 0;
295
+ lastAppliedGeneration = 0;
296
+ pendingWorkerSeedAgreement = false;
297
+ ackUnsubscribe = null;
298
+ init();
299
+ });
300
+
301
+ element.addEventListener('czap:dispose', () => {
302
+ cleanup();
303
+ });
304
+
305
+ init();
306
+ load();
307
+ }