@sebastianwessel/isostate 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 (61) hide show
  1. package/dist/animation/animation-engine.d.ts +78 -0
  2. package/dist/animation/animation-engine.d.ts.map +1 -0
  3. package/dist/animation/controller.d.ts +130 -0
  4. package/dist/animation/controller.d.ts.map +1 -0
  5. package/dist/browser/isostate.runtime.js +2449 -0
  6. package/dist/browser/isostate.runtime.js.map +1 -0
  7. package/dist/chunks/errors-DyqEkrm5.js +29 -0
  8. package/dist/chunks/errors-DyqEkrm5.js.map +1 -0
  9. package/dist/chunks/index-CDQt8CfR.js +2380 -0
  10. package/dist/chunks/index-CDQt8CfR.js.map +1 -0
  11. package/dist/dsl/compiler.d.ts +13 -0
  12. package/dist/dsl/compiler.d.ts.map +1 -0
  13. package/dist/dsl/index.d.ts +7 -0
  14. package/dist/dsl/index.d.ts.map +1 -0
  15. package/dist/dsl/index.js +2191 -0
  16. package/dist/dsl/index.js.map +1 -0
  17. package/dist/dsl/scene-parser.d.ts +6 -0
  18. package/dist/dsl/scene-parser.d.ts.map +1 -0
  19. package/dist/dsl/scene-validator.d.ts +11 -0
  20. package/dist/dsl/scene-validator.d.ts.map +1 -0
  21. package/dist/index.d.ts +12 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +49 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/rendering/animation-css.d.ts +3 -0
  26. package/dist/rendering/animation-css.d.ts.map +1 -0
  27. package/dist/rendering/asset-node.d.ts +13 -0
  28. package/dist/rendering/asset-node.d.ts.map +1 -0
  29. package/dist/rendering/rendering-engine.d.ts +77 -0
  30. package/dist/rendering/rendering-engine.d.ts.map +1 -0
  31. package/dist/rendering/theme.d.ts +2 -0
  32. package/dist/rendering/theme.d.ts.map +1 -0
  33. package/dist/runtime/index.d.ts +3 -0
  34. package/dist/runtime/index.d.ts.map +1 -0
  35. package/dist/runtime/index.js +3 -0
  36. package/dist/runtime/index.js.map +1 -0
  37. package/dist/runtime/mount-scene.d.ts +52 -0
  38. package/dist/runtime/mount-scene.d.ts.map +1 -0
  39. package/dist/types/asset-registry.d.ts +26 -0
  40. package/dist/types/asset-registry.d.ts.map +1 -0
  41. package/dist/types/assets.d.ts +37 -0
  42. package/dist/types/assets.d.ts.map +1 -0
  43. package/dist/types/errors.d.ts +23 -0
  44. package/dist/types/errors.d.ts.map +1 -0
  45. package/dist/types/index.d.ts +8 -0
  46. package/dist/types/index.d.ts.map +1 -0
  47. package/dist/types/node.d.ts +251 -0
  48. package/dist/types/node.d.ts.map +1 -0
  49. package/dist/types/runtime-bundle.d.ts +44 -0
  50. package/dist/types/runtime-bundle.d.ts.map +1 -0
  51. package/dist/types/scene.d.ts +94 -0
  52. package/dist/types/scene.d.ts.map +1 -0
  53. package/dist/types/validation.d.ts +40 -0
  54. package/dist/types/validation.d.ts.map +1 -0
  55. package/dist/utils/easing.d.ts +25 -0
  56. package/dist/utils/easing.d.ts.map +1 -0
  57. package/dist/utils/index.d.ts +3 -0
  58. package/dist/utils/index.d.ts.map +1 -0
  59. package/dist/utils/projection.d.ts +22 -0
  60. package/dist/utils/projection.d.ts.map +1 -0
  61. package/package.json +63 -0
@@ -0,0 +1,78 @@
1
+ import type { AmbientAnimation, PrimitiveContent, RuntimeConnectorState, RuntimeConnectorStyle, RuntimeElementState, TextContent } from "../types/node.ts";
2
+ import type { RuntimeBundle } from "../types/runtime-bundle.ts";
3
+ export type LifecycleKey = "entering" | "present" | "exiting" | "removed";
4
+ /** Interpolation result for a frame update. */
5
+ export interface FrameUpdate {
6
+ id: string;
7
+ asset: string;
8
+ lifecycle: LifecycleKey;
9
+ ambient: AmbientAnimation[];
10
+ pos: [number, number];
11
+ size: number;
12
+ layer: string;
13
+ entry?: string;
14
+ exit?: string;
15
+ text?: TextContent;
16
+ primitive?: PrimitiveContent;
17
+ }
18
+ /** Interpolation result for a connector frame update. */
19
+ export interface ConnectorFrameUpdate {
20
+ id: string;
21
+ route: [number, number][];
22
+ layer: string;
23
+ lifecycle: LifecycleKey;
24
+ style: RuntimeConnectorStyle;
25
+ start: RuntimeConnectorState["start"];
26
+ end: RuntimeConnectorState["end"];
27
+ direction: RuntimeConnectorState["direction"];
28
+ ambient: AmbientAnimation[];
29
+ entry?: string;
30
+ exit?: string;
31
+ }
32
+ /**
33
+ * Animation engine — resolves progress against compiled RuntimeBundle scene stops.
34
+ *
35
+ * The engine does not manipulate DOM. It computes interpolation data and lifecycle
36
+ * transitions that the controller applies to the rendering engine.
37
+ */
38
+ export declare class AnimationEngine {
39
+ private _bundle;
40
+ private _progress;
41
+ private _paused;
42
+ private _prevFrameMap;
43
+ private _elementFrameMap;
44
+ private _prevConnectorFrameMap;
45
+ private _connectorFrameMap;
46
+ get bundle(): RuntimeBundle | null;
47
+ get progress(): number;
48
+ getProgress(): number;
49
+ get paused(): boolean;
50
+ isPaused(): boolean;
51
+ get elementsCount(): number;
52
+ get connectorsCount(): number;
53
+ /** Initialize with a compiled runtime bundle. */
54
+ init(bundle: RuntimeBundle): void;
55
+ /** Set current scroll progress (0-1) and compute frame update. */
56
+ setProgress(progress: number): void;
57
+ /** Get interpolated FrameUpdate for an element id or runtime element. */
58
+ getElementUpdate(element: string | Pick<RuntimeElementState, "id">): FrameUpdate;
59
+ getFrameUpdates(): FrameUpdate[];
60
+ /** Get interpolated ConnectorFrameUpdate for a connector id or runtime connector. */
61
+ getConnectorUpdate(connector: string | Pick<RuntimeConnectorState, "id">): ConnectorFrameUpdate;
62
+ getConnectorFrameUpdates(): ConnectorFrameUpdate[];
63
+ /** Compute lifecycle transition between previous and current frame. */
64
+ getLifecycleTransition(elId: string): {
65
+ from: LifecycleKey;
66
+ to: LifecycleKey;
67
+ } | null;
68
+ /** Compute lifecycle transition between previous and current connector frame. */
69
+ getConnectorLifecycleTransition(connectorId: string): {
70
+ from: LifecycleKey;
71
+ to: LifecycleKey;
72
+ } | null;
73
+ getCurrentState(): RuntimeBundle["scenes"][number] | null;
74
+ pause(): void;
75
+ resume(): void;
76
+ destroy(): void;
77
+ }
78
+ //# sourceMappingURL=animation-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation-engine.d.ts","sourceRoot":"","sources":["../../src/animation/animation-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import type { RuntimeBundle } from "../types/runtime-bundle.ts";
2
+ import { AnimationEngine } from "./animation-engine.ts";
3
+ export interface ControllerEvents {
4
+ "progress-change": (progress: number) => void;
5
+ "scene-change": (index: number) => void;
6
+ paused: () => void;
7
+ resumed: () => void;
8
+ }
9
+ type EventKey = keyof ControllerEvents;
10
+ export interface ControllerConfig {
11
+ /** Scroll container used to derive progress. Defaults to the mount target in `mountScene()`. */
12
+ container?: HTMLElement;
13
+ /** SVG scene updated by this controller. Defaults to the first SVG in `container` for direct controller usage. */
14
+ sceneElement?: SVGSVGElement;
15
+ scrollDirection?: "vertical" | "horizontal";
16
+ scrollOffset?: {
17
+ top?: number;
18
+ bottom?: number;
19
+ left?: number;
20
+ right?: number;
21
+ };
22
+ minProgress?: number;
23
+ maxProgress?: number;
24
+ keyboardControls?: boolean;
25
+ touchControls?: boolean;
26
+ scrollSensitivity?: number;
27
+ transitionDuration?: number;
28
+ transitionEasing?: "linear" | "ease-in-out" | "ease-out";
29
+ }
30
+ interface ControllerRuntime {
31
+ engine?: AnimationEngine;
32
+ sceneElement?: SVGSVGElement;
33
+ }
34
+ /**
35
+ * Animation controller — manages scroll progress, scene navigation,
36
+ * and delegates to the animation engine for frame updates.
37
+ */
38
+ export declare class AnimationController {
39
+ private _engine;
40
+ private _bundle;
41
+ private _sceneIndex;
42
+ private _progress;
43
+ private _paused;
44
+ private _config;
45
+ private _container;
46
+ private _sceneElement;
47
+ private _ownsEngine;
48
+ private _rafId;
49
+ private _pendingProgress;
50
+ private _destroyed;
51
+ private _listeners;
52
+ private _minScroll;
53
+ private _maxScroll;
54
+ private _touchStartY;
55
+ private _touchStartX;
56
+ private _isDragging;
57
+ private _transitionAnim;
58
+ get engine(): AnimationEngine;
59
+ get progress(): number;
60
+ getProgress(): number;
61
+ get sceneIndex(): number;
62
+ getSceneIndex(): number;
63
+ get scenes(): RuntimeBundle["scenes"];
64
+ get paused(): boolean;
65
+ get currentScene(): RuntimeBundle["scenes"][number] | undefined;
66
+ /**
67
+ * Initialize the controller with a compiled bundle and optional runtime resources.
68
+ */
69
+ init(bundle: RuntimeBundle, config?: ControllerConfig, runtime?: ControllerRuntime): void;
70
+ /**
71
+ * Set scroll progress (0–1, clamped) and trigger frame update.
72
+ */
73
+ setProgress(progress: number): void;
74
+ /**
75
+ * Navigate to next scene (wraps to 0 if at end).
76
+ */
77
+ nextScene(): void;
78
+ /**
79
+ * Navigate to previous scene (wraps to last if at beginning).
80
+ */
81
+ prevScene(): void;
82
+ /**
83
+ * Set scene index directly.
84
+ */
85
+ setSceneIndex(index: number): void;
86
+ /**
87
+ * Pause all animations.
88
+ */
89
+ pause(): void;
90
+ /**
91
+ * Resume from paused state.
92
+ */
93
+ resume(): void;
94
+ /**
95
+ * Check if controller is paused.
96
+ */
97
+ isPaused(): boolean;
98
+ /**
99
+ * Destroy controller and clean up all listeners and resources.
100
+ */
101
+ destroy(): void;
102
+ on<K extends EventKey>(event: K, listener: ControllerEvents[K]): void;
103
+ off<K extends EventKey>(event: K, listener: ControllerEvents[K]): void;
104
+ private _emit;
105
+ private _scheduleProgressForward;
106
+ private _cancelFrame;
107
+ private _applyFrameUpdate;
108
+ private _applyLifecycleChanges;
109
+ private _applyConnectorLifecycleChanges;
110
+ private _applyEntryAnimation;
111
+ private _applyExitAnimation;
112
+ private _applyConnectorEntryAnimation;
113
+ private _applyConnectorExitAnimation;
114
+ private _transitionToScene;
115
+ private _animateProgress;
116
+ private _cancelTransition;
117
+ private _bindScroll;
118
+ private _unbindScroll;
119
+ private _calculateScrollBounds;
120
+ private _onScroll;
121
+ private _onResize;
122
+ private _onKeyDown;
123
+ private _onTouchStart;
124
+ private _onTouchMove;
125
+ private _onTouchEnd;
126
+ private _applyPauseState;
127
+ private _assertNotDestroyed;
128
+ }
129
+ export {};
130
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/animation/controller.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,MAAM,WAAW,gBAAgB;IAChC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,KAAK,QAAQ,GAAG,MAAM,gBAAgB,CAAC;AASvC,MAAM,WAAW,gBAAgB;IAChC,gGAAgG;IAChG,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,kHAAkH;IAClH,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,eAAe,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IAC5C,YAAY,CAAC,EAAE;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC;CACzD;AAmBD,UAAU,iBAAiB;IAC1B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,YAAY,CAAC,EAAE,aAAa,CAAC;CAC7B;AAID;;;GAGG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAmD;IAGrE,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,eAAe,CAAyD;IAEhF,IAAI,MAAM,IAAI,eAAe,CAE5B;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,WAAW,IAAI,MAAM;IAKrB,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,aAAa,IAAI,MAAM;IAKvB,IAAI,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,CAEpC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,YAAY,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAE9D;IAED;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,GAAE,gBAAqB,EAAE,OAAO,GAAE,iBAAsB,GAAG,IAAI;IAoBjG;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgBnC;;OAEG;IACH,SAAS,IAAI,IAAI;IAQjB;;OAEG;IACH,SAAS,IAAI,IAAI;IAQjB;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWlC;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,MAAM,IAAI,IAAI;IAUd;;OAEG;IACH,QAAQ,IAAI,OAAO;IAKnB;;OAEG;IACH,OAAO,IAAI,IAAI;IAef,EAAE,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAOrE,GAAG,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAQtE,OAAO,CAAC,KAAK;IAiBb,OAAO,CAAC,wBAAwB;IAehC,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,iBAAiB;IAyCzB,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,+BAA+B;IAsDvC,OAAO,CAAC,oBAAoB;IAe5B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,6BAA6B;IAkBrC,OAAO,CAAC,4BAA4B;IAuBpC,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,SAAS,CAqBf;IAEF,OAAO,CAAC,SAAS,CAGf;IAEF,OAAO,CAAC,UAAU,CAShB;IAEF,OAAO,CAAC,aAAa,CASnB;IAEF,OAAO,CAAC,YAAY,CAelB;IAEF,OAAO,CAAC,WAAW,CAGjB;IAIF,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,mBAAmB;CAI3B"}