@czap/core 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/addressed-digest.d.ts +15 -0
- package/dist/addressed-digest.d.ts.map +1 -0
- package/dist/addressed-digest.js +35 -0
- package/dist/addressed-digest.js.map +1 -0
- package/dist/animation.d.ts +46 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/animation.js +70 -0
- package/dist/animation.js.map +1 -0
- package/dist/assembly.d.ts +25 -0
- package/dist/assembly.d.ts.map +1 -0
- package/dist/assembly.js +58 -0
- package/dist/assembly.js.map +1 -0
- package/dist/av-bridge.d.ts +74 -0
- package/dist/av-bridge.d.ts.map +1 -0
- package/dist/av-bridge.js +107 -0
- package/dist/av-bridge.js.map +1 -0
- package/dist/av-renderer.d.ts +56 -0
- package/dist/av-renderer.d.ts.map +1 -0
- package/dist/av-renderer.js +65 -0
- package/dist/av-renderer.js.map +1 -0
- package/dist/blend.d.ts +61 -0
- package/dist/blend.d.ts.map +1 -0
- package/dist/blend.js +100 -0
- package/dist/blend.js.map +1 -0
- package/dist/boundary.d.ts +154 -0
- package/dist/boundary.d.ts.map +1 -0
- package/dist/boundary.js +269 -0
- package/dist/boundary.js.map +1 -0
- package/dist/brands.d.ts +63 -0
- package/dist/brands.d.ts.map +1 -0
- package/dist/brands.js +31 -0
- package/dist/brands.js.map +1 -0
- package/dist/caps.d.ts +49 -0
- package/dist/caps.d.ts.map +1 -0
- package/dist/caps.js +73 -0
- package/dist/caps.js.map +1 -0
- package/dist/capsule.d.ts +77 -0
- package/dist/capsule.d.ts.map +1 -0
- package/dist/capsule.js +18 -0
- package/dist/capsule.js.map +1 -0
- package/dist/capsules/boundary-evaluate.d.ts +28 -0
- package/dist/capsules/boundary-evaluate.d.ts.map +1 -0
- package/dist/capsules/boundary-evaluate.js +117 -0
- package/dist/capsules/boundary-evaluate.js.map +1 -0
- package/dist/capsules/canonical-cbor.d.ts +13 -0
- package/dist/capsules/canonical-cbor.d.ts.map +1 -0
- package/dist/capsules/canonical-cbor.js +60 -0
- package/dist/capsules/canonical-cbor.js.map +1 -0
- package/dist/capsules/token-buffer.d.ts +24 -0
- package/dist/capsules/token-buffer.d.ts.map +1 -0
- package/dist/capsules/token-buffer.js +53 -0
- package/dist/capsules/token-buffer.js.map +1 -0
- package/dist/capture.d.ts +40 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +10 -0
- package/dist/capture.js.map +1 -0
- package/dist/cbor.d.ts +33 -0
- package/dist/cbor.d.ts.map +1 -0
- package/dist/cbor.js +179 -0
- package/dist/cbor.js.map +1 -0
- package/dist/cell.d.ts +53 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +83 -0
- package/dist/cell.js.map +1 -0
- package/dist/codec.d.ts +30 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +25 -0
- package/dist/codec.js.map +1 -0
- package/dist/component.d.ts +52 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +44 -0
- package/dist/component.js.map +1 -0
- package/dist/composable.d.ts +76 -0
- package/dist/composable.d.ts.map +1 -0
- package/dist/composable.js +221 -0
- package/dist/composable.js.map +1 -0
- package/dist/compositor-pool.d.ts +74 -0
- package/dist/compositor-pool.d.ts.map +1 -0
- package/dist/compositor-pool.js +119 -0
- package/dist/compositor-pool.js.map +1 -0
- package/dist/compositor.d.ts +90 -0
- package/dist/compositor.d.ts.map +1 -0
- package/dist/compositor.js +278 -0
- package/dist/compositor.js.map +1 -0
- package/dist/config.d.ts +72 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +97 -0
- package/dist/config.js.map +1 -0
- package/dist/dag.d.ts +251 -0
- package/dist/dag.d.ts.map +1 -0
- package/dist/dag.js +450 -0
- package/dist/dag.js.map +1 -0
- package/dist/defaults.d.ts +45 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +45 -0
- package/dist/defaults.js.map +1 -0
- package/dist/derived.d.ts +34 -0
- package/dist/derived.d.ts.map +1 -0
- package/dist/derived.js +101 -0
- package/dist/derived.js.map +1 -0
- package/dist/diagnostics.d.ts +77 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +122 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/dirty.d.ts +55 -0
- package/dist/dirty.d.ts.map +1 -0
- package/dist/dirty.js +80 -0
- package/dist/dirty.js.map +1 -0
- package/dist/easing.d.ts +55 -0
- package/dist/easing.d.ts.map +1 -0
- package/dist/easing.js +291 -0
- package/dist/easing.js.map +1 -0
- package/dist/ecs.d.ts +105 -0
- package/dist/ecs.d.ts.map +1 -0
- package/dist/ecs.js +245 -0
- package/dist/ecs.js.map +1 -0
- package/dist/fnv.d.ts +14 -0
- package/dist/fnv.d.ts.map +1 -0
- package/dist/fnv.js +28 -0
- package/dist/fnv.js.map +1 -0
- package/dist/frame-budget.d.ts +73 -0
- package/dist/frame-budget.d.ts.map +1 -0
- package/dist/frame-budget.js +114 -0
- package/dist/frame-budget.js.map +1 -0
- package/dist/gen-frame.d.ts +102 -0
- package/dist/gen-frame.d.ts.map +1 -0
- package/dist/gen-frame.js +121 -0
- package/dist/gen-frame.js.map +1 -0
- package/dist/harness/arbitrary-from-schema.d.ts +28 -0
- package/dist/harness/arbitrary-from-schema.d.ts.map +1 -0
- package/dist/harness/arbitrary-from-schema.js +262 -0
- package/dist/harness/arbitrary-from-schema.js.map +1 -0
- package/dist/harness/cached-projection.d.ts +19 -0
- package/dist/harness/cached-projection.d.ts.map +1 -0
- package/dist/harness/cached-projection.js +39 -0
- package/dist/harness/cached-projection.js.map +1 -0
- package/dist/harness/index.d.ts +16 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +15 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/harness/policy-gate.d.ts +18 -0
- package/dist/harness/policy-gate.d.ts.map +1 -0
- package/dist/harness/policy-gate.js +46 -0
- package/dist/harness/policy-gate.js.map +1 -0
- package/dist/harness/pure-transform.d.ts +42 -0
- package/dist/harness/pure-transform.d.ts.map +1 -0
- package/dist/harness/pure-transform.js +76 -0
- package/dist/harness/pure-transform.js.map +1 -0
- package/dist/harness/receipted-mutation.d.ts +23 -0
- package/dist/harness/receipted-mutation.d.ts.map +1 -0
- package/dist/harness/receipted-mutation.js +52 -0
- package/dist/harness/receipted-mutation.js.map +1 -0
- package/dist/harness/scene-composition.d.ts +19 -0
- package/dist/harness/scene-composition.d.ts.map +1 -0
- package/dist/harness/scene-composition.js +47 -0
- package/dist/harness/scene-composition.js.map +1 -0
- package/dist/harness/site-adapter.d.ts +18 -0
- package/dist/harness/site-adapter.d.ts.map +1 -0
- package/dist/harness/site-adapter.js +38 -0
- package/dist/harness/site-adapter.js.map +1 -0
- package/dist/harness/state-machine.d.ts +19 -0
- package/dist/harness/state-machine.d.ts.map +1 -0
- package/dist/harness/state-machine.js +44 -0
- package/dist/harness/state-machine.js.map +1 -0
- package/dist/hlc.d.ts +99 -0
- package/dist/hlc.d.ts.map +1 -0
- package/dist/hlc.js +219 -0
- package/dist/hlc.js.map +1 -0
- package/dist/index.d.ts +104 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolate.d.ts +14 -0
- package/dist/interpolate.d.ts.map +1 -0
- package/dist/interpolate.js +31 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/live-cell.d.ts +46 -0
- package/dist/live-cell.d.ts.map +1 -0
- package/dist/live-cell.js +154 -0
- package/dist/live-cell.js.map +1 -0
- package/dist/op.d.ts +58 -0
- package/dist/op.d.ts.map +1 -0
- package/dist/op.js +171 -0
- package/dist/op.js.map +1 -0
- package/dist/plan.d.ts +195 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +211 -0
- package/dist/plan.js.map +1 -0
- package/dist/protocol.d.ts +33 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +10 -0
- package/dist/protocol.js.map +1 -0
- package/dist/quantizer-types.d.ts +28 -0
- package/dist/quantizer-types.d.ts.map +1 -0
- package/dist/quantizer-types.js +9 -0
- package/dist/quantizer-types.js.map +1 -0
- package/dist/receipt.d.ts +294 -0
- package/dist/receipt.d.ts.map +1 -0
- package/dist/receipt.js +352 -0
- package/dist/receipt.js.map +1 -0
- package/dist/runtime-coordinator.d.ts +75 -0
- package/dist/runtime-coordinator.d.ts.map +1 -0
- package/dist/runtime-coordinator.js +149 -0
- package/dist/runtime-coordinator.js.map +1 -0
- package/dist/scheduler.d.ts +58 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +109 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/ship-capsule.d.ts +54 -0
- package/dist/ship-capsule.d.ts.map +1 -0
- package/dist/ship-capsule.js +142 -0
- package/dist/ship-capsule.js.map +1 -0
- package/dist/ship-manifest.d.ts +45 -0
- package/dist/ship-manifest.d.ts.map +1 -0
- package/dist/ship-manifest.js +175 -0
- package/dist/ship-manifest.js.map +1 -0
- package/dist/signal.d.ts +149 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +277 -0
- package/dist/signal.js.map +1 -0
- package/dist/speculative.d.ts +67 -0
- package/dist/speculative.d.ts.map +1 -0
- package/dist/speculative.js +139 -0
- package/dist/speculative.js.map +1 -0
- package/dist/store.d.ts +39 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +42 -0
- package/dist/store.js.map +1 -0
- package/dist/style.d.ts +119 -0
- package/dist/style.d.ts.map +1 -0
- package/dist/style.js +168 -0
- package/dist/style.js.map +1 -0
- package/dist/testing.d.ts +14 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +14 -0
- package/dist/testing.js.map +1 -0
- package/dist/theme.d.ts +78 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +109 -0
- package/dist/theme.js.map +1 -0
- package/dist/timeline.d.ts +45 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +101 -0
- package/dist/timeline.js.map +1 -0
- package/dist/token-buffer.d.ts +43 -0
- package/dist/token-buffer.d.ts.map +1 -0
- package/dist/token-buffer.js +112 -0
- package/dist/token-buffer.js.map +1 -0
- package/dist/token.d.ts +107 -0
- package/dist/token.d.ts.map +1 -0
- package/dist/token.js +143 -0
- package/dist/token.js.map +1 -0
- package/dist/tuple.d.ts +16 -0
- package/dist/tuple.d.ts.map +1 -0
- package/dist/tuple.js +16 -0
- package/dist/tuple.js.map +1 -0
- package/dist/type-utils.d.ts +41 -0
- package/dist/type-utils.d.ts.map +1 -0
- package/dist/type-utils.js +10 -0
- package/dist/type-utils.js.map +1 -0
- package/dist/typed-ref.d.ts +50 -0
- package/dist/typed-ref.d.ts.map +1 -0
- package/dist/typed-ref.js +59 -0
- package/dist/typed-ref.js.map +1 -0
- package/dist/ui-quality.d.ts +50 -0
- package/dist/ui-quality.d.ts.map +1 -0
- package/dist/ui-quality.js +64 -0
- package/dist/ui-quality.js.map +1 -0
- package/dist/validation-error.d.ts +25 -0
- package/dist/validation-error.d.ts.map +1 -0
- package/dist/validation-error.js +32 -0
- package/dist/validation-error.js.map +1 -0
- package/dist/vector-clock.d.ts +46 -0
- package/dist/vector-clock.d.ts.map +1 -0
- package/dist/vector-clock.js +91 -0
- package/dist/vector-clock.js.map +1 -0
- package/dist/video.d.ts +62 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +59 -0
- package/dist/video.js.map +1 -0
- package/dist/wasm-dispatch.d.ts +52 -0
- package/dist/wasm-dispatch.d.ts.map +1 -0
- package/dist/wasm-dispatch.js +204 -0
- package/dist/wasm-dispatch.js.map +1 -0
- package/dist/wasm-fallback.d.ts +19 -0
- package/dist/wasm-fallback.d.ts.map +1 -0
- package/dist/wasm-fallback.js +93 -0
- package/dist/wasm-fallback.js.map +1 -0
- package/dist/wire.d.ts +49 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +201 -0
- package/dist/wire.js.map +1 -0
- package/dist/zap.d.ts +42 -0
- package/dist/zap.d.ts.map +1 -0
- package/dist/zap.js +172 -0
- package/dist/zap.js.map +1 -0
- package/package.json +71 -0
- package/src/addressed-digest.ts +48 -0
- package/src/animation.ts +103 -0
- package/src/assembly.ts +76 -0
- package/src/av-bridge.ts +161 -0
- package/src/av-renderer.ts +118 -0
- package/src/blend.ts +135 -0
- package/src/boundary.ts +363 -0
- package/src/brands.ts +86 -0
- package/src/caps.ts +100 -0
- package/src/capsule.ts +95 -0
- package/src/capsules/boundary-evaluate.ts +128 -0
- package/src/capsules/canonical-cbor.ts +60 -0
- package/src/capsules/token-buffer.ts +57 -0
- package/src/capture.ts +48 -0
- package/src/cbor.ts +199 -0
- package/src/cell.ts +130 -0
- package/src/codec.ts +39 -0
- package/src/component.ts +102 -0
- package/src/composable.ts +328 -0
- package/src/compositor-pool.ts +162 -0
- package/src/compositor.ts +387 -0
- package/src/config.ts +157 -0
- package/src/dag.ts +527 -0
- package/src/defaults.ts +60 -0
- package/src/derived.ts +164 -0
- package/src/diagnostics.ts +186 -0
- package/src/dirty.ts +101 -0
- package/src/easing.ts +334 -0
- package/src/ecs.ts +382 -0
- package/src/fnv.ts +31 -0
- package/src/frame-budget.ts +149 -0
- package/src/gen-frame.ts +229 -0
- package/src/harness/arbitrary-from-schema.ts +270 -0
- package/src/harness/cached-projection.ts +46 -0
- package/src/harness/index.ts +16 -0
- package/src/harness/policy-gate.ts +51 -0
- package/src/harness/pure-transform.ts +121 -0
- package/src/harness/receipted-mutation.ts +59 -0
- package/src/harness/scene-composition.ts +54 -0
- package/src/harness/site-adapter.ts +43 -0
- package/src/harness/state-machine.ts +49 -0
- package/src/hlc.ts +238 -0
- package/src/index.ts +274 -0
- package/src/interpolate.ts +37 -0
- package/src/live-cell.ts +199 -0
- package/src/op.ts +233 -0
- package/src/plan.ts +317 -0
- package/src/protocol.ts +49 -0
- package/src/quantizer-types.ts +29 -0
- package/src/receipt.ts +444 -0
- package/src/runtime-coordinator.ts +230 -0
- package/src/scheduler.ts +161 -0
- package/src/ship-capsule.ts +191 -0
- package/src/signal.ts +345 -0
- package/src/speculative.ts +186 -0
- package/src/store.ts +77 -0
- package/src/style.ts +249 -0
- package/src/testing.ts +14 -0
- package/src/theme.ts +153 -0
- package/src/timeline.ts +146 -0
- package/src/token-buffer.ts +151 -0
- package/src/token.ts +197 -0
- package/src/tuple.ts +19 -0
- package/src/type-utils.ts +48 -0
- package/src/typed-ref.ts +79 -0
- package/src/ui-quality.ts +105 -0
- package/src/validation-error.ts +34 -0
- package/src/vector-clock.ts +111 -0
- package/src/video.ts +106 -0
- package/src/wasm-dispatch.ts +300 -0
- package/src/wasm-fallback.ts +102 -0
- package/src/wire.ts +274 -0
- package/src/zap.ts +241 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline -- quantizer over time with play/pause/seek/scrub/reverse.
|
|
3
|
+
*
|
|
4
|
+
* A Timeline wraps a BoundaryDef and drives it from a time-based signal,
|
|
5
|
+
* producing discrete state transitions as the elapsed time crosses thresholds.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { Stream, Scope } from 'effect';
|
|
10
|
+
import { Effect } from 'effect';
|
|
11
|
+
import type { Millis } from './brands.js';
|
|
12
|
+
import { Boundary } from './boundary.js';
|
|
13
|
+
import type { StateUnion } from './type-utils.js';
|
|
14
|
+
import type { Scheduler } from './scheduler.js';
|
|
15
|
+
interface TimelineShape<B extends Boundary.Shape = Boundary.Shape> {
|
|
16
|
+
readonly boundary: B;
|
|
17
|
+
readonly state: Effect.Effect<StateUnion<B>>;
|
|
18
|
+
readonly progress: Effect.Effect<number>;
|
|
19
|
+
readonly elapsed: Effect.Effect<Millis>;
|
|
20
|
+
readonly changes: Stream.Stream<StateUnion<B>>;
|
|
21
|
+
play(): Effect.Effect<void>;
|
|
22
|
+
pause(): Effect.Effect<void>;
|
|
23
|
+
reverse(): Effect.Effect<void>;
|
|
24
|
+
seek(ms: Millis): Effect.Effect<void>;
|
|
25
|
+
scrub(progress: number): Effect.Effect<void>;
|
|
26
|
+
}
|
|
27
|
+
interface TimelineFactory {
|
|
28
|
+
from<B extends Boundary.Shape>(boundary: B, config?: {
|
|
29
|
+
duration?: Millis;
|
|
30
|
+
loop?: boolean;
|
|
31
|
+
scheduler?: Scheduler.Shape;
|
|
32
|
+
}): Effect.Effect<TimelineShape<B>, never, Scope.Scope>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Timeline — scheduler-driven advancement over a {@link Boundary}.
|
|
36
|
+
* Produces a scoped reactive timeline that seeks or plays between boundary
|
|
37
|
+
* states; pluggable clock via {@link Scheduler}.
|
|
38
|
+
*/
|
|
39
|
+
export declare const Timeline: TimelineFactory;
|
|
40
|
+
export declare namespace Timeline {
|
|
41
|
+
/** Structural shape of a timeline instance for a given {@link Boundary}. */
|
|
42
|
+
type Shape<B extends Boundary.Shape = Boundary.Shape> = TimelineShape<B>;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAwB,MAAM,QAAQ,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,UAAU,aAAa,CAAC,CAAC,SAAS,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK;IAC/D,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED,UAAU,eAAe;IACvB,IAAI,CAAC,CAAC,SAAS,QAAQ,CAAC,KAAK,EAC3B,QAAQ,EAAE,CAAC,EACX,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAC,KAAK,CAAA;KAAE,GAC1E,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,eAiGtB,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,4EAA4E;IAC5E,KAAY,KAAK,CAAC,CAAC,SAAS,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC;CACjF"}
|
package/dist/timeline.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline -- quantizer over time with play/pause/seek/scrub/reverse.
|
|
3
|
+
*
|
|
4
|
+
* A Timeline wraps a BoundaryDef and drives it from a time-based signal,
|
|
5
|
+
* producing discrete state transitions as the elapsed time crosses thresholds.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { Effect, SubscriptionRef, Ref } from 'effect';
|
|
10
|
+
import { Millis as mkMillis } from './brands.js';
|
|
11
|
+
import { Boundary } from './boundary.js';
|
|
12
|
+
import { Scheduler as SchedulerImpl } from './scheduler.js';
|
|
13
|
+
/**
|
|
14
|
+
* Timeline — scheduler-driven advancement over a {@link Boundary}.
|
|
15
|
+
* Produces a scoped reactive timeline that seeks or plays between boundary
|
|
16
|
+
* states; pluggable clock via {@link Scheduler}.
|
|
17
|
+
*/
|
|
18
|
+
export const Timeline = {
|
|
19
|
+
from(boundary, config) {
|
|
20
|
+
const duration = config?.duration ??
|
|
21
|
+
(boundary.thresholds.length > 0 ? boundary.thresholds[boundary.thresholds.length - 1] * 1.2 : 1000);
|
|
22
|
+
const loop = config?.loop ?? false;
|
|
23
|
+
return Effect.gen(function* () {
|
|
24
|
+
const elapsedRef = yield* SubscriptionRef.make(0);
|
|
25
|
+
const playingRef = yield* Ref.make(false);
|
|
26
|
+
const directionRef = yield* Ref.make(1);
|
|
27
|
+
const initialState = Boundary.evaluate(boundary, 0);
|
|
28
|
+
const stateRef = yield* SubscriptionRef.make(initialState);
|
|
29
|
+
const sched = config?.scheduler ??
|
|
30
|
+
(typeof requestAnimationFrame !== 'undefined' ? SchedulerImpl.raf() : SchedulerImpl.noop());
|
|
31
|
+
let lastTime = null;
|
|
32
|
+
let playing = false;
|
|
33
|
+
let direction = 1;
|
|
34
|
+
let currentElapsed = 0;
|
|
35
|
+
const step = (now) => {
|
|
36
|
+
if (lastTime !== null && playing) {
|
|
37
|
+
const dt = (now - lastTime) * direction;
|
|
38
|
+
let next = currentElapsed + dt;
|
|
39
|
+
if (loop) {
|
|
40
|
+
next = ((next % duration) + duration) % duration;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
next = Math.max(0, Math.min(duration, next));
|
|
44
|
+
}
|
|
45
|
+
currentElapsed = next;
|
|
46
|
+
Effect.runSync(SubscriptionRef.set(elapsedRef, next));
|
|
47
|
+
const newState = Boundary.evaluate(boundary, next);
|
|
48
|
+
const oldState = Effect.runSync(SubscriptionRef.get(stateRef));
|
|
49
|
+
if (newState !== oldState) {
|
|
50
|
+
Effect.runSync(SubscriptionRef.set(stateRef, newState));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
lastTime = now;
|
|
54
|
+
schedId = sched.schedule(step);
|
|
55
|
+
};
|
|
56
|
+
let schedId = sched.schedule(step);
|
|
57
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => sched.cancel(schedId)));
|
|
58
|
+
const timeline = {
|
|
59
|
+
boundary,
|
|
60
|
+
state: SubscriptionRef.get(stateRef),
|
|
61
|
+
progress: Effect.map(SubscriptionRef.get(elapsedRef), (e) => Math.max(0, Math.min(e / duration, 1))),
|
|
62
|
+
elapsed: Effect.map(SubscriptionRef.get(elapsedRef), (e) => mkMillis(e)),
|
|
63
|
+
changes: SubscriptionRef.changes(stateRef),
|
|
64
|
+
play: () => Effect.gen(function* () {
|
|
65
|
+
playing = true;
|
|
66
|
+
yield* Ref.set(playingRef, true);
|
|
67
|
+
}),
|
|
68
|
+
pause: () => Effect.gen(function* () {
|
|
69
|
+
playing = false;
|
|
70
|
+
yield* Ref.set(playingRef, false);
|
|
71
|
+
}),
|
|
72
|
+
reverse: () => Effect.gen(function* () {
|
|
73
|
+
direction = direction === 1 ? -1 : 1;
|
|
74
|
+
yield* Ref.update(directionRef, (d) => (d === 1 ? -1 : 1));
|
|
75
|
+
}),
|
|
76
|
+
seek: (ms) => Effect.gen(function* () {
|
|
77
|
+
const clamped = Math.max(0, Math.min(duration, ms));
|
|
78
|
+
currentElapsed = clamped;
|
|
79
|
+
yield* SubscriptionRef.set(elapsedRef, clamped);
|
|
80
|
+
const newState = Boundary.evaluate(boundary, clamped);
|
|
81
|
+
const oldState = yield* SubscriptionRef.get(stateRef);
|
|
82
|
+
if (newState !== oldState) {
|
|
83
|
+
yield* SubscriptionRef.set(stateRef, newState);
|
|
84
|
+
}
|
|
85
|
+
}),
|
|
86
|
+
scrub: (progress) => Effect.gen(function* () {
|
|
87
|
+
const val = Math.max(0, Math.min(1, progress)) * duration;
|
|
88
|
+
currentElapsed = val;
|
|
89
|
+
yield* SubscriptionRef.set(elapsedRef, val);
|
|
90
|
+
const newState = Boundary.evaluate(boundary, val);
|
|
91
|
+
const oldState = yield* SubscriptionRef.get(stateRef);
|
|
92
|
+
if (newState !== oldState) {
|
|
93
|
+
yield* SubscriptionRef.set(stateRef, newState);
|
|
94
|
+
}
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
return timeline;
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenBuffer -- ring buffer that absorbs bursty LLM token arrival
|
|
3
|
+
* and emits at smooth cadence.
|
|
4
|
+
*
|
|
5
|
+
* Backed by pre-allocated array (zero-alloc push/drain).
|
|
6
|
+
* EMA (exponential moving average) for rate estimation.
|
|
7
|
+
* Stall detection: buffer empty + `gen < consume`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
interface TokenBufferShape<T = string> {
|
|
12
|
+
push(token: T): void;
|
|
13
|
+
drain(maxCount?: number): T[];
|
|
14
|
+
reset(): void;
|
|
15
|
+
readonly occupancy: number;
|
|
16
|
+
readonly generationRate: number;
|
|
17
|
+
readonly consumptionRate: number;
|
|
18
|
+
readonly isStalled: boolean;
|
|
19
|
+
readonly length: number;
|
|
20
|
+
readonly capacity: number;
|
|
21
|
+
}
|
|
22
|
+
interface TokenBufferConfig {
|
|
23
|
+
readonly capacity?: number;
|
|
24
|
+
readonly emaAlpha?: number;
|
|
25
|
+
}
|
|
26
|
+
declare function _make<T = string>(config?: TokenBufferConfig): TokenBufferShape<T>;
|
|
27
|
+
/**
|
|
28
|
+
* TokenBuffer — zero-alloc ring buffer that absorbs bursty LLM token arrival
|
|
29
|
+
* and hands tokens out at a smooth cadence. Reports stall via `isStalled`
|
|
30
|
+
* and rate via an internal EMA.
|
|
31
|
+
*/
|
|
32
|
+
export declare const TokenBuffer: {
|
|
33
|
+
/** Build a new buffer — pass capacity or reuse defaults. */
|
|
34
|
+
make: typeof _make;
|
|
35
|
+
};
|
|
36
|
+
export declare namespace TokenBuffer {
|
|
37
|
+
/** Structural shape of a token buffer: `push`, `drain`, `reset`, stall/rate accessors. */
|
|
38
|
+
type Shape<T = string> = TokenBufferShape<T>;
|
|
39
|
+
/** Configuration accepted by {@link TokenBuffer.make}. */
|
|
40
|
+
type Config = TokenBufferConfig;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=token-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-buffer.d.ts","sourceRoot":"","sources":["../src/token-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,UAAU,gBAAgB,CAAC,CAAC,GAAG,MAAM;IACnC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;IACd,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,UAAU,iBAAiB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,iBAAS,KAAK,CAAC,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAyG1E;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW;IACtB,4DAA4D;;CAE7D,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,0FAA0F;IAC1F,KAAY,KAAK,CAAC,CAAC,GAAG,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACpD,0DAA0D;IAC1D,KAAY,MAAM,GAAG,iBAAiB,CAAC;CACxC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenBuffer -- ring buffer that absorbs bursty LLM token arrival
|
|
3
|
+
* and emits at smooth cadence.
|
|
4
|
+
*
|
|
5
|
+
* Backed by pre-allocated array (zero-alloc push/drain).
|
|
6
|
+
* EMA (exponential moving average) for rate estimation.
|
|
7
|
+
* Stall detection: buffer empty + `gen < consume`.
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
function _make(config) {
|
|
12
|
+
const capacity = config?.capacity ?? 256;
|
|
13
|
+
const alpha = config?.emaAlpha ?? 0.1;
|
|
14
|
+
// Ring buffer backing store
|
|
15
|
+
const buffer = new Array(capacity);
|
|
16
|
+
let head = 0; // next write position
|
|
17
|
+
let tail = 0; // next read position
|
|
18
|
+
let count = 0;
|
|
19
|
+
// Rate estimation
|
|
20
|
+
let genRate = 0; // tokens/sec EMA
|
|
21
|
+
let consumeRate = 0;
|
|
22
|
+
let lastPushTime = 0;
|
|
23
|
+
let lastDrainTime = 0;
|
|
24
|
+
function now() {
|
|
25
|
+
return typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
push(token) {
|
|
29
|
+
const t = now();
|
|
30
|
+
if (lastPushTime > 0) {
|
|
31
|
+
const dt = (t - lastPushTime) / 1000;
|
|
32
|
+
if (dt > 0) {
|
|
33
|
+
const instantRate = 1 / dt;
|
|
34
|
+
genRate = genRate === 0 ? instantRate : genRate * (1 - alpha) + instantRate * alpha;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
lastPushTime = t;
|
|
38
|
+
if (count < capacity) {
|
|
39
|
+
buffer[head] = token;
|
|
40
|
+
head = (head + 1) % capacity;
|
|
41
|
+
count++;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Overflow: overwrite oldest (drop tail)
|
|
45
|
+
buffer[head] = token;
|
|
46
|
+
head = (head + 1) % capacity;
|
|
47
|
+
tail = (tail + 1) % capacity;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
drain(maxCount) {
|
|
51
|
+
const max = maxCount ?? count;
|
|
52
|
+
const drainSize = Math.min(max, count);
|
|
53
|
+
if (drainSize === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const t = now();
|
|
56
|
+
if (lastDrainTime > 0) {
|
|
57
|
+
const dt = (t - lastDrainTime) / 1000;
|
|
58
|
+
if (dt > 0) {
|
|
59
|
+
const instantRate = drainSize / dt;
|
|
60
|
+
consumeRate = consumeRate === 0 ? instantRate : consumeRate * (1 - alpha) + instantRate * alpha;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
lastDrainTime = t;
|
|
64
|
+
const result = [];
|
|
65
|
+
for (let i = 0; i < drainSize; i++) {
|
|
66
|
+
result.push(buffer[tail]);
|
|
67
|
+
buffer[tail] = undefined;
|
|
68
|
+
tail = (tail + 1) % capacity;
|
|
69
|
+
count--;
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
},
|
|
73
|
+
reset() {
|
|
74
|
+
head = 0;
|
|
75
|
+
tail = 0;
|
|
76
|
+
count = 0;
|
|
77
|
+
genRate = 0;
|
|
78
|
+
consumeRate = 0;
|
|
79
|
+
lastPushTime = 0;
|
|
80
|
+
lastDrainTime = 0;
|
|
81
|
+
buffer.fill(undefined);
|
|
82
|
+
},
|
|
83
|
+
get occupancy() {
|
|
84
|
+
return count / capacity;
|
|
85
|
+
},
|
|
86
|
+
get generationRate() {
|
|
87
|
+
return genRate;
|
|
88
|
+
},
|
|
89
|
+
get consumptionRate() {
|
|
90
|
+
return consumeRate;
|
|
91
|
+
},
|
|
92
|
+
get isStalled() {
|
|
93
|
+
return count === 0 && genRate > 0 && genRate < consumeRate;
|
|
94
|
+
},
|
|
95
|
+
get length() {
|
|
96
|
+
return count;
|
|
97
|
+
},
|
|
98
|
+
get capacity() {
|
|
99
|
+
return capacity;
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* TokenBuffer — zero-alloc ring buffer that absorbs bursty LLM token arrival
|
|
105
|
+
* and hands tokens out at a smooth cadence. Reports stall via `isStalled`
|
|
106
|
+
* and rate via an internal EMA.
|
|
107
|
+
*/
|
|
108
|
+
export const TokenBuffer = {
|
|
109
|
+
/** Build a new buffer — pass capacity or reuse defaults. */
|
|
110
|
+
make: _make,
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=token-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-buffer.js","sourceRoot":"","sources":["../src/token-buffer.ts"],"names":[],"mappings":"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"}
|
package/dist/token.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenDef -- design token primitive for constraint-based adaptive rendering.
|
|
3
|
+
*
|
|
4
|
+
* A token defines a named design value that varies across axes (e.g. theme,
|
|
5
|
+
* density, contrast). Content-addressed via FNV-1a.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { ContentAddress } from './brands.js';
|
|
10
|
+
/** Design-system category of a {@link Token} — governs compilation strategy and CSS property prefix. */
|
|
11
|
+
export type TokenCategory = 'color' | 'spacing' | 'typography' | 'shadow' | 'radius' | 'animation' | 'effect';
|
|
12
|
+
interface TokenDef<N extends string = string, Axes extends readonly string[] = readonly string[]> {
|
|
13
|
+
readonly _tag: 'TokenDef';
|
|
14
|
+
readonly _version: 1;
|
|
15
|
+
readonly id: ContentAddress;
|
|
16
|
+
readonly name: N;
|
|
17
|
+
readonly category: TokenCategory;
|
|
18
|
+
readonly axes: Axes;
|
|
19
|
+
readonly values: Record<string, unknown>;
|
|
20
|
+
readonly fallback: unknown;
|
|
21
|
+
readonly cssProperty: `--${string}`;
|
|
22
|
+
}
|
|
23
|
+
interface TokenFactory {
|
|
24
|
+
make<N extends string, const A extends readonly [string, ...string[]]>(config: {
|
|
25
|
+
readonly name: N;
|
|
26
|
+
readonly category: TokenCategory;
|
|
27
|
+
readonly axes: A;
|
|
28
|
+
readonly values: Record<string, unknown>;
|
|
29
|
+
readonly fallback: unknown;
|
|
30
|
+
}): TokenDef<N, A>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolve a token's value for the given axis values. Builds a sorted lookup key.
|
|
34
|
+
*
|
|
35
|
+
* Axes are sorted alphabetically and joined with ':' to form the lookup key.
|
|
36
|
+
* Falls back to the token's fallback value if no match is found.
|
|
37
|
+
*
|
|
38
|
+
* The optional type parameter `T` lets callers narrow the return value when
|
|
39
|
+
* they know the value shape; without it, the return is `unknown` (the
|
|
40
|
+
* underlying `TokenDef.values` is `Record<string, unknown>` because token
|
|
41
|
+
* values can be any JSON shape — colors as strings, spacing as numbers,
|
|
42
|
+
* shadow records as objects). Pass `Token.tap<string>(...)` for a color
|
|
43
|
+
* token, etc.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const token = Token.make({
|
|
48
|
+
* name: 'primary', category: 'color',
|
|
49
|
+
* axes: ['theme'] as const,
|
|
50
|
+
* values: { 'light': '#000', 'dark': '#fff' },
|
|
51
|
+
* fallback: '#888',
|
|
52
|
+
* });
|
|
53
|
+
* const value = Token.tap<string>(token, { theme: 'dark' });
|
|
54
|
+
* // value === '#fff' (typed as string)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
declare function _tap<T = unknown>(token: TokenDef, axisValues: Record<string, string>): T;
|
|
58
|
+
/**
|
|
59
|
+
* Generate a CSS var() reference for a token.
|
|
60
|
+
*
|
|
61
|
+
* Returns a `var(--czap-<name>)` string suitable for use in CSS properties.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const token = Token.make({
|
|
66
|
+
* name: 'primary', category: 'color',
|
|
67
|
+
* axes: ['theme'] as const,
|
|
68
|
+
* values: { 'light': '#000' },
|
|
69
|
+
* fallback: '#888',
|
|
70
|
+
* });
|
|
71
|
+
* const ref = Token.cssVar(token);
|
|
72
|
+
* // ref === 'var(--czap-primary)'
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function _cssVar<N extends string>(token: TokenDef<N>): `var(--czap-${N})`;
|
|
76
|
+
/**
|
|
77
|
+
* Token namespace -- design token primitive for adaptive rendering.
|
|
78
|
+
*
|
|
79
|
+
* Create named design values that vary across axes (theme, density, contrast).
|
|
80
|
+
* Tokens are content-addressed and produce CSS custom property references.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { Token } from '@czap/core';
|
|
85
|
+
*
|
|
86
|
+
* const spacing = Token.make({
|
|
87
|
+
* name: 'gap', category: 'spacing',
|
|
88
|
+
* axes: ['density'] as const,
|
|
89
|
+
* values: { 'compact': '4px', 'comfortable': '8px' },
|
|
90
|
+
* fallback: '6px',
|
|
91
|
+
* });
|
|
92
|
+
* const resolved = Token.tap(spacing, { density: 'compact' });
|
|
93
|
+
* // resolved === '4px'
|
|
94
|
+
* const cssRef = Token.cssVar(spacing);
|
|
95
|
+
* // cssRef === 'var(--czap-gap)'
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare const Token: TokenFactory & {
|
|
99
|
+
tap: typeof _tap;
|
|
100
|
+
cssVar: typeof _cssVar;
|
|
101
|
+
};
|
|
102
|
+
export declare namespace Token {
|
|
103
|
+
/** Structural shape of a token definition parameterized by its name `N` and axis tuple `Axes`. */
|
|
104
|
+
type Shape<N extends string = string, Axes extends readonly string[] = readonly string[]> = TokenDef<N, Axes>;
|
|
105
|
+
}
|
|
106
|
+
export {};
|
|
107
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,wGAAwG;AACxG,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE9G,UAAU,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,IAAI,SAAS,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE;IAC9F,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;CACrC;AAED,UAAU,YAAY;IACpB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE;QAC7E,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACjB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QACjC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;KAC5B,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACpB;AAsBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,iBAAS,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAMjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,GAAG,CAEzE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,KAAK,EAAE,YAAY,GAAG;IACjC,GAAG,EAAE,OAAO,IAAI,CAAC;IACjB,MAAM,EAAE,OAAO,OAAO,CAAC;CAsDxB,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,KAAK,CAAC;IAC7B,kGAAkG;IAClG,KAAY,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,IAAI,SAAS,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,IAAI,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;CACtH"}
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenDef -- design token primitive for constraint-based adaptive rendering.
|
|
3
|
+
*
|
|
4
|
+
* A token defines a named design value that varies across axes (e.g. theme,
|
|
5
|
+
* density, contrast). Content-addressed via FNV-1a.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { CanonicalCbor } from './cbor.js';
|
|
10
|
+
import { fnv1aBytes } from './fnv.js';
|
|
11
|
+
import { CzapValidationError } from './validation-error.js';
|
|
12
|
+
function deterministicId(name, category, axes, values, fallback) {
|
|
13
|
+
return fnv1aBytes(CanonicalCbor.encode({
|
|
14
|
+
_tag: 'TokenDef',
|
|
15
|
+
_version: 1,
|
|
16
|
+
name,
|
|
17
|
+
category,
|
|
18
|
+
axes,
|
|
19
|
+
values,
|
|
20
|
+
fallback,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a token's value for the given axis values. Builds a sorted lookup key.
|
|
25
|
+
*
|
|
26
|
+
* Axes are sorted alphabetically and joined with ':' to form the lookup key.
|
|
27
|
+
* Falls back to the token's fallback value if no match is found.
|
|
28
|
+
*
|
|
29
|
+
* The optional type parameter `T` lets callers narrow the return value when
|
|
30
|
+
* they know the value shape; without it, the return is `unknown` (the
|
|
31
|
+
* underlying `TokenDef.values` is `Record<string, unknown>` because token
|
|
32
|
+
* values can be any JSON shape — colors as strings, spacing as numbers,
|
|
33
|
+
* shadow records as objects). Pass `Token.tap<string>(...)` for a color
|
|
34
|
+
* token, etc.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const token = Token.make({
|
|
39
|
+
* name: 'primary', category: 'color',
|
|
40
|
+
* axes: ['theme'] as const,
|
|
41
|
+
* values: { 'light': '#000', 'dark': '#fff' },
|
|
42
|
+
* fallback: '#888',
|
|
43
|
+
* });
|
|
44
|
+
* const value = Token.tap<string>(token, { theme: 'dark' });
|
|
45
|
+
* // value === '#fff' (typed as string)
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
function _tap(token, axisValues) {
|
|
49
|
+
const key = [...token.axes]
|
|
50
|
+
.sort()
|
|
51
|
+
.map((axis) => axisValues[axis] ?? '')
|
|
52
|
+
.join(':');
|
|
53
|
+
return (token.values[key] ?? token.fallback);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate a CSS var() reference for a token.
|
|
57
|
+
*
|
|
58
|
+
* Returns a `var(--czap-<name>)` string suitable for use in CSS properties.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const token = Token.make({
|
|
63
|
+
* name: 'primary', category: 'color',
|
|
64
|
+
* axes: ['theme'] as const,
|
|
65
|
+
* values: { 'light': '#000' },
|
|
66
|
+
* fallback: '#888',
|
|
67
|
+
* });
|
|
68
|
+
* const ref = Token.cssVar(token);
|
|
69
|
+
* // ref === 'var(--czap-primary)'
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
function _cssVar(token) {
|
|
73
|
+
return `var(--czap-${token.name})`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Token namespace -- design token primitive for adaptive rendering.
|
|
77
|
+
*
|
|
78
|
+
* Create named design values that vary across axes (theme, density, contrast).
|
|
79
|
+
* Tokens are content-addressed and produce CSS custom property references.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* import { Token } from '@czap/core';
|
|
84
|
+
*
|
|
85
|
+
* const spacing = Token.make({
|
|
86
|
+
* name: 'gap', category: 'spacing',
|
|
87
|
+
* axes: ['density'] as const,
|
|
88
|
+
* values: { 'compact': '4px', 'comfortable': '8px' },
|
|
89
|
+
* fallback: '6px',
|
|
90
|
+
* });
|
|
91
|
+
* const resolved = Token.tap(spacing, { density: 'compact' });
|
|
92
|
+
* // resolved === '4px'
|
|
93
|
+
* const cssRef = Token.cssVar(spacing);
|
|
94
|
+
* // cssRef === 'var(--czap-gap)'
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export const Token = {
|
|
98
|
+
/**
|
|
99
|
+
* Create a new TokenDef from a configuration object.
|
|
100
|
+
*
|
|
101
|
+
* The token is content-addressed via FNV-1a hash of its name, category,
|
|
102
|
+
* axes, and values. The resulting object is frozen.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* const token = Token.make({
|
|
107
|
+
* name: 'bg', category: 'color',
|
|
108
|
+
* axes: ['theme', 'contrast'] as const,
|
|
109
|
+
* values: { 'light:normal': '#fff', 'dark:normal': '#111' },
|
|
110
|
+
* fallback: '#ccc',
|
|
111
|
+
* });
|
|
112
|
+
* // token._tag === 'TokenDef'
|
|
113
|
+
* // token.cssProperty === '--czap-bg'
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
make(config) {
|
|
117
|
+
if (config.name === '') {
|
|
118
|
+
throw new CzapValidationError('Token.make', 'Token name must not be empty.');
|
|
119
|
+
}
|
|
120
|
+
const seen = new Set();
|
|
121
|
+
for (const axis of config.axes) {
|
|
122
|
+
if (seen.has(axis)) {
|
|
123
|
+
throw new CzapValidationError('Token.make', `duplicate axis "${axis}". Each axis must have a unique name.`);
|
|
124
|
+
}
|
|
125
|
+
seen.add(axis);
|
|
126
|
+
}
|
|
127
|
+
const id = deterministicId(config.name, config.category, config.axes, config.values, config.fallback);
|
|
128
|
+
return Object.freeze({
|
|
129
|
+
_tag: 'TokenDef',
|
|
130
|
+
_version: 1,
|
|
131
|
+
id,
|
|
132
|
+
name: config.name,
|
|
133
|
+
category: config.category,
|
|
134
|
+
axes: config.axes,
|
|
135
|
+
values: config.values,
|
|
136
|
+
fallback: config.fallback,
|
|
137
|
+
cssProperty: `--czap-${config.name}`,
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
tap: _tap,
|
|
141
|
+
cssVar: _cssVar,
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AA2B5D,SAAS,eAAe,CACtB,IAAY,EACZ,QAAgB,EAChB,IAAuB,EACvB,MAA+B,EAC/B,QAAiB;IAEjB,OAAO,UAAU,CACf,aAAa,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC;QACX,IAAI;QACJ,QAAQ;QACR,IAAI;QACJ,MAAM;QACN,QAAQ;KACT,CAAC,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAS,IAAI,CAAc,KAAe,EAAE,UAAkC;IAC5E,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;SACxB,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SACrC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAM,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAS,OAAO,CAAmB,KAAkB;IACnD,OAAO,cAAc,KAAK,CAAC,IAAI,GAAyB,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,KAAK,GAGd;IACF;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAmE,MAMtE;QACC,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAAC,YAAY,EAAE,+BAA+B,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,mBAAmB,CAAC,YAAY,EAAE,mBAAmB,IAAI,uCAAuC,CAAC,CAAC;YAC9G,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEtG,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,UAAmB;YACzB,QAAQ,EAAE,CAAU;YACpB,EAAE;YACF,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,WAAW,EAAE,UAAU,MAAM,CAAC,IAAI,EAAW;SAC9C,CAAC,CAAC;IACL,CAAC;IACD,GAAG,EAAE,IAAI;IACT,MAAM,EAAE,OAAO;CAChB,CAAC"}
|
package/dist/tuple.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map each element of a readonly tuple, preserving tuple arity and ordering.
|
|
3
|
+
*
|
|
4
|
+
* TypeScript's Array.prototype.map returns U[], erasing tuple structure.
|
|
5
|
+
* This helper reintroduces the mapped tuple type via one narrow cast,
|
|
6
|
+
* provably safe: the map is total over the input and the output element
|
|
7
|
+
* type is uniform.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const types = tupleMap([1, 'two', true] as const, (el) => typeof el);
|
|
12
|
+
* // types: readonly ['number', 'string', 'boolean']
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const tupleMap: <T extends readonly unknown[], U>(tuple: T, fn: (element: T[number], index: number) => U) => { readonly [K in keyof T]: U; };
|
|
16
|
+
//# sourceMappingURL=tuple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuple.d.ts","sourceRoot":"","sources":["../src/tuple.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,SAAS,OAAO,EAAE,EAAE,CAAC,EACtD,OAAO,CAAC,EACR,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,KAC3C,EAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GACkB,CAAC"}
|
package/dist/tuple.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map each element of a readonly tuple, preserving tuple arity and ordering.
|
|
3
|
+
*
|
|
4
|
+
* TypeScript's Array.prototype.map returns U[], erasing tuple structure.
|
|
5
|
+
* This helper reintroduces the mapped tuple type via one narrow cast,
|
|
6
|
+
* provably safe: the map is total over the input and the output element
|
|
7
|
+
* type is uniform.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const types = tupleMap([1, 'two', true] as const, (el) => typeof el);
|
|
12
|
+
* // types: readonly ['number', 'string', 'boolean']
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export const tupleMap = (tuple, fn) => tuple.map(fn);
|
|
16
|
+
//# sourceMappingURL=tuple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuple.js","sourceRoot":"","sources":["../src/tuple.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,KAAQ,EACR,EAA4C,EACZ,EAAE,CAClC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAmC,CAAC"}
|