@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.
- package/LICENSE +21 -0
- package/README.md +19 -0
- package/dist/Satellite.d.ts +42 -0
- package/dist/Satellite.d.ts.map +1 -0
- package/dist/Satellite.js +55 -0
- package/dist/Satellite.js.map +1 -0
- package/dist/client-directives/gpu.d.ts +3 -0
- package/dist/client-directives/gpu.d.ts.map +1 -0
- package/dist/client-directives/gpu.js +5 -0
- package/dist/client-directives/gpu.js.map +1 -0
- package/dist/client-directives/llm.d.ts +3 -0
- package/dist/client-directives/llm.d.ts.map +1 -0
- package/dist/client-directives/llm.js +5 -0
- package/dist/client-directives/llm.js.map +1 -0
- package/dist/client-directives/satellite.d.ts +3 -0
- package/dist/client-directives/satellite.d.ts.map +1 -0
- package/dist/client-directives/satellite.js +5 -0
- package/dist/client-directives/satellite.js.map +1 -0
- package/dist/client-directives/stream.d.ts +3 -0
- package/dist/client-directives/stream.d.ts.map +1 -0
- package/dist/client-directives/stream.js +5 -0
- package/dist/client-directives/stream.js.map +1 -0
- package/dist/client-directives/wasm.d.ts +3 -0
- package/dist/client-directives/wasm.d.ts.map +1 -0
- package/dist/client-directives/wasm.js +6 -0
- package/dist/client-directives/wasm.js.map +1 -0
- package/dist/client-directives/worker.d.ts +3 -0
- package/dist/client-directives/worker.d.ts.map +1 -0
- package/dist/client-directives/worker.js +5 -0
- package/dist/client-directives/worker.js.map +1 -0
- package/dist/detect-upgrade.d.ts +16 -0
- package/dist/detect-upgrade.d.ts.map +1 -0
- package/dist/detect-upgrade.js +105 -0
- package/dist/detect-upgrade.js.map +1 -0
- package/dist/headers.d.ts +45 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +64 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.d.ts +76 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +240 -0
- package/dist/integration.js.map +1 -0
- package/dist/middleware.d.ts +69 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +75 -0
- package/dist/middleware.js.map +1 -0
- package/dist/quantize.d.ts +50 -0
- package/dist/quantize.d.ts.map +1 -0
- package/dist/quantize.js +122 -0
- package/dist/quantize.js.map +1 -0
- package/dist/runtime/boundary.d.ts +123 -0
- package/dist/runtime/boundary.d.ts.map +1 -0
- package/dist/runtime/boundary.js +164 -0
- package/dist/runtime/boundary.js.map +1 -0
- package/dist/runtime/globals.d.ts +32 -0
- package/dist/runtime/globals.d.ts.map +1 -0
- package/dist/runtime/globals.js +45 -0
- package/dist/runtime/globals.js.map +1 -0
- package/dist/runtime/gpu.d.ts +15 -0
- package/dist/runtime/gpu.d.ts.map +1 -0
- package/dist/runtime/gpu.js +266 -0
- package/dist/runtime/gpu.js.map +1 -0
- package/dist/runtime/index.d.ts +7 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/llm-receipt-tracker.d.ts +21 -0
- package/dist/runtime/llm-receipt-tracker.d.ts.map +1 -0
- package/dist/runtime/llm-receipt-tracker.js +60 -0
- package/dist/runtime/llm-receipt-tracker.js.map +1 -0
- package/dist/runtime/llm-render-pipeline.d.ts +89 -0
- package/dist/runtime/llm-render-pipeline.d.ts.map +1 -0
- package/dist/runtime/llm-render-pipeline.js +241 -0
- package/dist/runtime/llm-render-pipeline.js.map +1 -0
- package/dist/runtime/llm-session.d.ts +126 -0
- package/dist/runtime/llm-session.d.ts.map +1 -0
- package/dist/runtime/llm-session.js +385 -0
- package/dist/runtime/llm-session.js.map +1 -0
- package/dist/runtime/llm.d.ts +16 -0
- package/dist/runtime/llm.d.ts.map +1 -0
- package/dist/runtime/llm.js +273 -0
- package/dist/runtime/llm.js.map +1 -0
- package/dist/runtime/policy.d.ts +100 -0
- package/dist/runtime/policy.d.ts.map +1 -0
- package/dist/runtime/policy.js +147 -0
- package/dist/runtime/policy.js.map +1 -0
- package/dist/runtime/receipt-chain.d.ts +22 -0
- package/dist/runtime/receipt-chain.d.ts.map +1 -0
- package/dist/runtime/receipt-chain.js +80 -0
- package/dist/runtime/receipt-chain.js.map +1 -0
- package/dist/runtime/runtime-session.d.ts +34 -0
- package/dist/runtime/runtime-session.d.ts.map +1 -0
- package/dist/runtime/runtime-session.js +102 -0
- package/dist/runtime/runtime-session.js.map +1 -0
- package/dist/runtime/satellite.d.ts +13 -0
- package/dist/runtime/satellite.d.ts.map +1 -0
- package/dist/runtime/satellite.js +59 -0
- package/dist/runtime/satellite.js.map +1 -0
- package/dist/runtime/slots.d.ts +34 -0
- package/dist/runtime/slots.d.ts.map +1 -0
- package/dist/runtime/slots.js +108 -0
- package/dist/runtime/slots.js.map +1 -0
- package/dist/runtime/stream-session.d.ts +47 -0
- package/dist/runtime/stream-session.d.ts.map +1 -0
- package/dist/runtime/stream-session.js +82 -0
- package/dist/runtime/stream-session.js.map +1 -0
- package/dist/runtime/stream.d.ts +9 -0
- package/dist/runtime/stream.d.ts.map +1 -0
- package/dist/runtime/stream.js +308 -0
- package/dist/runtime/stream.js.map +1 -0
- package/dist/runtime/url-policy.d.ts +28 -0
- package/dist/runtime/url-policy.d.ts.map +1 -0
- package/dist/runtime/url-policy.js +87 -0
- package/dist/runtime/url-policy.js.map +1 -0
- package/dist/runtime/wasm.d.ts +20 -0
- package/dist/runtime/wasm.d.ts.map +1 -0
- package/dist/runtime/wasm.js +70 -0
- package/dist/runtime/wasm.js.map +1 -0
- package/dist/runtime/worker.d.ts +11 -0
- package/dist/runtime/worker.d.ts.map +1 -0
- package/dist/runtime/worker.js +249 -0
- package/dist/runtime/worker.js.map +1 -0
- package/package.json +106 -0
- package/src/Satellite.astro +39 -0
- package/src/Satellite.ts +84 -0
- package/src/client-directives/gpu.ts +5 -0
- package/src/client-directives/llm.ts +5 -0
- package/src/client-directives/satellite.ts +5 -0
- package/src/client-directives/stream.ts +5 -0
- package/src/client-directives/wasm.ts +6 -0
- package/src/client-directives/worker.ts +5 -0
- package/src/detect-upgrade.ts +105 -0
- package/src/headers.ts +84 -0
- package/src/index.ts +30 -0
- package/src/integration.ts +309 -0
- package/src/middleware.ts +133 -0
- package/src/quantize.ts +173 -0
- package/src/runtime/boundary.ts +263 -0
- package/src/runtime/globals.ts +57 -0
- package/src/runtime/gpu.ts +291 -0
- package/src/runtime/index.ts +12 -0
- package/src/runtime/llm-receipt-tracker.ts +88 -0
- package/src/runtime/llm-render-pipeline.ts +366 -0
- package/src/runtime/llm-session.ts +548 -0
- package/src/runtime/llm.ts +344 -0
- package/src/runtime/policy.ts +229 -0
- package/src/runtime/receipt-chain.ts +106 -0
- package/src/runtime/runtime-session.ts +139 -0
- package/src/runtime/satellite.ts +80 -0
- package/src/runtime/slots.ts +136 -0
- package/src/runtime/stream-session.ts +125 -0
- package/src/runtime/stream.ts +407 -0
- package/src/runtime/url-policy.ts +107 -0
- package/src/runtime/wasm.ts +85 -0
- package/src/runtime/worker.ts +307 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-runtime helpers for parsing serialized boundaries out of
|
|
3
|
+
* `data-czap-boundary` attributes, attaching viewport observers,
|
|
4
|
+
* evaluating boundaries live, and applying the resulting state to a
|
|
5
|
+
* satellite element.
|
|
6
|
+
*
|
|
7
|
+
* Consumed by the Astro `client:satellite` / `client:worker` directives
|
|
8
|
+
* when they hydrate a server-rendered `<div data-czap-boundary="...">`.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { Boundary } from '@czap/core';
|
|
13
|
+
/**
|
|
14
|
+
* JSON shape produced on the server by `satelliteAttrs()` and read back
|
|
15
|
+
* on the client via {@link parseBoundary}. Every field corresponds
|
|
16
|
+
* directly to a {@link Boundary.Shape} input.
|
|
17
|
+
*/
|
|
18
|
+
export interface SerializedBoundary {
|
|
19
|
+
/** Optional stable boundary id (becomes the runtime `name`). */
|
|
20
|
+
readonly id?: string;
|
|
21
|
+
/** Signal key this boundary consumes (e.g. `"viewport.width"`). */
|
|
22
|
+
readonly input: string;
|
|
23
|
+
/** Ordered ascending thresholds (`thresholds[i]` lower bound of `states[i]`). */
|
|
24
|
+
readonly thresholds: readonly number[];
|
|
25
|
+
/** Non-empty ordered state labels. */
|
|
26
|
+
readonly states: readonly [string, ...string[]];
|
|
27
|
+
/** Optional hysteresis band applied during evaluation. */
|
|
28
|
+
readonly hysteresis?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Client-side representation of a parsed boundary plus its resolved
|
|
32
|
+
* runtime name, ready to be evaluated against a live signal.
|
|
33
|
+
*/
|
|
34
|
+
export interface RuntimeBoundary {
|
|
35
|
+
/** Resolved boundary name (defaults to `"default"`). */
|
|
36
|
+
readonly name: string;
|
|
37
|
+
/** Signal key this boundary consumes. */
|
|
38
|
+
readonly input: string;
|
|
39
|
+
/** Fully-constructed `Boundary.Shape` ready for evaluation. */
|
|
40
|
+
readonly boundary: Boundary.Shape<string, readonly [string, ...string[]]>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalised boundary-state payload used for `CustomEvent` dispatch and
|
|
44
|
+
* DOM application. CSS keys are filtered to `--czap-*`; ARIA keys to
|
|
45
|
+
* `role` / `aria-*`.
|
|
46
|
+
*/
|
|
47
|
+
export interface BoundaryStateDetail {
|
|
48
|
+
/** Discrete state per quantizer name. */
|
|
49
|
+
readonly discrete: Record<string, string>;
|
|
50
|
+
/** Whitelisted `--czap-*` CSS variable map. */
|
|
51
|
+
readonly css: Record<string, string | number>;
|
|
52
|
+
/** GLSL uniform map (`u_*`). */
|
|
53
|
+
readonly glsl: Record<string, number>;
|
|
54
|
+
/** Whitelisted ARIA attribute map. */
|
|
55
|
+
readonly aria: Record<string, string>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse a JSON-serialised boundary (as produced by
|
|
59
|
+
* `satelliteAttrs()`) into a {@link RuntimeBoundary}. Returns `null`
|
|
60
|
+
* for malformed or structurally invalid payloads so callers can fall
|
|
61
|
+
* back cleanly rather than throwing mid-hydration.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseBoundary(boundaryJson: string | null): RuntimeBoundary | null;
|
|
64
|
+
/**
|
|
65
|
+
* Attach a ResizeObserver on `document.documentElement` that calls `callback`
|
|
66
|
+
* whenever the viewport resizes, but only when `input` is a viewport signal
|
|
67
|
+
* (i.e. starts with `"viewport."`) and `ResizeObserver` is available.
|
|
68
|
+
*
|
|
69
|
+
* Returns a cleanup function that disconnects the observer, or `null` when no
|
|
70
|
+
* observer was attached (non-viewport input or no ResizeObserver support).
|
|
71
|
+
*
|
|
72
|
+
* Centralises the identical `observeIfNeeded` blocks that previously lived in
|
|
73
|
+
* satellite.ts and worker.ts.
|
|
74
|
+
*/
|
|
75
|
+
export declare function attachViewportObserver(input: string, callback: () => void): (() => void) | null;
|
|
76
|
+
/**
|
|
77
|
+
* Read the current numeric value for a signal `input` (e.g.
|
|
78
|
+
* `"viewport.width"`). Returns `undefined` for unknown inputs; returns
|
|
79
|
+
* `0` in non-DOM environments so callers can treat SSR and malformed
|
|
80
|
+
* signals uniformly.
|
|
81
|
+
*/
|
|
82
|
+
export declare function readSignalValue(input: string): number | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Evaluate a {@link RuntimeBoundary} against a signal value, applying
|
|
85
|
+
* hysteresis when `previousState` is provided and the boundary has a
|
|
86
|
+
* hysteresis band.
|
|
87
|
+
*/
|
|
88
|
+
export declare function evaluateBoundary(boundary: RuntimeBoundary, value: number, previousState?: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Merge `state.*` and `state.outputs.*` fields into a single
|
|
91
|
+
* {@link BoundaryStateDetail}, filtering CSS keys to `--czap-*` and
|
|
92
|
+
* ARIA keys to `role` / `aria-*`. Used as the `detail` of the
|
|
93
|
+
* `czap:state` custom event.
|
|
94
|
+
*/
|
|
95
|
+
export declare function normalizeBoundaryState(state: {
|
|
96
|
+
readonly discrete?: Record<string, string>;
|
|
97
|
+
readonly css?: Record<string, string | number>;
|
|
98
|
+
readonly glsl?: Record<string, number>;
|
|
99
|
+
readonly aria?: Record<string, string>;
|
|
100
|
+
readonly outputs?: {
|
|
101
|
+
readonly css?: Record<string, string | number>;
|
|
102
|
+
readonly glsl?: Record<string, number>;
|
|
103
|
+
readonly aria?: Record<string, string>;
|
|
104
|
+
};
|
|
105
|
+
}): BoundaryStateDetail;
|
|
106
|
+
/**
|
|
107
|
+
* Apply a normalised state to a satellite element: sets
|
|
108
|
+
* `data-czap-state`, writes whitelisted CSS variables and ARIA
|
|
109
|
+
* attributes, and dispatches `eventName` + `czap:uniform-update`
|
|
110
|
+
* custom events for downstream listeners (GPU/WASM runtimes).
|
|
111
|
+
*/
|
|
112
|
+
export declare function applyBoundaryState(element: HTMLElement, boundary: RuntimeBoundary, state: {
|
|
113
|
+
readonly discrete?: Record<string, string>;
|
|
114
|
+
readonly css?: Record<string, string | number>;
|
|
115
|
+
readonly glsl?: Record<string, number>;
|
|
116
|
+
readonly aria?: Record<string, string>;
|
|
117
|
+
readonly outputs?: {
|
|
118
|
+
readonly css?: Record<string, string | number>;
|
|
119
|
+
readonly glsl?: Record<string, number>;
|
|
120
|
+
readonly aria?: Record<string, string>;
|
|
121
|
+
};
|
|
122
|
+
}, eventName: string): void;
|
|
123
|
+
//# sourceMappingURL=boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/runtime/boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-runtime helpers for parsing serialized boundaries out of
|
|
3
|
+
* `data-czap-boundary` attributes, attaching viewport observers,
|
|
4
|
+
* evaluating boundaries live, and applying the resulting state to a
|
|
5
|
+
* satellite element.
|
|
6
|
+
*
|
|
7
|
+
* Consumed by the Astro `client:satellite` / `client:worker` directives
|
|
8
|
+
* when they hydrate a server-rendered `<div data-czap-boundary="...">`.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { Boundary } from '@czap/core';
|
|
13
|
+
function isAllowedBoundaryCssProperty(property) {
|
|
14
|
+
return property.startsWith('--czap-');
|
|
15
|
+
}
|
|
16
|
+
// NOTE: This logic is intentionally duplicated from `isValidAriaKey` in
|
|
17
|
+
// packages/compiler/src/aria.ts. @czap/astro does not depend on @czap/compiler,
|
|
18
|
+
// so the check cannot be shared without introducing a new dependency. Keep the
|
|
19
|
+
// two implementations in sync if either changes.
|
|
20
|
+
function isAllowedBoundaryAttribute(attribute) {
|
|
21
|
+
return attribute === 'role' || attribute.startsWith('aria-');
|
|
22
|
+
}
|
|
23
|
+
function parseBoundaryPayload(boundaryJson) {
|
|
24
|
+
let parsed = null;
|
|
25
|
+
let malformed = false;
|
|
26
|
+
try {
|
|
27
|
+
parsed = JSON.parse(boundaryJson);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error instanceof SyntaxError) {
|
|
31
|
+
malformed = true;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return malformed ? null : parsed;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse a JSON-serialised boundary (as produced by
|
|
41
|
+
* `satelliteAttrs()`) into a {@link RuntimeBoundary}. Returns `null`
|
|
42
|
+
* for malformed or structurally invalid payloads so callers can fall
|
|
43
|
+
* back cleanly rather than throwing mid-hydration.
|
|
44
|
+
*/
|
|
45
|
+
export function parseBoundary(boundaryJson) {
|
|
46
|
+
if (!boundaryJson) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const parsed = parseBoundaryPayload(boundaryJson);
|
|
50
|
+
if (!parsed) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
if (typeof parsed.input !== 'string' ||
|
|
54
|
+
!Array.isArray(parsed.thresholds) ||
|
|
55
|
+
parsed.thresholds.length === 0 ||
|
|
56
|
+
!Array.isArray(parsed.states) ||
|
|
57
|
+
parsed.states.length === 0 ||
|
|
58
|
+
!parsed.thresholds.every((value) => typeof value === 'number') ||
|
|
59
|
+
!parsed.states.every((value) => typeof value === 'string')) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
const states = parsed.states;
|
|
63
|
+
const first = [parsed.thresholds[0], states[0]];
|
|
64
|
+
const rest = parsed.thresholds.slice(1).map((threshold, index) => [threshold, states[index + 1]]);
|
|
65
|
+
const at = [first, ...rest];
|
|
66
|
+
return {
|
|
67
|
+
name: parsed.id ?? 'default',
|
|
68
|
+
input: parsed.input,
|
|
69
|
+
boundary: Boundary.make({
|
|
70
|
+
input: parsed.input,
|
|
71
|
+
at,
|
|
72
|
+
...(typeof parsed.hysteresis === 'number' ? { hysteresis: parsed.hysteresis } : {}),
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Attach a ResizeObserver on `document.documentElement` that calls `callback`
|
|
78
|
+
* whenever the viewport resizes, but only when `input` is a viewport signal
|
|
79
|
+
* (i.e. starts with `"viewport."`) and `ResizeObserver` is available.
|
|
80
|
+
*
|
|
81
|
+
* Returns a cleanup function that disconnects the observer, or `null` when no
|
|
82
|
+
* observer was attached (non-viewport input or no ResizeObserver support).
|
|
83
|
+
*
|
|
84
|
+
* Centralises the identical `observeIfNeeded` blocks that previously lived in
|
|
85
|
+
* satellite.ts and worker.ts.
|
|
86
|
+
*/
|
|
87
|
+
export function attachViewportObserver(input, callback) {
|
|
88
|
+
if (!input.startsWith('viewport.') || typeof ResizeObserver === 'undefined') {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const observer = new ResizeObserver(callback);
|
|
92
|
+
observer.observe(document.documentElement);
|
|
93
|
+
return () => observer.disconnect();
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Read the current numeric value for a signal `input` (e.g.
|
|
97
|
+
* `"viewport.width"`). Returns `undefined` for unknown inputs; returns
|
|
98
|
+
* `0` in non-DOM environments so callers can treat SSR and malformed
|
|
99
|
+
* signals uniformly.
|
|
100
|
+
*/
|
|
101
|
+
export function readSignalValue(input) {
|
|
102
|
+
if (typeof window === 'undefined')
|
|
103
|
+
return 0;
|
|
104
|
+
if (!input.startsWith('viewport.')) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const axis = input.slice('viewport.'.length);
|
|
108
|
+
return axis === 'height' ? window.innerHeight : window.innerWidth;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Evaluate a {@link RuntimeBoundary} against a signal value, applying
|
|
112
|
+
* hysteresis when `previousState` is provided and the boundary has a
|
|
113
|
+
* hysteresis band.
|
|
114
|
+
*/
|
|
115
|
+
export function evaluateBoundary(boundary, value, previousState) {
|
|
116
|
+
if (previousState && boundary.boundary.hysteresis) {
|
|
117
|
+
return Boundary.evaluateWithHysteresis(boundary.boundary, value, previousState);
|
|
118
|
+
}
|
|
119
|
+
return Boundary.evaluate(boundary.boundary, value);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Merge `state.*` and `state.outputs.*` fields into a single
|
|
123
|
+
* {@link BoundaryStateDetail}, filtering CSS keys to `--czap-*` and
|
|
124
|
+
* ARIA keys to `role` / `aria-*`. Used as the `detail` of the
|
|
125
|
+
* `czap:state` custom event.
|
|
126
|
+
*/
|
|
127
|
+
export function normalizeBoundaryState(state) {
|
|
128
|
+
const css = { ...(state.outputs?.css ?? {}), ...(state.css ?? {}) };
|
|
129
|
+
const aria = { ...(state.outputs?.aria ?? {}), ...(state.aria ?? {}) };
|
|
130
|
+
return {
|
|
131
|
+
discrete: { ...(state.discrete ?? {}) },
|
|
132
|
+
css: Object.fromEntries(Object.entries(css).filter(([property]) => isAllowedBoundaryCssProperty(property))),
|
|
133
|
+
glsl: { ...(state.outputs?.glsl ?? {}), ...(state.glsl ?? {}) },
|
|
134
|
+
aria: Object.fromEntries(Object.entries(aria).filter(([attribute]) => isAllowedBoundaryAttribute(attribute))),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Apply a normalised state to a satellite element: sets
|
|
139
|
+
* `data-czap-state`, writes whitelisted CSS variables and ARIA
|
|
140
|
+
* attributes, and dispatches `eventName` + `czap:uniform-update`
|
|
141
|
+
* custom events for downstream listeners (GPU/WASM runtimes).
|
|
142
|
+
*/
|
|
143
|
+
export function applyBoundaryState(element, boundary, state, eventName) {
|
|
144
|
+
const detail = normalizeBoundaryState(state);
|
|
145
|
+
const stateName = detail.discrete[boundary.name];
|
|
146
|
+
if (stateName && element.getAttribute('data-czap-state') !== stateName) {
|
|
147
|
+
element.setAttribute('data-czap-state', stateName);
|
|
148
|
+
}
|
|
149
|
+
for (const [property, value] of Object.entries(detail.css)) {
|
|
150
|
+
element.style.setProperty(property, String(value));
|
|
151
|
+
}
|
|
152
|
+
for (const [attribute, value] of Object.entries(detail.aria)) {
|
|
153
|
+
element.setAttribute(attribute, value);
|
|
154
|
+
}
|
|
155
|
+
element.dispatchEvent(new CustomEvent(eventName, {
|
|
156
|
+
detail,
|
|
157
|
+
bubbles: true,
|
|
158
|
+
}));
|
|
159
|
+
element.dispatchEvent(new CustomEvent('czap:uniform-update', {
|
|
160
|
+
detail,
|
|
161
|
+
bubbles: true,
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../src/runtime/boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe read/write helpers for named `window` globals used as runtime
|
|
3
|
+
* handshake points between inline detect scripts and the hydrated
|
|
4
|
+
* runtime (e.g. `__CZAP_DETECT__`, `__CZAP_SLOTS__`). Works on both
|
|
5
|
+
* client and server entry paths -- returns `undefined` under SSR.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read a named `window` global, narrowed through `guard`. Returns
|
|
16
|
+
* `undefined` under SSR or when the guard rejects the runtime value.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readRuntimeGlobal<T>(name: string, guard: (v: unknown) => v is T): T | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Write a named `window` global as a non-enumerable property.
|
|
21
|
+
*
|
|
22
|
+
* `options.writable` defaults to `false` so the value is lock-down by default.
|
|
23
|
+
* `options.configurable` defaults to `true` so HMR and bootstrap re-runs can
|
|
24
|
+
* replace the global; security-critical globals (e.g. `__CZAP_RUNTIME_POLICY__`)
|
|
25
|
+
* should pass `configurable: false` to prevent post-install redefinition by
|
|
26
|
+
* any later script on the page.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeRuntimeGlobal<T>(name: string, value: T, options?: {
|
|
29
|
+
readonly writable?: boolean;
|
|
30
|
+
readonly configurable?: boolean;
|
|
31
|
+
}): T;
|
|
32
|
+
//# sourceMappingURL=globals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/runtime/globals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB;CACF;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,SAAS,CAK/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACzE,CAAC,CAaH"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe read/write helpers for named `window` globals used as runtime
|
|
3
|
+
* handshake points between inline detect scripts and the hydrated
|
|
4
|
+
* runtime (e.g. `__CZAP_DETECT__`, `__CZAP_SLOTS__`). Works on both
|
|
5
|
+
* client and server entry paths -- returns `undefined` under SSR.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
function runtimeWindow() {
|
|
10
|
+
return typeof window === 'undefined' ? null : window;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Read a named `window` global, narrowed through `guard`. Returns
|
|
14
|
+
* `undefined` under SSR or when the guard rejects the runtime value.
|
|
15
|
+
*/
|
|
16
|
+
export function readRuntimeGlobal(name, guard) {
|
|
17
|
+
const win = runtimeWindow();
|
|
18
|
+
if (!win)
|
|
19
|
+
return undefined;
|
|
20
|
+
const raw = win[name];
|
|
21
|
+
return guard(raw) ? raw : undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Write a named `window` global as a non-enumerable property.
|
|
25
|
+
*
|
|
26
|
+
* `options.writable` defaults to `false` so the value is lock-down by default.
|
|
27
|
+
* `options.configurable` defaults to `true` so HMR and bootstrap re-runs can
|
|
28
|
+
* replace the global; security-critical globals (e.g. `__CZAP_RUNTIME_POLICY__`)
|
|
29
|
+
* should pass `configurable: false` to prevent post-install redefinition by
|
|
30
|
+
* any later script on the page.
|
|
31
|
+
*/
|
|
32
|
+
export function writeRuntimeGlobal(name, value, options) {
|
|
33
|
+
const win = runtimeWindow();
|
|
34
|
+
if (!win) {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
Object.defineProperty(win, name, {
|
|
38
|
+
value,
|
|
39
|
+
configurable: options?.configurable ?? true,
|
|
40
|
+
enumerable: false,
|
|
41
|
+
writable: options?.writable ?? false,
|
|
42
|
+
});
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=globals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/runtime/globals.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,SAAS,aAAa;IACpB,OAAO,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAI,IAAY,EAAE,KAA6B;IAC9E,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,GAAG,GAAY,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,KAAQ,EACR,OAA0E;IAE1E,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE;QAC/B,KAAK;QACL,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,IAAI;QAC3C,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,KAAK;KACrC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point used by the `client:gpu` directive to wire a
|
|
3
|
+
* satellite element to a WebGL shader.
|
|
4
|
+
*
|
|
5
|
+
* Reads `data-czap-shader-type` / `data-czap-shader-src` off the
|
|
6
|
+
* element, fetches and compiles the program, then subscribes to
|
|
7
|
+
* `czap:uniform-update` events so each boundary transition updates the
|
|
8
|
+
* shader uniforms.
|
|
9
|
+
*
|
|
10
|
+
* @param load - Dynamic-import factory the directive passes in (kept
|
|
11
|
+
* async so the expensive GPU module is code-split).
|
|
12
|
+
* @param el - Satellite element carrying the shader attributes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function initGPUDirective(load: () => Promise<unknown>, el: HTMLElement): void;
|
|
15
|
+
//# sourceMappingURL=gpu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu.d.ts","sourceRoot":"","sources":["../../src/runtime/gpu.ts"],"names":[],"mappings":"AA0DA;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CA2NpF"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { Diagnostics, CANVAS_FALLBACK_WIDTH, CANVAS_FALLBACK_HEIGHT } from '@czap/core';
|
|
2
|
+
import { readRuntimeEndpointPolicy } from './policy.js';
|
|
3
|
+
import { allowRuntimeEndpointUrl } from './url-policy.js';
|
|
4
|
+
const DEFAULT_VERTEX_SHADER = `#version 300 es
|
|
5
|
+
precision mediump float;
|
|
6
|
+
in vec2 a_position;
|
|
7
|
+
out vec2 v_uv;
|
|
8
|
+
void main() {
|
|
9
|
+
v_uv = a_position * 0.5 + 0.5;
|
|
10
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
11
|
+
}`;
|
|
12
|
+
const FULLSCREEN_QUAD = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
|
|
13
|
+
function compileShader(gl, type, source) {
|
|
14
|
+
const shader = gl.createShader(type);
|
|
15
|
+
if (!shader)
|
|
16
|
+
return null;
|
|
17
|
+
gl.shaderSource(shader, source);
|
|
18
|
+
gl.compileShader(shader);
|
|
19
|
+
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
|
20
|
+
Diagnostics.warn({
|
|
21
|
+
source: 'czap/astro.gpu',
|
|
22
|
+
code: 'shader-compile-failed',
|
|
23
|
+
message: 'Shader compilation failed.',
|
|
24
|
+
detail: gl.getShaderInfoLog(shader),
|
|
25
|
+
});
|
|
26
|
+
gl.deleteShader(shader);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return shader;
|
|
30
|
+
}
|
|
31
|
+
function createProgram(gl, vertSrc, fragSrc) {
|
|
32
|
+
const vert = compileShader(gl, gl.VERTEX_SHADER, vertSrc);
|
|
33
|
+
const frag = compileShader(gl, gl.FRAGMENT_SHADER, fragSrc);
|
|
34
|
+
if (!vert || !frag)
|
|
35
|
+
return null;
|
|
36
|
+
const program = gl.createProgram();
|
|
37
|
+
if (!program)
|
|
38
|
+
return null;
|
|
39
|
+
gl.attachShader(program, vert);
|
|
40
|
+
gl.attachShader(program, frag);
|
|
41
|
+
gl.linkProgram(program);
|
|
42
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
43
|
+
Diagnostics.warn({
|
|
44
|
+
source: 'czap/astro.gpu',
|
|
45
|
+
code: 'program-link-failed',
|
|
46
|
+
message: 'Shader program linking failed.',
|
|
47
|
+
detail: gl.getProgramInfoLog(program),
|
|
48
|
+
});
|
|
49
|
+
gl.deleteProgram(program);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return program;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Entry point used by the `client:gpu` directive to wire a
|
|
56
|
+
* satellite element to a WebGL shader.
|
|
57
|
+
*
|
|
58
|
+
* Reads `data-czap-shader-type` / `data-czap-shader-src` off the
|
|
59
|
+
* element, fetches and compiles the program, then subscribes to
|
|
60
|
+
* `czap:uniform-update` events so each boundary transition updates the
|
|
61
|
+
* shader uniforms.
|
|
62
|
+
*
|
|
63
|
+
* @param load - Dynamic-import factory the directive passes in (kept
|
|
64
|
+
* async so the expensive GPU module is code-split).
|
|
65
|
+
* @param el - Satellite element carrying the shader attributes.
|
|
66
|
+
*/
|
|
67
|
+
export function initGPUDirective(load, el) {
|
|
68
|
+
const shaderType = el.getAttribute('data-czap-shader-type') ?? 'glsl';
|
|
69
|
+
const shaderSrc = allowRuntimeEndpointUrl(el.getAttribute('data-czap-shader-src'), 'gpu-shader', 'czap/astro.gpu', {
|
|
70
|
+
crossOriginRejected: 'shader-cross-origin-url-rejected',
|
|
71
|
+
malformedUrl: 'shader-malformed-url-rejected',
|
|
72
|
+
originNotAllowed: 'shader-origin-not-allowed',
|
|
73
|
+
endpointKindNotPermitted: 'shader-endpoint-kind-not-permitted',
|
|
74
|
+
}, readRuntimeEndpointPolicy());
|
|
75
|
+
const tier = document.documentElement.getAttribute('data-czap-tier') ?? 'reactive';
|
|
76
|
+
if (tier === 'static' || tier === 'styled') {
|
|
77
|
+
load();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (shaderType === 'wgsl') {
|
|
81
|
+
Diagnostics.warnOnce({
|
|
82
|
+
source: 'czap/astro.gpu',
|
|
83
|
+
code: 'wgsl-not-yet-supported',
|
|
84
|
+
message: 'WGSL shader directives are not yet wired into the Astro GPU runtime. Use WGSLCompiler directly for WGSL output.',
|
|
85
|
+
});
|
|
86
|
+
load();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let canvas;
|
|
90
|
+
if (el instanceof HTMLCanvasElement) {
|
|
91
|
+
canvas = el;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
canvas = document.createElement('canvas');
|
|
95
|
+
canvas.width = el.clientWidth || CANVAS_FALLBACK_WIDTH;
|
|
96
|
+
canvas.height = el.clientHeight || CANVAS_FALLBACK_HEIGHT;
|
|
97
|
+
canvas.style.width = '100%';
|
|
98
|
+
canvas.style.height = '100%';
|
|
99
|
+
el.appendChild(canvas);
|
|
100
|
+
}
|
|
101
|
+
const gl = canvas.getContext('webgl2');
|
|
102
|
+
if (!gl) {
|
|
103
|
+
Diagnostics.warnOnce({
|
|
104
|
+
source: 'czap/astro.gpu',
|
|
105
|
+
code: 'webgl2-unavailable',
|
|
106
|
+
message: 'WebGL2 is unavailable; falling back to CSS rendering.',
|
|
107
|
+
});
|
|
108
|
+
load();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const webgl = gl;
|
|
112
|
+
async function initShader() {
|
|
113
|
+
let fragSource;
|
|
114
|
+
if (shaderSrc && (shaderSrc.startsWith('/') || shaderSrc.startsWith('http'))) {
|
|
115
|
+
try {
|
|
116
|
+
const response = await fetch(shaderSrc);
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
Diagnostics.warn({
|
|
119
|
+
source: 'czap/astro.gpu',
|
|
120
|
+
code: 'shader-fetch-failed',
|
|
121
|
+
message: 'Failed to fetch shader source.',
|
|
122
|
+
detail: response.statusText,
|
|
123
|
+
});
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
fragSource = await response.text();
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
Diagnostics.warn({
|
|
130
|
+
source: 'czap/astro.gpu',
|
|
131
|
+
code: 'shader-fetch-threw',
|
|
132
|
+
message: 'Fetching shader source threw an error.',
|
|
133
|
+
cause: err,
|
|
134
|
+
});
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (shaderSrc) {
|
|
139
|
+
fragSource = shaderSrc;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
fragSource = `#version 300 es
|
|
143
|
+
precision mediump float;
|
|
144
|
+
in vec2 v_uv;
|
|
145
|
+
out vec4 fragColor;
|
|
146
|
+
uniform float u_state;
|
|
147
|
+
uniform float u_time;
|
|
148
|
+
void main() {
|
|
149
|
+
vec3 color = mix(vec3(0.2, 0.3, 0.8), vec3(0.8, 0.3, 0.2), u_state);
|
|
150
|
+
float bands = 4.0;
|
|
151
|
+
color = floor(color * bands) / bands;
|
|
152
|
+
fragColor = vec4(color, 1.0);
|
|
153
|
+
}`;
|
|
154
|
+
}
|
|
155
|
+
const program = createProgram(webgl, DEFAULT_VERTEX_SHADER, fragSource);
|
|
156
|
+
if (!program)
|
|
157
|
+
return;
|
|
158
|
+
webgl.useProgram(program);
|
|
159
|
+
const vao = webgl.createVertexArray();
|
|
160
|
+
webgl.bindVertexArray(vao);
|
|
161
|
+
const buffer = webgl.createBuffer();
|
|
162
|
+
webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);
|
|
163
|
+
webgl.bufferData(webgl.ARRAY_BUFFER, FULLSCREEN_QUAD, webgl.STATIC_DRAW);
|
|
164
|
+
const posLoc = webgl.getAttribLocation(program, 'a_position');
|
|
165
|
+
webgl.enableVertexAttribArray(posLoc);
|
|
166
|
+
webgl.vertexAttribPointer(posLoc, 2, webgl.FLOAT, false, 0, 0);
|
|
167
|
+
const uniforms = new Map();
|
|
168
|
+
const numUniforms = webgl.getProgramParameter(program, webgl.ACTIVE_UNIFORMS);
|
|
169
|
+
for (let i = 0; i < numUniforms; i++) {
|
|
170
|
+
const info = webgl.getActiveUniform(program, i);
|
|
171
|
+
if (info) {
|
|
172
|
+
const loc = webgl.getUniformLocation(program, info.name);
|
|
173
|
+
if (loc)
|
|
174
|
+
uniforms.set(info.name, loc);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const startTime = performance.now();
|
|
178
|
+
let animFrame = 0;
|
|
179
|
+
function render() {
|
|
180
|
+
const w = canvas.clientWidth;
|
|
181
|
+
const h = canvas.clientHeight;
|
|
182
|
+
if (canvas.width !== w || canvas.height !== h) {
|
|
183
|
+
canvas.width = w;
|
|
184
|
+
canvas.height = h;
|
|
185
|
+
webgl.viewport(0, 0, w, h);
|
|
186
|
+
}
|
|
187
|
+
const timeLoc = uniforms.get('u_time');
|
|
188
|
+
if (timeLoc) {
|
|
189
|
+
webgl.uniform1f(timeLoc, (performance.now() - startTime) / 1000);
|
|
190
|
+
}
|
|
191
|
+
const resLoc = uniforms.get('u_resolution');
|
|
192
|
+
if (resLoc) {
|
|
193
|
+
webgl.uniform2f(resLoc, w, h);
|
|
194
|
+
}
|
|
195
|
+
webgl.drawArrays(webgl.TRIANGLES, 0, 6);
|
|
196
|
+
animFrame = requestAnimationFrame(render);
|
|
197
|
+
}
|
|
198
|
+
const onElementUniformUpdate = (event) => {
|
|
199
|
+
/* v8 ignore next — `czap:uniform-update` is always dispatched via `new CustomEvent(...)`;
|
|
200
|
+
the guard narrows the generic `Event` parameter for TypeScript's typed `.detail` access. */
|
|
201
|
+
if (!(event instanceof CustomEvent))
|
|
202
|
+
return;
|
|
203
|
+
const detail = event.detail;
|
|
204
|
+
if (!detail)
|
|
205
|
+
return;
|
|
206
|
+
const boundaryJson = el.getAttribute('data-czap-boundary');
|
|
207
|
+
if (boundaryJson && detail.discrete) {
|
|
208
|
+
try {
|
|
209
|
+
const boundary = JSON.parse(boundaryJson);
|
|
210
|
+
const stateName = detail.discrete[boundary.id ?? 'default'];
|
|
211
|
+
if (stateName) {
|
|
212
|
+
const idx = boundary.states.indexOf(stateName);
|
|
213
|
+
const stateLoc = uniforms.get('u_state');
|
|
214
|
+
if (stateLoc && idx >= 0) {
|
|
215
|
+
webgl.uniform1f(stateLoc, idx / Math.max(1, boundary.states.length - 1));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
Diagnostics.warnOnce({
|
|
221
|
+
source: 'czap/astro.gpu',
|
|
222
|
+
code: 'uniform-update-parse-failed',
|
|
223
|
+
message: 'Failed to parse boundary JSON during uniform update.',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (detail.css) {
|
|
228
|
+
for (const [key, value] of Object.entries(detail.css)) {
|
|
229
|
+
const uniformName = key.replace('--czap-', 'u_').replace(/-/g, '_');
|
|
230
|
+
const loc = uniforms.get(uniformName);
|
|
231
|
+
if (loc && typeof value === 'string') {
|
|
232
|
+
const num = parseFloat(value);
|
|
233
|
+
if (!Number.isNaN(num)) {
|
|
234
|
+
webgl.uniform1f(loc, num);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const onDocumentUniformUpdate = (event) => {
|
|
241
|
+
/* v8 ignore next — `czap:uniform-update` is always dispatched via `new CustomEvent(...)`;
|
|
242
|
+
the guard narrows the generic `Event` parameter for TypeScript's typed `.detail` access. */
|
|
243
|
+
if (!(event instanceof CustomEvent))
|
|
244
|
+
return;
|
|
245
|
+
if (event.detail?.uniform && event.detail?.value !== undefined) {
|
|
246
|
+
const loc = uniforms.get(event.detail.uniform);
|
|
247
|
+
if (loc) {
|
|
248
|
+
webgl.uniform1f(loc, event.detail.value);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
el.addEventListener('czap:uniform-update', onElementUniformUpdate);
|
|
253
|
+
document.addEventListener('czap:uniform-update', onDocumentUniformUpdate);
|
|
254
|
+
el.dispatchEvent(new CustomEvent('czap:gpu-ready', { bubbles: true }));
|
|
255
|
+
render();
|
|
256
|
+
el.addEventListener('czap:reinit', () => {
|
|
257
|
+
cancelAnimationFrame(animFrame);
|
|
258
|
+
el.removeEventListener('czap:uniform-update', onElementUniformUpdate);
|
|
259
|
+
document.removeEventListener('czap:uniform-update', onDocumentUniformUpdate);
|
|
260
|
+
webgl.deleteProgram(program);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
void initShader();
|
|
264
|
+
load();
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=gpu.js.map
|