@rafaelaugusto/jolt 0.1.0-rc.12 → 0.1.0-rc.12.1

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 (103) hide show
  1. package/README.md +2 -2
  2. package/dist/core/gradient-text.d.ts +24 -0
  3. package/dist/core/gradient-text.d.ts.map +1 -0
  4. package/dist/core/gradient-text.js +30 -0
  5. package/dist/core/gradient-text.js.map +1 -0
  6. package/dist/core/motion-behaviors.d.ts +68 -0
  7. package/dist/core/motion-behaviors.d.ts.map +1 -0
  8. package/dist/core/motion-behaviors.js +276 -0
  9. package/dist/core/motion-behaviors.js.map +1 -0
  10. package/dist/core/rig.d.ts +73 -0
  11. package/dist/core/rig.d.ts.map +1 -0
  12. package/dist/core/rig.js +99 -0
  13. package/dist/core/rig.js.map +1 -0
  14. package/dist/gradient-text/index.d.ts +2 -10
  15. package/dist/gradient-text/index.d.ts.map +1 -1
  16. package/dist/gradient-text/index.js +2 -25
  17. package/dist/gradient-text/index.js.map +1 -1
  18. package/dist/gradient-text/native.d.ts +2 -8
  19. package/dist/gradient-text/native.d.ts.map +1 -1
  20. package/dist/gradient-text/native.js.map +1 -1
  21. package/dist/motion-behaviors.d.ts +5 -54
  22. package/dist/motion-behaviors.d.ts.map +1 -1
  23. package/dist/motion-behaviors.js +18 -267
  24. package/dist/motion-behaviors.js.map +1 -1
  25. package/dist/rig/index.d.ts +2 -27
  26. package/dist/rig/index.d.ts.map +1 -1
  27. package/dist/rig/index.js +5 -89
  28. package/dist/rig/index.js.map +1 -1
  29. package/dist/web/behaviors.d.ts +5 -0
  30. package/dist/web/behaviors.d.ts.map +1 -0
  31. package/dist/web/behaviors.js +2 -0
  32. package/dist/web/behaviors.js.map +1 -0
  33. package/dist/web/effect.d.ts +2 -1
  34. package/dist/web/effect.d.ts.map +1 -1
  35. package/dist/web/effect.js +11 -4
  36. package/dist/web/effect.js.map +1 -1
  37. package/dist/web/gradient-css.d.ts +2 -0
  38. package/dist/web/gradient-css.d.ts.map +1 -0
  39. package/dist/web/gradient-css.js +5 -0
  40. package/dist/web/gradient-css.js.map +1 -0
  41. package/dist/web/gradient-text.d.ts +24 -0
  42. package/dist/web/gradient-text.d.ts.map +1 -0
  43. package/dist/web/gradient-text.js +179 -0
  44. package/dist/web/gradient-text.js.map +1 -0
  45. package/dist/web/gradient.d.ts.map +1 -1
  46. package/dist/web/gradient.js +2 -1
  47. package/dist/web/gradient.js.map +1 -1
  48. package/dist/web/interaction.d.ts +2 -0
  49. package/dist/web/interaction.d.ts.map +1 -1
  50. package/dist/web/interaction.js.map +1 -1
  51. package/dist/web/plan.d.ts +2 -0
  52. package/dist/web/plan.d.ts.map +1 -1
  53. package/dist/web/plan.js.map +1 -1
  54. package/dist/web/public.d.ts +17 -3
  55. package/dist/web/public.d.ts.map +1 -1
  56. package/dist/web/public.js +8 -0
  57. package/dist/web/public.js.map +1 -1
  58. package/dist/web/rig.d.ts +43 -0
  59. package/dist/web/rig.d.ts.map +1 -0
  60. package/dist/web/rig.js +307 -0
  61. package/dist/web/rig.js.map +1 -0
  62. package/dist/web/runtime.d.ts +15 -3
  63. package/dist/web/runtime.d.ts.map +1 -1
  64. package/dist/web/runtime.js +97 -4
  65. package/dist/web/runtime.js.map +1 -1
  66. package/dist/web/scope.d.ts +7 -1
  67. package/dist/web/scope.d.ts.map +1 -1
  68. package/dist/web/scope.js +16 -2
  69. package/dist/web/scope.js.map +1 -1
  70. package/dist/web/sensors.d.ts +11 -4
  71. package/dist/web/sensors.d.ts.map +1 -1
  72. package/dist/web/sensors.js +59 -33
  73. package/dist/web/sensors.js.map +1 -1
  74. package/dist/web/shape.d.ts +2 -0
  75. package/dist/web/shape.d.ts.map +1 -1
  76. package/dist/web/shape.js +44 -12
  77. package/dist/web/shape.js.map +1 -1
  78. package/dist/web/vue/index.d.ts +12 -3
  79. package/dist/web/vue/index.d.ts.map +1 -1
  80. package/dist/web/vue/index.js +115 -35
  81. package/dist/web/vue/index.js.map +1 -1
  82. package/package.json +5 -2
  83. package/src/core/gradient-text.ts +56 -0
  84. package/src/core/motion-behaviors.ts +337 -0
  85. package/src/core/rig.ts +149 -0
  86. package/src/gradient-text/index.ts +7 -43
  87. package/src/gradient-text/native.ts +2 -7
  88. package/src/motion-behaviors.ts +34 -316
  89. package/src/rig/index.ts +25 -124
  90. package/src/web/behaviors.ts +12 -0
  91. package/src/web/effect.ts +10 -5
  92. package/src/web/gradient-css.ts +8 -0
  93. package/src/web/gradient-text.ts +234 -0
  94. package/src/web/gradient.ts +2 -1
  95. package/src/web/interaction.ts +2 -0
  96. package/src/web/plan.ts +2 -0
  97. package/src/web/public.ts +45 -4
  98. package/src/web/rig.ts +377 -0
  99. package/src/web/runtime.ts +116 -8
  100. package/src/web/scope.ts +32 -4
  101. package/src/web/sensors.ts +76 -48
  102. package/src/web/shape.ts +42 -9
  103. package/src/web/vue/index.ts +122 -31
package/README.md CHANGED
@@ -31,7 +31,7 @@ NativeScript's `view.animate()` covers the basics and stops there: one curve for
31
31
 
32
32
  Jolt computes the motion once, in JavaScript, when the animation starts, and hands it to the platform as keyframes: Core Animation on iOS, `ObjectAnimator` on Android. Those default view tracks play without per-frame JavaScript. Real-size layout, opt-in subscribers, gesture input and timeline step activation retain their documented [execution limits](https://jolt.rafaelaugusto.dev/guide/how-it-works). Springs follow real physics, and an animation that interrupts another one starts from where the view is, at the speed it was going.
33
33
 
34
- The [0.1.0-rc.12 release candidate](https://github.com/rafaelaugustos/jolt/blob/v0.1.0-rc.12/CHANGELOG.md) adds native/Web pointer presence, property groups, renderer activity, bounded drawing, drop targets, optional audio/cues and inspection, plus Web paths, 3D rotation and shadows. The versioned [portable foundations](https://github.com/rafaelaugustos/jolt/blob/v0.1.0-rc.12/docs/guide/portable-foundations.md) and [interaction/depth guides](https://github.com/rafaelaugustos/jolt/blob/v0.1.0-rc.12/docs/guide/interaction-depth.md) include reviewed recordings and platform limits. Install `@rafaelaugusto/jolt@0.1.0-rc.12` and rebuild native apps; external native properties also need matching `@rafaelaugusto/jolt-native@0.1.0-rc.12`. Web APIs remain experimental; physical-device acceptance and performance investigations remain open.
34
+ The [0.1.0-rc.12.1 release candidate](https://github.com/rafaelaugustos/jolt/blob/v0.1.0-rc.12.1/CHANGELOG.md) adds [portable composition](https://github.com/rafaelaugustos/jolt/blob/v0.1.0-rc.12.1/docs/guide/portable-composition.md): retained Web resources and Vue shapes, behavior priorities, gradient text, articulated 2D rigs, shared helpers and runtime-aware reduced-motion observation. Browser vector adapters include explicit availability; physical browser sensor validation remains open in #385. The guide includes reviewed native/browser recordings and platform limits. Install `@rafaelaugusto/jolt@0.1.0-rc.12.1` and rebuild native apps; external native properties also need matching `@rafaelaugusto/jolt-native@0.1.0-rc.12.1`. Web APIs remain experimental; performance investigations remain open.
35
35
 
36
36
  For the browser, import **`@rafaelaugusto/jolt/web`**. It installs without NativeScript, Vue or React; **`@rafaelaugusto/jolt/web/vue`** optionally integrates Vue 3.5 DOM refs and enter/leave. Both entries are experimental and use the same motion compiler as native playback. See [installation](https://jolt.rafaelaugusto.dev/guide/install#experimental-web-candidate), [finite Web playback](https://jolt.rafaelaugusto.dev/guide/web-runtime) and [Vue Web motion](https://jolt.rafaelaugusto.dev/guide/web-vue). Mavis integration and its shared application proof continue separately.
37
37
 
@@ -101,7 +101,7 @@ For the browser, import **`@rafaelaugusto/jolt/web`**. It installs without Nativ
101
101
  npm install @rafaelaugusto/jolt@next
102
102
  ```
103
103
 
104
- The current release candidate is **0.1.0-rc.12**, published under the `next` tag. Requires `@nativescript/core` 8.9 or later. It doesn't depend on a framework: it takes a view, or an element that holds one. Rebuild the native app after installing or upgrading Jolt. See [release status and limits](https://jolt.rafaelaugusto.dev/guide/not-there-yet) for the remaining stable-release acceptance work.
104
+ The current release candidate is **0.1.0-rc.12.1**, published under the `next` tag. Requires `@nativescript/core` 8.9 or later. It doesn't depend on a framework: it takes a view, or an element that holds one. Rebuild the native app after installing or upgrading Jolt. See [release status and limits](https://jolt.rafaelaugusto.dev/guide/not-there-yet) for the remaining stable-release acceptance work.
105
105
 
106
106
  On iOS 15+, Jolt requests up to 120 Hz on ProMotion displays. Set `CADisableMinimumFrameDurationOnPhone` to `true` in the app's `App_Resources/iOS/Info.plist` and rebuild to enable higher rates on iPhone. See the [iOS setup](https://jolt.rafaelaugusto.dev/guide/install#promotion-on-ios); the system still chooses the actual refresh rate.
107
107
 
@@ -0,0 +1,24 @@
1
+ /** Plain text paint shared by native glyph masks and browser text clipping. */
2
+ export interface GradientTextDefinition<Color = string> {
3
+ colors: readonly Color[];
4
+ stops?: readonly number[];
5
+ /** Degrees clockwise from left-to-right. */
6
+ angle?: number;
7
+ sheen?: {
8
+ color?: Color;
9
+ width?: number;
10
+ direction?: 'left' | 'right';
11
+ };
12
+ }
13
+ export interface TextPaint {
14
+ colors: number[];
15
+ stops: number[];
16
+ angle: number;
17
+ sheen: number;
18
+ width: number;
19
+ }
20
+ export declare function resolveGradientText<Color>(options: GradientTextDefinition<Color>, parse: (color: Color) => number): {
21
+ paint: TextPaint;
22
+ direction: "left" | "right";
23
+ };
24
+ //# sourceMappingURL=gradient-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gradient-text.d.ts","sourceRoot":"","sources":["../../src/core/gradient-text.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB,CAAC,KAAK,GAAG,MAAM;IACpD,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACzB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CACxE;AACD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AACD,wBAAgB,mBAAmB,CAAC,KAAK,EACvC,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,EACtC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM;;;EAsChC"}
@@ -0,0 +1,30 @@
1
+ export function resolveGradientText(options, parse) {
2
+ if (!Array.isArray(options.colors) ||
3
+ options.colors.length < 2 ||
4
+ options.colors.length > 8)
5
+ throw new TypeError('Gradient text needs 2..8 colors.');
6
+ const colors = Array.from(options.colors, parse);
7
+ const stops = options.stops
8
+ ? Array.from(options.stops)
9
+ : colors.map((_, i) => i / (colors.length - 1));
10
+ if (stops.length !== colors.length ||
11
+ stops.some((stop, i) => !Number.isFinite(stop) || stop < 0 || stop > 1 || (i > 0 && stop < stops[i - 1])))
12
+ throw new TypeError('Gradient stops must be ordered in 0..1 and match colors.');
13
+ const paint = {
14
+ colors,
15
+ stops,
16
+ angle: options.angle ?? 0,
17
+ sheen: options.sheen?.color === undefined ? 0xbfffffff : parse(options.sheen.color),
18
+ width: options.sheen?.width ?? 0.3,
19
+ };
20
+ const direction = options.sheen?.direction ?? 'right';
21
+ if (direction !== 'left' && direction !== 'right')
22
+ throw new TypeError('Invalid text sheen direction.');
23
+ if (!Number.isFinite(paint.angle) ||
24
+ !Number.isFinite(paint.width) ||
25
+ paint.width <= 0 ||
26
+ paint.width > 1)
27
+ throw new TypeError('Invalid text gradient angle or sheen width.');
28
+ return { paint, direction };
29
+ }
30
+ //# sourceMappingURL=gradient-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gradient-text.js","sourceRoot":"","sources":["../../src/core/gradient-text.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,mBAAmB,CACjC,OAAsC,EACtC,KAA+B;IAE/B,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAEzB,MAAM,IAAI,SAAS,CAAC,kCAAkC,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK;QACzB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;IACjD,IACE,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAC9B,KAAK,CAAC,IAAI,CACR,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACV,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CACpF;QAED,MAAM,IAAI,SAAS,CAAC,0DAA0D,CAAC,CAAA;IACjF,MAAM,KAAK,GAAc;QACvB,MAAM;QACN,KAAK;QACL,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QACnF,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,IAAI,GAAG;KACnC,CAAA;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE,SAAS,IAAI,OAAO,CAAA;IACrD,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO;QAC/C,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAA;IACtD,IACE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7B,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;QAC7B,KAAK,CAAC,KAAK,IAAI,CAAC;QAChB,KAAK,CAAC,KAAK,GAAG,CAAC;QAEf,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAA;IACpE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,68 @@
1
+ /** Platform execution is supplied by the native or browser scope adapter. */
2
+ export interface BehaviorScope {
3
+ suspend(): void;
4
+ resume(): void;
5
+ dispose(): void;
6
+ }
7
+ export interface BehaviorHost<S extends BehaviorScope> {
8
+ scope(): S;
9
+ hidden(): boolean;
10
+ visibility(callback: () => void): () => void;
11
+ disposed?(): void;
12
+ }
13
+ export type BehaviorStatus = 'completed' | 'interrupted' | 'cancelled' | 'failed' | 'blocked';
14
+ export interface BehaviorResult {
15
+ readonly status: BehaviorStatus;
16
+ readonly error?: unknown;
17
+ }
18
+ export interface BehaviorRun {
19
+ readonly id: number;
20
+ readonly name: string;
21
+ readonly finished: Promise<BehaviorResult>;
22
+ cancel(): void;
23
+ }
24
+ export interface BehaviorContext<S extends BehaviorScope> {
25
+ /** Private to this run; cancellation disposes it before the next run starts. */
26
+ readonly scope: S;
27
+ readonly id: number;
28
+ readonly active: boolean;
29
+ /** Check after an external await, before starting work or changing application state. */
30
+ checkpoint(): void;
31
+ /** Await work and check identity before continuing. False animation results cancel the run. */
32
+ wait<T>(work: PromiseLike<T>): Promise<T>;
33
+ /** Guard a callback that may arrive after interruption (e.g. a service response). */
34
+ guard<A extends unknown[]>(callback: (...args: A) => void): (...args: A) => void;
35
+ }
36
+ export interface MotionBehavior<S extends BehaviorScope> {
37
+ priority?: number;
38
+ /** Evaluated on each request. Domain state stays in the application. */
39
+ when?: () => boolean;
40
+ /** Explicit exclusions, including higher-priority requests. Defaults to none. */
41
+ blocks?: readonly string[];
42
+ /** Equal-priority requests, including the same name, reject by default. */
43
+ equal?: 'reject' | 'replace';
44
+ run(context: BehaviorContext<S>): void | PromiseLike<unknown>;
45
+ }
46
+ export interface MotionBehaviorsOptions<N extends string> {
47
+ /** Restart this declared rest behavior after success, cancellation or failure. No implicit resume. */
48
+ rest?: N;
49
+ /** Receive failure after cleanup. Throwing here does not strand another run. */
50
+ onError?: (error: unknown, name: N) => void;
51
+ }
52
+ export interface MotionBehaviors<N extends string = string> {
53
+ readonly current: N | undefined;
54
+ readonly disposed: boolean;
55
+ readonly paused: boolean;
56
+ can(name: N): boolean;
57
+ request(name: N): BehaviorRun;
58
+ /** Cancel the active run and restore the declared rest behavior. */
59
+ cancel(): void;
60
+ pause(): void;
61
+ play(): void;
62
+ /** Cancel without restoration; later requests may start again. */
63
+ stop(): void;
64
+ dispose(): void;
65
+ }
66
+ /** One exclusive interaction lane; other coordinators and unrelated input remain independent. */
67
+ export declare function createMotionBehaviors<S extends BehaviorScope, const D extends Record<string, MotionBehavior<S>>>(definitions: D, options: MotionBehaviorsOptions<Extract<keyof D, string>>, host: BehaviorHost<S>): MotionBehaviors<Extract<keyof D, string>>;
68
+ //# sourceMappingURL=motion-behaviors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion-behaviors.d.ts","sourceRoot":"","sources":["../../src/core/motion-behaviors.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAA;IACf,MAAM,IAAI,IAAI,CAAA;IACd,OAAO,IAAI,IAAI,CAAA;CAChB;AACD,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,aAAa;IACnD,KAAK,IAAI,CAAC,CAAA;IACV,MAAM,IAAI,OAAO,CAAA;IACjB,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC5C,QAAQ,CAAC,IAAI,IAAI,CAAA;CAClB;AAED,MAAM,MAAM,cAAc,GACxB,WAAW,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;AAClE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AACD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC1C,MAAM,IAAI,IAAI,CAAA;CACf;AACD,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,aAAa;IACtD,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,yFAAyF;IACzF,UAAU,IAAI,IAAI,CAAA;IAClB,+FAA+F;IAC/F,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACzC,qFAAqF;IACrF,KAAK,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;CACjF;AACD,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,aAAa;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,OAAO,CAAA;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;CAC9D;AACD,MAAM,WAAW,sBAAsB,CAAC,CAAC,SAAS,MAAM;IACtD,sGAAsG;IACtG,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,gFAAgF;IAChF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;CAC5C;AACD,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxD,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,OAAO,CAAA;IACrB,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,WAAW,CAAA;IAC7B,oEAAoE;IACpE,MAAM,IAAI,IAAI,CAAA;IACd,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,kEAAkE;IAClE,IAAI,IAAI,IAAI,CAAA;IACZ,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,iGAAiG;AACjG,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,aAAa,EACvB,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,EAEjD,WAAW,EAAE,CAAC,EACd,OAAO,EAAE,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,EACzD,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACpB,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAoQ3C"}
@@ -0,0 +1,276 @@
1
+ /** One exclusive interaction lane; other coordinators and unrelated input remain independent. */
2
+ export function createMotionBehaviors(definitions, options, host) {
3
+ // Copy policy so changing the caller's object cannot silently change an active run.
4
+ const policies = new Map();
5
+ for (const [name, definition] of Object.entries(definitions)) {
6
+ if (!definition ||
7
+ typeof definition.run !== 'function' ||
8
+ !Number.isFinite(definition.priority ?? 0) ||
9
+ (definition.when !== undefined && typeof definition.when !== 'function') ||
10
+ (definition.equal !== undefined &&
11
+ !['reject', 'replace'].includes(definition.equal)) ||
12
+ (definition.blocks !== undefined &&
13
+ (!Array.isArray(definition.blocks) ||
14
+ definition.blocks.some((n) => !Object.hasOwn(definitions, n)))))
15
+ throw new TypeError(`Invalid motion behavior "${name}".`);
16
+ policies.set(name, { ...definition, blocks: [...(definition.blocks ?? [])] });
17
+ }
18
+ if (options.rest !== undefined && !policies.has(options.rest))
19
+ throw new TypeError('The rest behavior must be declared.');
20
+ const cancelled = Symbol('cancelled behavior');
21
+ let serial = 0, disposed = false, paused = false, changing = false, restPending = false;
22
+ let background = host.hidden();
23
+ let unlisten = () => { };
24
+ const isPaused = () => paused || background;
25
+ let active;
26
+ const policy = (name) => {
27
+ const definition = policies.get(name);
28
+ if (!definition)
29
+ throw new TypeError(`Unknown motion behavior "${name}".`);
30
+ return definition;
31
+ };
32
+ const report = (error, name) => {
33
+ try {
34
+ options.onError?.(error, name);
35
+ }
36
+ catch {
37
+ /* Reporters cannot replace ownership. */
38
+ }
39
+ };
40
+ const finish = (run, status, error) => {
41
+ if (run.done)
42
+ return;
43
+ run.done = true;
44
+ run.wake?.();
45
+ if (active === run)
46
+ active = undefined;
47
+ try {
48
+ run.scope.dispose();
49
+ }
50
+ catch (cleanup) {
51
+ error =
52
+ error === undefined
53
+ ? cleanup
54
+ : new AggregateError([error, cleanup], 'Behavior cleanup failed.');
55
+ status = 'failed';
56
+ }
57
+ run.resolve({ status, ...(error === undefined ? {} : { error }) });
58
+ if (error !== undefined)
59
+ report(error, run.name);
60
+ };
61
+ const restore = (previous) => {
62
+ if (!disposed && !active && options.rest !== undefined && previous !== options.rest) {
63
+ restPending = isPaused();
64
+ if (!isPaused()) {
65
+ try {
66
+ controller.request(options.rest);
67
+ }
68
+ catch (error) {
69
+ report(error, options.rest);
70
+ }
71
+ }
72
+ }
73
+ };
74
+ const allowed = (name) => {
75
+ const candidate = policy(name);
76
+ if (disposed || isPaused() || changing)
77
+ return false;
78
+ let permitted;
79
+ changing = true;
80
+ try {
81
+ permitted = candidate.when?.() !== false;
82
+ }
83
+ finally {
84
+ changing = false;
85
+ }
86
+ if (!permitted || disposed || isPaused())
87
+ return false;
88
+ if (!active)
89
+ return true;
90
+ const current = policy(active.name);
91
+ if (current.blocks?.includes(name))
92
+ return false;
93
+ const delta = (candidate.priority ?? 0) - (current.priority ?? 0);
94
+ return delta > 0 || (delta === 0 && candidate.equal === 'replace');
95
+ };
96
+ const cancel = (restoreRest) => {
97
+ if (changing)
98
+ return;
99
+ restPending = false;
100
+ const previous = active?.name;
101
+ changing = true;
102
+ try {
103
+ if (active)
104
+ finish(active, 'cancelled');
105
+ }
106
+ finally {
107
+ changing = false;
108
+ }
109
+ if (restoreRest)
110
+ restore(previous);
111
+ };
112
+ const controller = {
113
+ get current() {
114
+ return active?.name;
115
+ },
116
+ get disposed() {
117
+ return disposed;
118
+ },
119
+ get paused() {
120
+ return isPaused();
121
+ },
122
+ can: allowed,
123
+ request(name) {
124
+ const id = ++serial;
125
+ if (!allowed(name))
126
+ return { id, name, finished: Promise.resolve({ status: 'blocked' }), cancel() { } };
127
+ // Guard/exclusion callbacks may have changed ownership; evaluate them before mutation.
128
+ const definition = policy(name);
129
+ changing = true;
130
+ try {
131
+ if (active)
132
+ finish(active, 'interrupted');
133
+ }
134
+ finally {
135
+ changing = false;
136
+ }
137
+ if (disposed || isPaused())
138
+ return {
139
+ id,
140
+ name,
141
+ finished: Promise.resolve({ status: 'cancelled' }),
142
+ cancel() { },
143
+ };
144
+ restPending = false;
145
+ let resolve;
146
+ const finished = new Promise((r) => {
147
+ resolve = r;
148
+ });
149
+ const run = { id, name, scope: host.scope(), done: false, resolve };
150
+ active = run;
151
+ const checkpoint = () => {
152
+ if (disposed || run.done || active !== run)
153
+ throw cancelled;
154
+ };
155
+ const context = {
156
+ id,
157
+ scope: run.scope,
158
+ get active() {
159
+ return !disposed && !run.done && active === run;
160
+ },
161
+ checkpoint,
162
+ async wait(work) {
163
+ checkpoint();
164
+ const result = await work;
165
+ checkpoint();
166
+ while (isPaused()) {
167
+ await new Promise((resolve) => {
168
+ const previous = run.wake;
169
+ run.wake = () => {
170
+ previous?.();
171
+ resolve();
172
+ };
173
+ });
174
+ checkpoint();
175
+ }
176
+ if (result === false)
177
+ throw cancelled;
178
+ return result;
179
+ },
180
+ guard(callback) {
181
+ return (...args) => {
182
+ if (context.active)
183
+ callback(...args);
184
+ };
185
+ },
186
+ };
187
+ const settle = (status, error) => {
188
+ if (run.done)
189
+ return;
190
+ changing = true;
191
+ try {
192
+ finish(run, status, error);
193
+ }
194
+ finally {
195
+ changing = false;
196
+ }
197
+ restore(name);
198
+ };
199
+ try {
200
+ const work = definition.run(context);
201
+ void Promise.resolve(work).then(() => settle('completed'), (error) => error === cancelled ? settle('cancelled') : settle('failed', error));
202
+ }
203
+ catch (error) {
204
+ settle(error === cancelled ? 'cancelled' : 'failed', error === cancelled ? undefined : error);
205
+ }
206
+ return {
207
+ id,
208
+ name,
209
+ finished,
210
+ cancel() {
211
+ if (active === run)
212
+ cancel(true);
213
+ },
214
+ };
215
+ },
216
+ cancel() {
217
+ cancel(true);
218
+ },
219
+ pause() {
220
+ if (paused || disposed)
221
+ return;
222
+ paused = true;
223
+ active?.scope.suspend();
224
+ },
225
+ play() {
226
+ if (!paused || disposed)
227
+ return;
228
+ paused = false;
229
+ if (!background)
230
+ active?.scope.resume();
231
+ wake();
232
+ },
233
+ stop() {
234
+ cancel(false);
235
+ },
236
+ dispose() {
237
+ if (disposed)
238
+ return;
239
+ disposed = true;
240
+ unlisten();
241
+ restPending = false;
242
+ // Guards and cleanup may dispose reentrantly. Invalidate the current run too.
243
+ const wasChanging = changing;
244
+ changing = true;
245
+ try {
246
+ if (active)
247
+ finish(active, 'cancelled');
248
+ }
249
+ finally {
250
+ changing = wasChanging;
251
+ host.disposed?.();
252
+ }
253
+ },
254
+ };
255
+ const wake = () => {
256
+ if (disposed || isPaused())
257
+ return;
258
+ active?.wake?.();
259
+ if (active)
260
+ active.wake = undefined;
261
+ if (restPending) {
262
+ restPending = false;
263
+ restore();
264
+ }
265
+ };
266
+ unlisten = host.visibility(() => {
267
+ background = host.hidden();
268
+ if (background)
269
+ active?.scope.suspend();
270
+ else if (!paused)
271
+ active?.scope.resume();
272
+ wake();
273
+ });
274
+ return controller;
275
+ }
276
+ //# sourceMappingURL=motion-behaviors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion-behaviors.js","sourceRoot":"","sources":["../../src/core/motion-behaviors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { Track } from './track.js';
2
+ export declare const rigChannels: readonly ['x', 'y', 'scaleX', 'scaleY', 'rotate'];
3
+ export type RigChannel = (typeof rigChannels)[number];
4
+ export type RigTransform = Partial<Record<RigChannel, number>>;
5
+ export interface RigPart {
6
+ parent?: string;
7
+ /** Fractions of the part's border-box size. */
8
+ pivot?: {
9
+ x: number;
10
+ y: number;
11
+ };
12
+ rest?: RigTransform;
13
+ /** Degrees; the entire sampled rotation, including spring overshoot, is bounded. */
14
+ rotation?: readonly [number, number];
15
+ }
16
+ export interface RigSocket {
17
+ part: string;
18
+ /** Local logical units (native DIPs / CSS pixels), or fractions when relative. */
19
+ x: number;
20
+ y: number;
21
+ units?: 'dip' | 'relative';
22
+ }
23
+ export interface RigDefinition {
24
+ parts: Record<string, RigPart>;
25
+ poses: Record<string, Record<string, RigTransform>>;
26
+ sockets?: Record<string, RigSocket>;
27
+ }
28
+ export declare const shortestRigAngle: (angle: number) => number;
29
+ export interface RigPoseLayer {
30
+ pose: Record<string, RigTransform>;
31
+ weight: number;
32
+ }
33
+ export declare function resolveRigDefinition(definition: RigDefinition): {
34
+ parts: Map<string, {
35
+ parent?: string;
36
+ pivot: {
37
+ x: number;
38
+ y: number;
39
+ } | undefined;
40
+ rest: {
41
+ rotate?: number | undefined;
42
+ scaleX?: number | undefined;
43
+ scaleY?: number | undefined;
44
+ x?: number | undefined;
45
+ y?: number | undefined;
46
+ };
47
+ rotation: [number, number] | undefined;
48
+ }>;
49
+ poses: Map<string, {
50
+ [k: string]: {
51
+ rotate?: number | undefined;
52
+ scaleX?: number | undefined;
53
+ scaleY?: number | undefined;
54
+ x?: number | undefined;
55
+ y?: number | undefined;
56
+ };
57
+ }>;
58
+ sockets: Map<string, {
59
+ part: string;
60
+ /** Local logical units (native DIPs / CSS pixels), or fractions when relative. */
61
+ x: number;
62
+ y: number;
63
+ units?: 'dip' | 'relative';
64
+ }>;
65
+ used: Map<string, Set<"rotate" | "scaleX" | "scaleY" | "x" | "y">>;
66
+ select: (layers: readonly {
67
+ pose: string;
68
+ weight: number;
69
+ }[]) => RigPoseLayer[];
70
+ };
71
+ export declare function rigDestination(part: RigPart, name: string, property: RigChannel, rest: number, current: number, selected: readonly RigPoseLayer[]): number;
72
+ export declare function limitRigTrack(original: Track, limits?: readonly [number, number]): Track;
73
+ //# sourceMappingURL=rig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rig.d.ts","sourceRoot":"","sources":["../../src/core/rig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,eAAO,MAAM,WAAW,YAAI,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AACrD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;AAC9D,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+CAA+C;IAC/C,KAAK,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChC,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,kFAAkF;IAClF,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,CAAC,EAAE,KAAK,GAAG,UAAU,CAAA;CAC3B;AACD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAA;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CACpC;AAED,eAAO,MAAM,gBAAgB,UAAW,MAAM,WACD,CAAA;AAC7C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAClC,MAAM,EAAE,MAAM,CAAA;CACf;AACD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,aAAa;;iBA1BnD,MAAM;;eAEF,MAAM;eAAK,MAAM;;;;;;;;;;;;;;;;;;;;;cAMxB,MAAM;QACZ,kFAAkF;WAC/E,MAAM;WACN,MAAM;gBACD,KAAK,GAAG,UAAU;;;qBAgFhB,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,KAClD,YAAY,EAAE;EAQlB;AACD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,SAAS,YAAY,EAAE,UAiBlC;AACD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,KAAK,EACf,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,KAAK,CAcP"}
@@ -0,0 +1,99 @@
1
+ export const rigChannels = ['x', 'y', 'scaleX', 'scaleY', 'rotate'];
2
+ const finite = (n) => typeof n === 'number' && Number.isFinite(n);
3
+ export const shortestRigAngle = (angle) => ((((angle + 180) % 360) + 360) % 360) - 180;
4
+ export function resolveRigDefinition(definition) {
5
+ const parts = new Map(Object.entries(definition.parts).map(([name, part]) => [
6
+ name,
7
+ {
8
+ ...part,
9
+ pivot: part.pivot && { ...part.pivot },
10
+ rest: { ...part.rest },
11
+ rotation: part.rotation && [...part.rotation],
12
+ },
13
+ ]));
14
+ if (!parts.size || parts.size > 64)
15
+ throw new RangeError('A rig supports 1..64 parts.');
16
+ const validateTransform = (values) => {
17
+ for (const [key, value] of Object.entries(values))
18
+ if (!rigChannels.includes(key) || !finite(value))
19
+ throw new TypeError('Invalid rig transform.');
20
+ };
21
+ const used = new Map();
22
+ for (const [name, part] of parts) {
23
+ validateTransform(part.rest);
24
+ used.set(name, new Set(Object.keys(part.rest)));
25
+ if (part.pivot && (!finite(part.pivot.x) || !finite(part.pivot.y)))
26
+ throw new TypeError('Invalid rig pivot.');
27
+ if (part.rotation &&
28
+ (part.rotation.length !== 2 ||
29
+ !part.rotation.every(finite) ||
30
+ part.rotation[0] > part.rotation[1]))
31
+ throw new TypeError('Invalid rotation limits.');
32
+ const visited = new Set([name]);
33
+ let parent = part.parent;
34
+ while (parent !== undefined) {
35
+ if (!parts.has(parent) || visited.has(parent))
36
+ throw new TypeError('Rig hierarchy contains a cycle or missing parent.');
37
+ visited.add(parent);
38
+ parent = parts.get(parent).parent;
39
+ }
40
+ }
41
+ const poses = new Map(Object.entries(definition.poses).map(([name, pose]) => [
42
+ name,
43
+ Object.fromEntries(Object.entries(pose).map(([part, values]) => {
44
+ if (!parts.has(part))
45
+ throw new TypeError(`Unknown rig part "${part}".`);
46
+ validateTransform(values);
47
+ Object.keys(values).forEach((key) => used.get(part).add(key));
48
+ return [part, { ...values }];
49
+ })),
50
+ ]));
51
+ const sockets = new Map(Object.entries(definition.sockets ?? {}).map(([name, socket]) => {
52
+ if (!parts.has(socket.part) ||
53
+ !finite(socket.x) ||
54
+ !finite(socket.y) ||
55
+ (socket.units !== undefined && !['dip', 'relative'].includes(socket.units)))
56
+ throw new TypeError('Invalid rig socket.');
57
+ return [name, { ...socket }];
58
+ }));
59
+ const select = (layers) => {
60
+ return layers.map((layer) => {
61
+ if (!finite(layer.weight) || layer.weight < 0 || !poses.has(layer.pose))
62
+ throw new TypeError('Unknown pose or invalid blend weight.');
63
+ return { pose: poses.get(layer.pose), weight: layer.weight };
64
+ });
65
+ };
66
+ return { parts, poses, sockets, used, select };
67
+ }
68
+ export function rigDestination(part, name, property, rest, current, selected) {
69
+ let total = 0, offset = 0;
70
+ for (const layer of selected) {
71
+ const value = layer.pose[name]?.[property];
72
+ if (value === undefined)
73
+ continue;
74
+ total += layer.weight;
75
+ offset +=
76
+ (property === 'rotate' && !part.rotation
77
+ ? shortestRigAngle(value - rest)
78
+ : value - rest) * layer.weight;
79
+ }
80
+ const destination = rest + offset / Math.max(1, total);
81
+ return property === 'rotate' && !part.rotation
82
+ ? current + shortestRigAngle(destination - current)
83
+ : destination;
84
+ }
85
+ export function limitRigTrack(original, limits) {
86
+ if (!limits)
87
+ return original;
88
+ const [min, max] = limits, clamp = (value) => Math.max(min, Math.min(max, value));
89
+ return {
90
+ ...original,
91
+ values: original.values.map(clamp),
92
+ to: clamp(original.to),
93
+ valueAt: (time) => clamp(original.valueAt(time)),
94
+ velocityAt: (time) => original.valueAt(time) <= min || original.valueAt(time) >= max
95
+ ? 0
96
+ : original.velocityAt(time),
97
+ };
98
+ }
99
+ //# sourceMappingURL=rig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rig.js","sourceRoot":"","sources":["../../src/core/rig.ts"],"names":[],"mappings":"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"}