@fundamental-engine/dom 0.8.0 → 0.9.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 (40) hide show
  1. package/dist/browser-host.d.ts.map +1 -1
  2. package/dist/browser-host.js +4 -0
  3. package/dist/browser-host.js.map +1 -1
  4. package/dist/feedback.d.ts +21 -0
  5. package/dist/feedback.d.ts.map +1 -1
  6. package/dist/feedback.js +18 -0
  7. package/dist/feedback.js.map +1 -1
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +3 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/lint.d.ts +24 -1
  13. package/dist/lint.d.ts.map +1 -1
  14. package/dist/lint.js +40 -1
  15. package/dist/lint.js.map +1 -1
  16. package/dist/perf.d.ts +31 -4
  17. package/dist/perf.d.ts.map +1 -1
  18. package/dist/perf.js +57 -4
  19. package/dist/perf.js.map +1 -1
  20. package/dist/register-properties.d.ts +25 -0
  21. package/dist/register-properties.d.ts.map +1 -0
  22. package/dist/register-properties.js +48 -0
  23. package/dist/register-properties.js.map +1 -0
  24. package/dist/text-bodies.d.ts +16 -5
  25. package/dist/text-bodies.d.ts.map +1 -1
  26. package/dist/text-bodies.js +37 -6
  27. package/dist/text-bodies.js.map +1 -1
  28. package/dist/worker/offthread-bridge.d.ts +17 -0
  29. package/dist/worker/offthread-bridge.d.ts.map +1 -0
  30. package/dist/worker/offthread-bridge.js +47 -0
  31. package/dist/worker/offthread-bridge.js.map +1 -0
  32. package/dist/worker/render-worker.d.ts +9 -0
  33. package/dist/worker/render-worker.d.ts.map +1 -0
  34. package/dist/worker/render-worker.js +43 -0
  35. package/dist/worker/render-worker.js.map +1 -0
  36. package/dist/x-ray.d.ts +14 -0
  37. package/dist/x-ray.d.ts.map +1 -0
  38. package/dist/x-ray.js +66 -0
  39. package/dist/x-ray.js.map +1 -0
  40. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"browser-host.d.ts","sourceRoot":"","sources":["../src/browser-host.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAK1D,yDAAyD;AACzD,wBAAgB,WAAW,IAAI,SAAS,CAkCvC"}
1
+ {"version":3,"file":"browser-host.d.ts","sourceRoot":"","sources":["../src/browser-host.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAM1D,yDAAyD;AACzD,wBAAgB,WAAW,IAAI,SAAS,CAqCvC"}
@@ -1,7 +1,11 @@
1
1
  import { prefersReducedMotion, pageHidden } from "./env.js";
2
+ import { registerFieldProperties } from "./register-properties.js";
2
3
  const INPUT_EVENTS = ['pointerdown', 'wheel', 'keydown', 'touchstart'];
3
4
  /** Build a FieldHost backed by `window` / `document`. */
4
5
  export function browserHost() {
6
+ // Register the field-density channels as typed, compositor-interpolable CSS properties once at
7
+ // boot so consumers can transition/animate var(--field-density)/var(--d). No-op if unsupported.
8
+ registerFieldProperties();
5
9
  return {
6
10
  root: document,
7
11
  viewport: () => ({ width: window.innerWidth, height: window.innerHeight, dpr: window.devicePixelRatio || 1 }),
@@ -1 +1 @@
1
- {"version":3,"file":"browser-host.js","sourceRoot":"","sources":["../src/browser-host.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE5D,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAU,CAAC;AAEhF,yDAAyD;AACzD,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,gBAAgB,IAAI,CAAC,EAAE,CAAC;QAC7G,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC;QAClC,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY;QACzD,aAAa,EAAE,GAAG,EAAE,CAAC,oBAAoB,EAAE;QAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;QAC1B,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACtC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC3C,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;QACpD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;YACf,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;YACf,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE;YACnB,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAClD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,KAAK,MAAM,EAAE,IAAI,YAAY;gBAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,OAAO,GAAG,EAAE;gBACV,KAAK,MAAM,EAAE,IAAI,YAAY;oBAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACpE,CAAC,CAAC;QACJ,CAAC;QACD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;YACxB,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"browser-host.js","sourceRoot":"","sources":["../src/browser-host.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAU,CAAC;AAEhF,yDAAyD;AACzD,MAAM,UAAU,WAAW;IACzB,+FAA+F;IAC/F,gGAAgG;IAChG,uBAAuB,EAAE,CAAC;IAC1B,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,gBAAgB,IAAI,CAAC,EAAE,CAAC;QAC7G,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC;QAClC,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,YAAY;QACzD,aAAa,EAAE,GAAG,EAAE,CAAC,oBAAoB,EAAE;QAC3C,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;QAC1B,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACtC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC3C,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC;QACpD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;YACf,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE;YACf,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE;YACnB,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;YAClD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YACd,KAAK,MAAM,EAAE,IAAI,YAAY;gBAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,OAAO,GAAG,EAAE;gBACV,KAAK,MAAM,EAAE,IAAI,YAAY;oBAAE,MAAM,CAAC,mBAAmB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACpE,CAAC,CAAC;QACJ,CAAC;QACD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;YACxB,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -10,10 +10,19 @@ export interface ThresholdOptions {
10
10
  /** event dispatched on the exit edge (e.g. `field:dim` to pair with `field:lit`). */
11
11
  exitEvent?: string;
12
12
  }
13
+ /** Per-binding runtime activity: how many flushes the body has lived through, and whether any
14
+ * bound channel has ever received a non-zero value. The "silent contract gap" detector reads this. */
15
+ export interface FeedbackActivity {
16
+ /** flushes seen while this binding was registered (and the element connected). */
17
+ flushes: number;
18
+ /** has any bound channel ever flushed a non-zero value onto this element? */
19
+ written: boolean;
20
+ }
13
21
  export declare class FeedbackRegistry {
14
22
  private readonly bindings;
15
23
  private readonly direct;
16
24
  private readonly thresholds;
25
+ private readonly activity;
17
26
  private _cssWritesLastFrame;
18
27
  /** Declare which state keys map to which CSS vars on an element (e.g. `{ density: '--field-density' }`). */
19
28
  bind(element: Element, map: VarBinding): void;
@@ -30,6 +39,18 @@ export declare class FeedbackRegistry {
30
39
  element: Element;
31
40
  vars: string[];
32
41
  }>;
42
+ /**
43
+ * Per-element runtime feedback activity accumulated across `flush()` calls: how many flushes the
44
+ * binding has lived through and whether any bound channel ever flushed a non-zero value. The
45
+ * "silent contract gap" detector (`lintFeedbackNeverWritten`) reads this to flag a body that has
46
+ * been bound for many frames but never actually received a value — it reacts to nothing. Inspection
47
+ * only; never mutated outside `flush()`.
48
+ */
49
+ feedbackActivity(): Array<{
50
+ element: Element;
51
+ flushes: number;
52
+ written: boolean;
53
+ }>;
33
54
  /**
34
55
  * Actual `style.setProperty` calls made during the last `flush()`. Use this (not
35
56
  * `boundVars().length`) to measure real per-frame DOM write cost: off-screen elements with
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,8DAA8D;AAC9D,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA6BzC,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8C;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,mBAAmB,CAAK;IAEhC,4GAA4G;IAC5G,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI;IAI7C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7C,4FAA4F;IAC5F,SAAS,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAIxD;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;IAI5B,kEAAkE;IAClE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IAMlE,iGAAiG;IACjG,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAU5E;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IASlC;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,SAAI,GAAG,IAAI;CA0B3C"}
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,8DAA8D;AAC9D,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA6BzC,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;uGACuG;AACvG,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8C;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,mBAAmB,CAAK;IAEhC,4GAA4G;IAC5G,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI;IAI7C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7C,4FAA4F;IAC5F,SAAS,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAIxD;;;;;;OAMG;IACH,gBAAgB,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAIlF;;;;OAIG;IACH,kBAAkB,IAAI,MAAM;IAI5B,kEAAkE;IAClE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI;IAMlE,iGAAiG;IACjG,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAU5E;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAUlC;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,SAAI,GAAG,IAAI;CA8B3C"}
package/dist/feedback.js CHANGED
@@ -29,6 +29,7 @@ export class FeedbackRegistry {
29
29
  bindings = new Map();
30
30
  direct = new Map();
31
31
  thresholds = [];
32
+ activity = new Map();
32
33
  _cssWritesLastFrame = 0;
33
34
  /** Declare which state keys map to which CSS vars on an element (e.g. `{ density: '--field-density' }`). */
34
35
  bind(element, map) {
@@ -50,6 +51,16 @@ export class FeedbackRegistry {
50
51
  boundVars() {
51
52
  return [...this.bindings].map(([element, map]) => ({ element, vars: Object.values(map) }));
52
53
  }
54
+ /**
55
+ * Per-element runtime feedback activity accumulated across `flush()` calls: how many flushes the
56
+ * binding has lived through and whether any bound channel ever flushed a non-zero value. The
57
+ * "silent contract gap" detector (`lintFeedbackNeverWritten`) reads this to flag a body that has
58
+ * been bound for many frames but never actually received a value — it reacts to nothing. Inspection
59
+ * only; never mutated outside `flush()`.
60
+ */
61
+ feedbackActivity() {
62
+ return [...this.activity].map(([element, a]) => ({ element, flushes: a.flushes, written: a.written }));
63
+ }
53
64
  /**
54
65
  * Actual `style.setProperty` calls made during the last `flush()`. Use this (not
55
66
  * `boundVars().length`) to measure real per-frame DOM write cost: off-screen elements with
@@ -82,6 +93,7 @@ export class FeedbackRegistry {
82
93
  unregister(element) {
83
94
  this.bindings.delete(element);
84
95
  this.direct.delete(element);
96
+ this.activity.delete(element);
85
97
  // splice in reverse so the index arithmetic stays correct as we remove entries
86
98
  for (let i = this.thresholds.length - 1; i >= 0; i--) {
87
99
  if (this.thresholds[i].element === element)
@@ -101,14 +113,20 @@ export class FeedbackRegistry {
101
113
  // layout-wise but still costs a Map lookup + style.setProperty call every frame.
102
114
  if (!el.isConnected) {
103
115
  this.bindings.delete(el);
116
+ this.activity.delete(el);
104
117
  continue;
105
118
  }
119
+ const act = this.activity.get(el) ?? { flushes: 0, written: false };
120
+ act.flushes++;
106
121
  for (const key of Object.keys(map)) {
107
122
  const v = state.get(el, key);
108
123
  if (!v)
109
124
  continue;
125
+ if (v.type === 'number' ? v.value !== 0 : Boolean(v.value))
126
+ act.written = true;
110
127
  this._cssWritesLastFrame += writeVar(el, map[key], v.type === 'number' ? v.value.toFixed(3) : String(v.value ?? ''));
111
128
  }
129
+ this.activity.set(el, act);
112
130
  }
113
131
  for (const [el, vars] of this.direct) {
114
132
  for (const name of Object.keys(vars))
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ export * from './apply-recipe.ts';
27
27
  export * from './field-nav.ts';
28
28
  export * from './bind-data.ts';
29
29
  export * from './browser-host.ts';
30
+ export * from './register-properties.ts';
30
31
  export * from './container-host.ts';
31
32
  export * from './export-dom.ts';
32
33
  export * from './governor.ts';
@@ -35,6 +36,8 @@ export * from './text-bodies.ts';
35
36
  export * from './contours.ts';
36
37
  export * from './thread-overlay.ts';
37
38
  export * from './perf.ts';
39
+ export { attachOffthreadRender, type OffthreadBridgeResult } from './worker/offthread-bridge.ts';
40
+ export * from './x-ray.ts';
38
41
  /** Start the core engine on a canvas with the default browser host — `createField` + `browserHost()`. */
39
42
  export declare function createBrowserField(canvas: HTMLCanvasElement, opts?: Omit<FieldOptions, 'host'>): FieldHandle;
40
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG5F,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAE1B,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAM,GAAG,WAAW,CAEhH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG5F,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACjG,cAAc,YAAY,CAAC;AAE3B,yGAAyG;AACzG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAM,GAAG,WAAW,CAEhH"}
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ export * from "./apply-recipe.js";
28
28
  export * from "./field-nav.js";
29
29
  export * from "./bind-data.js";
30
30
  export * from "./browser-host.js";
31
+ export * from "./register-properties.js";
31
32
  export * from "./container-host.js";
32
33
  export * from "./export-dom.js";
33
34
  export * from "./governor.js";
@@ -36,6 +37,8 @@ export * from "./text-bodies.js";
36
37
  export * from "./contours.js";
37
38
  export * from "./thread-overlay.js";
38
39
  export * from "./perf.js";
40
+ export { attachOffthreadRender } from "./worker/offthread-bridge.js";
41
+ export * from "./x-ray.js";
39
42
  /** Start the core engine on a canvas with the default browser host — `createField` + `browserHost()`. */
40
43
  export function createBrowserField(canvas, opts = {}) {
41
44
  return createField(canvas, { ...opts, host: browserHost() });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAuC,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAE1B,yGAAyG;AACzG,MAAM,UAAU,kBAAkB,CAAC,MAAyB,EAAE,OAAmC,EAAE;IACjG,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAuC,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAA8B,MAAM,8BAA8B,CAAC;AACjG,cAAc,YAAY,CAAC;AAE3B,yGAAyG;AACzG,MAAM,UAAU,kBAAkB,CAAC,MAAyB,EAAE,OAAmC,EAAE;IACjG,OAAO,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC"}
package/dist/lint.d.ts CHANGED
@@ -15,7 +15,7 @@ import type { RelationshipRegistry } from './relationships.ts';
15
15
  import type { VisualBindingRegistry } from './visual-bindings.ts';
16
16
  import type { FrameScheduler } from './schedule.ts';
17
17
  import type { Resolver } from './relationships.ts';
18
- export type LintCode = 'relation-target-missing' | 'visual-orphan' | 'visual-not-hidden' | 'state-unregistered' | 'overlay-without-links' | 'feedback-non-css-var' | 'measurement-off-phase' | 'sink-without-feedback' | 'feedback-vars-unwritten' | 'feedback-writes-unread' | 'feedback-reads-unwritten' | 'feedback-lane-inert' | 'compositing-fill-trap';
18
+ export type LintCode = 'relation-target-missing' | 'visual-orphan' | 'visual-not-hidden' | 'state-unregistered' | 'overlay-without-links' | 'feedback-non-css-var' | 'measurement-off-phase' | 'sink-without-feedback' | 'feedback-vars-unwritten' | 'feedback-writes-unread' | 'feedback-reads-unwritten' | 'feedback-never-written' | 'feedback-lane-inert' | 'compositing-fill-trap';
19
19
  export interface PlatformLintWarning {
20
20
  code: LintCode;
21
21
  severity: 'warning' | 'error';
@@ -73,6 +73,18 @@ export declare function lintOverlayLinks(overlays: OverlayRegistry, relationship
73
73
  * never reports (`lintSinkFeedback`). Pure.
74
74
  */
75
75
  export declare function lintInertFeedback(feedback: FeedbackRegistry): PlatformLintWarning[];
76
+ /** Default flush count after which a still-empty feedback body is considered "never written". */
77
+ export declare const FEEDBACK_NEVER_WRITTEN_FRAMES = 120;
78
+ /**
79
+ * The RUNTIME half of the silent contract gap, the companion to `lintFeedbackWritesUnread` (which is
80
+ * static/CSS-based): a `data-feedback` body that has lived through many `flush()` calls but never once
81
+ * received a non-zero value. The CSS consumer may be wired correctly, yet the body still reacts to
82
+ * nothing — its density (or any bound channel) stays at rest forever, usually because it was never
83
+ * measured, sits outside the field, or no force ever reaches it. Reads `FeedbackRegistry.feedbackActivity()`
84
+ * (accumulated in `flush()`); a body under the threshold is still warming up and is left alone, so this
85
+ * only fires once the field has had a fair chance to write. Pure (reads the registry, never mutates).
86
+ */
87
+ export declare function lintFeedbackNeverWritten(feedback: FeedbackRegistry, afterFrames?: number): PlatformLintWarning[];
76
88
  /** Feedback must write CSS custom properties, not ARIA/attributes — state is not accessibility state. Pure. */
77
89
  export declare function lintFeedbackVars(feedback: FeedbackRegistry): PlatformLintWarning[];
78
90
  /** Off-phase reads recorded by the scheduler (e.g. a measurement during the write phase). */
@@ -89,11 +101,22 @@ export interface PlatformLike {
89
101
  overlays: OverlayRegistry;
90
102
  scheduler: FrameScheduler;
91
103
  }
104
+ /** A pluggable lint rule. Pure: reads only, never mutates the platform or DOM. */
105
+ export interface LintRule {
106
+ readonly id: string;
107
+ run(root: ParentNode, warnings: PlatformLintWarning[]): void;
108
+ }
109
+ /** Register a custom lint rule globally. Returns an unregister function.
110
+ * The rule runs alongside built-ins on every lintPlatform() call.
111
+ */
112
+ export declare function registerLintRule(rule: LintRule): () => void;
92
113
  export interface LintOptions {
93
114
  /** the subtree to scan for relation targets (defaults to the platform root). */
94
115
  root?: ParentNode;
95
116
  /** id resolver for relation targets (defaults to document.getElementById). */
96
117
  resolve?: Resolver;
118
+ /** inline rules to run alongside built-ins for this call only. */
119
+ rules?: LintRule[];
97
120
  }
98
121
  /**
99
122
  * The DPR2 / mix-blend fill trap (#405, #532) — the hardest-won perf lesson, made a guard. A
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,MAAM,QAAQ,GAChB,yBAAyB,GACzB,eAAe,GACf,mBAAmB,GACnB,oBAAoB,GACpB,uBAAuB,GACvB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,GACvB,yBAAyB,GACzB,wBAAwB,GACxB,0BAA0B,GAC1B,wBAAwB,GACxB,qBAAqB,GACrB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,GAAG,mBAAmB,EAAE,CAa9F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAcxE;AAKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAe5E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAkChF;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CA6BlF;AAED,8GAA8G;AAC9G,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,EAAE,CAO/G;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,GAAG,mBAAmB,EAAE,CAKtH;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CAiBnF;AAED,iGAAiG;AACjG,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,WAAW,GAAE,MAAsC,GAClD,mBAAmB,EAAE,CAYvB;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,EAAE,CASlF;AAED,6FAA6F;AAC7F,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,cAAc,GAAG,mBAAmB,EAAE,CAMxF;AAED,sGAAsG;AACtG,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,mBAAmB,EAAE,CAOjF;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,mBAAmB,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,aAAa,EAAE,oBAAoB,CAAC;IACpC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,kFAAkF;AAClF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;CAC9D;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAG3D;AAED,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,kEAAkE;IAClE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAqB3E;AAED,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,GAAE,WAAgB,GAAG,mBAAmB,EAAE,CAwBlG"}
package/dist/lint.js CHANGED
@@ -215,6 +215,31 @@ export function lintInertFeedback(feedback) {
215
215
  }
216
216
  return out;
217
217
  }
218
+ /** Default flush count after which a still-empty feedback body is considered "never written". */
219
+ export const FEEDBACK_NEVER_WRITTEN_FRAMES = 120;
220
+ /**
221
+ * The RUNTIME half of the silent contract gap, the companion to `lintFeedbackWritesUnread` (which is
222
+ * static/CSS-based): a `data-feedback` body that has lived through many `flush()` calls but never once
223
+ * received a non-zero value. The CSS consumer may be wired correctly, yet the body still reacts to
224
+ * nothing — its density (or any bound channel) stays at rest forever, usually because it was never
225
+ * measured, sits outside the field, or no force ever reaches it. Reads `FeedbackRegistry.feedbackActivity()`
226
+ * (accumulated in `flush()`); a body under the threshold is still warming up and is left alone, so this
227
+ * only fires once the field has had a fair chance to write. Pure (reads the registry, never mutates).
228
+ */
229
+ export function lintFeedbackNeverWritten(feedback, afterFrames = FEEDBACK_NEVER_WRITTEN_FRAMES) {
230
+ const out = [];
231
+ for (const { element, flushes, written } of feedback.feedbackActivity()) {
232
+ if (written || flushes < afterFrames)
233
+ continue;
234
+ out.push({
235
+ code: 'feedback-never-written',
236
+ severity: 'warning',
237
+ element,
238
+ message: `data-feedback body has been bound for ${flushes} frames but never received a non-zero value — the reciprocal loop is inert (it is likely unmeasured, outside the field, or no force reaches it)`,
239
+ });
240
+ }
241
+ return out;
242
+ }
218
243
  /** Feedback must write CSS custom properties, not ARIA/attributes — state is not accessibility state. Pure. */
219
244
  export function lintFeedbackVars(feedback) {
220
245
  const out = [];
@@ -243,6 +268,14 @@ export function lintVisuals(visuals) {
243
268
  element: w.visual,
244
269
  }));
245
270
  }
271
+ const _customRules = new Map();
272
+ /** Register a custom lint rule globally. Returns an unregister function.
273
+ * The rule runs alongside built-ins on every lintPlatform() call.
274
+ */
275
+ export function registerLintRule(rule) {
276
+ _customRules.set(rule.id, rule);
277
+ return () => { _customRules.delete(rule.id); };
278
+ }
246
279
  /**
247
280
  * The DPR2 / mix-blend fill trap (#405, #532) — the hardest-won perf lesson, made a guard. A
248
281
  * full-viewport `mix-blend-mode` canvas re-composites the WHOLE screen every frame the layer below
@@ -280,7 +313,7 @@ export function lintCompositingPerf(root) {
280
313
  export function lintPlatform(platform, opts = {}) {
281
314
  const root = opts.root ?? platform.root;
282
315
  const resolve = opts.resolve ?? ((id) => (typeof document !== 'undefined' ? document.getElementById(id) : null));
283
- return [
316
+ const warnings = [
284
317
  ...lintRelationTargets(root, resolve),
285
318
  ...lintCompositingPerf(root),
286
319
  ...lintSinkFeedback(root),
@@ -291,8 +324,14 @@ export function lintPlatform(platform, opts = {}) {
291
324
  ...lintOverlayLinks(platform.overlays, platform.relationships),
292
325
  ...lintFeedbackVars(platform.feedback),
293
326
  ...lintInertFeedback(platform.feedback),
327
+ ...lintFeedbackNeverWritten(platform.feedback),
294
328
  ...lintVisuals(platform.visuals),
295
329
  ...lintSchedulerViolations(platform.scheduler),
296
330
  ];
331
+ // pluggable rules — inline (opts.rules) + globally registered
332
+ const extraRules = [...(opts?.rules ?? []), ..._customRules.values()];
333
+ for (const rule of extraRules)
334
+ rule.run(root, warnings);
335
+ return warnings;
297
336
  }
298
337
  //# sourceMappingURL=lint.js.map
package/dist/lint.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../src/lint.ts"],"names":[],"mappings":"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"}
package/dist/perf.d.ts CHANGED
@@ -23,15 +23,30 @@
23
23
  * - fps: `Math.round(1000 / medianMs)` over the current window; `null` while empty.
24
24
  * - `frames`: total clean deltas ever counted (not capped by the window).
25
25
  *
26
- * Pure and host-driven by design: NO `requestAnimationFrame` of its own (callers feed their
27
- * loop's timestamps) and NO PerformanceObserver — the LoAF / long-task split stays page-side
28
- * in this slice (the DataConsole keeps its own observer; a platform LoAF lane is future work).
26
+ * Frame timing is host-driven by design: NO `requestAnimationFrame` of its own (callers feed
27
+ * their loop's timestamps). The LoAF / long-task lane is the one optional exception — opt in with
28
+ * `{ loaf: true }` and the meter attaches a `PerformanceObserver`, mirroring the DataConsole's
29
+ * own observer byte-for-byte:
30
+ * - observes `'long-animation-frame'` (LoAF) when available, else falls back to `'longtask'`.
31
+ * - counts only entries with `duration >= 50` ms (the long-task / LoAF threshold).
32
+ * - `loafCount` is the running tally of those entries; `tbtMs` sums their blocking time as
33
+ * `Σ max(0, duration − 50)` — Total Blocking Time, the DataConsole's exact formula.
34
+ * - feature-detected and fully graceful: where `PerformanceObserver` (or the entry type) is
35
+ * unsupported the lane is a silent no-op (`loafCount` / `tbtMs` stay 0). Without `loaf`,
36
+ * the meter is pure (no observer, no globals) — existing callers are unchanged.
37
+ * Call `dispose()` when done to disconnect the observer (a no-op when none was attached).
29
38
  */
30
39
  export interface FieldPerfOptions {
31
40
  /** rolling delta-window size (default 180 — the DataConsole's ~3 s at 60 Hz). Min 1. */
32
41
  window?: number;
33
42
  /** number of clean deltas used to detect the frame budget (default 30); the budget is their median. Min 1. */
34
43
  budgetSeed?: number;
44
+ /**
45
+ * Observe Long Animation Frames / long tasks via `PerformanceObserver` (default false). When
46
+ * enabled and supported, `snapshot()` reports `loafCount` / `tbtMs`; when unsupported it is a
47
+ * silent no-op. Leave off to keep the meter pure (no observer, no globals).
48
+ */
49
+ loaf?: boolean;
35
50
  }
36
51
  export interface FieldPerfSnapshot {
37
52
  /** `Math.round(1000 / medianMs)`; `null` until a delta exists. */
@@ -48,14 +63,26 @@ export interface FieldPerfSnapshot {
48
63
  dropped: number;
49
64
  /** total clean deltas counted since creation/reset (not capped by the window). */
50
65
  frames: number;
66
+ /**
67
+ * Long Animation Frames / long tasks (`duration >= 50` ms) observed since creation/reset.
68
+ * Always 0 unless `{ loaf: true }` was set and the observer is supported.
69
+ */
70
+ loafCount: number;
71
+ /**
72
+ * Total Blocking Time (ms): `Σ max(0, duration − 50)` over the observed LoAF / long-task
73
+ * entries. Always 0 unless the LoAF lane is enabled and supported.
74
+ */
75
+ tbtMs: number;
51
76
  }
52
77
  export interface FieldPerf {
53
78
  /** Feed one rAF timestamp (ms). Deltas are computed internally; gaps > 500 ms are ignored (discontinuity). */
54
79
  feed(frameTs: number): void;
55
80
  /** Read the current numbers (pure — no layout, no globals). */
56
81
  snapshot(): FieldPerfSnapshot;
57
- /** Forget everything: window, seed, budget, counters, and the last timestamp. */
82
+ /** Forget everything: window, seed, budget, counters, the last timestamp, and the LoAF tally. */
58
83
  reset(): void;
84
+ /** Disconnect the LoAF / long-task observer (no-op when the lane is off or unsupported). */
85
+ dispose(): void;
59
86
  }
60
87
  /** Create a frame-duration meter. Feed it rAF timestamps; read `snapshot()` whenever. */
61
88
  export declare function createFieldPerf(opts?: FieldPerfOptions): FieldPerf;
@@ -1 +1 @@
1
- {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8GAA8G;IAC9G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,8GAA8G;IAC9G,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,IAAI,iBAAiB,CAAC;IAC9B,iFAAiF;IACjF,KAAK,IAAI,IAAI,CAAC;CACf;AAYD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,GAAE,gBAAqB,GAAG,SAAS,CAyDtE"}
1
+ {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8GAA8G;IAC9G,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8FAA8F;IAC9F,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,8GAA8G;IAC9G,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,IAAI,iBAAiB,CAAC;IAC9B,iGAAiG;IACjG,KAAK,IAAI,IAAI,CAAC;IACd,4FAA4F;IAC5F,OAAO,IAAI,IAAI,CAAC;CACjB;AA4CD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,GAAE,gBAAqB,GAAG,SAAS,CA2EtE"}
package/dist/perf.js CHANGED
@@ -23,12 +23,49 @@
23
23
  * - fps: `Math.round(1000 / medianMs)` over the current window; `null` while empty.
24
24
  * - `frames`: total clean deltas ever counted (not capped by the window).
25
25
  *
26
- * Pure and host-driven by design: NO `requestAnimationFrame` of its own (callers feed their
27
- * loop's timestamps) and NO PerformanceObserver — the LoAF / long-task split stays page-side
28
- * in this slice (the DataConsole keeps its own observer; a platform LoAF lane is future work).
26
+ * Frame timing is host-driven by design: NO `requestAnimationFrame` of its own (callers feed
27
+ * their loop's timestamps). The LoAF / long-task lane is the one optional exception — opt in with
28
+ * `{ loaf: true }` and the meter attaches a `PerformanceObserver`, mirroring the DataConsole's
29
+ * own observer byte-for-byte:
30
+ * - observes `'long-animation-frame'` (LoAF) when available, else falls back to `'longtask'`.
31
+ * - counts only entries with `duration >= 50` ms (the long-task / LoAF threshold).
32
+ * - `loafCount` is the running tally of those entries; `tbtMs` sums their blocking time as
33
+ * `Σ max(0, duration − 50)` — Total Blocking Time, the DataConsole's exact formula.
34
+ * - feature-detected and fully graceful: where `PerformanceObserver` (or the entry type) is
35
+ * unsupported the lane is a silent no-op (`loafCount` / `tbtMs` stay 0). Without `loaf`,
36
+ * the meter is pure (no observer, no globals) — existing callers are unchanged.
37
+ * Call `dispose()` when done to disconnect the observer (a no-op when none was attached).
29
38
  */
30
39
  /** A gap above this (ms) is a discontinuity — tab switch / sleep — and is skipped, not measured. */
31
40
  const DISCONTINUITY_MS = 500;
41
+ /** LoAF / long-task threshold (ms): entries at or above this are counted; the TBT floor too. */
42
+ const LOAF_MS = 50;
43
+ /**
44
+ * Attach a LoAF / long-task observer, feeding each qualifying entry to `onEntry`. Tries
45
+ * `'long-animation-frame'` first, falls back to `'longtask'`. Returns a disconnect fn, or a
46
+ * no-op where `PerformanceObserver` (or both entry types) is unsupported — fully graceful.
47
+ */
48
+ function observeLoaf(onEntry) {
49
+ const PO = globalThis.PerformanceObserver;
50
+ if (typeof PO !== 'function')
51
+ return () => { };
52
+ for (const type of ['long-animation-frame', 'longtask']) {
53
+ try {
54
+ const obs = new PO((list) => {
55
+ for (const e of list.getEntries()) {
56
+ if (e.duration >= LOAF_MS)
57
+ onEntry(e);
58
+ }
59
+ });
60
+ obs.observe({ type, buffered: true });
61
+ return () => obs.disconnect();
62
+ }
63
+ catch {
64
+ // entry type unsupported in this engine — try the next, then give up gracefully
65
+ }
66
+ }
67
+ return () => { };
68
+ }
32
69
  /** Nearest-rank-by-floor percentile on a copy (the DataConsole's `pct`). `null` when empty. */
33
70
  function pct(arr, p) {
34
71
  if (!arr.length)
@@ -46,6 +83,15 @@ export function createFieldPerf(opts = {}) {
46
83
  let budget = null;
47
84
  let dropped = 0;
48
85
  let frames = 0;
86
+ let loafCount = 0;
87
+ let tbtMs = 0;
88
+ // LoAF / long-task lane — opt-in, feature-detected, graceful no-op where unsupported.
89
+ const disconnectLoaf = opts.loaf
90
+ ? observeLoaf((e) => {
91
+ loafCount++;
92
+ tbtMs += Math.max(0, e.duration - LOAF_MS);
93
+ })
94
+ : () => { };
49
95
  const feed = (frameTs) => {
50
96
  if (lastTs === null) {
51
97
  lastTs = frameTs;
@@ -79,6 +125,8 @@ export function createFieldPerf(opts = {}) {
79
125
  p99Ms: pct(deltas, 99),
80
126
  dropped,
81
127
  frames,
128
+ loafCount,
129
+ tbtMs,
82
130
  };
83
131
  };
84
132
  const reset = () => {
@@ -88,7 +136,12 @@ export function createFieldPerf(opts = {}) {
88
136
  budget = null;
89
137
  dropped = 0;
90
138
  frames = 0;
139
+ loafCount = 0;
140
+ tbtMs = 0;
141
+ };
142
+ const dispose = () => {
143
+ disconnectLoaf();
91
144
  };
92
- return { feed, snapshot, reset };
145
+ return { feed, snapshot, reset, dispose };
93
146
  }
94
147
  //# sourceMappingURL=perf.js.map
package/dist/perf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * registerFieldProperties — register the engine's field-density channels as typed, compositor-
3
+ * interpolable CSS custom properties via `CSS.registerProperty`. Once a property is registered with
4
+ * `syntax: '<number>'`, the browser can interpolate it on the compositor thread, so consumers can
5
+ * `transition`/`animate` `var(--field-density)` (and its compact alias `var(--d)`) smoothly instead
6
+ * of getting an all-or-nothing swap (untyped custom properties are treated as `<custom-ident>` and
7
+ * jump rather than tween).
8
+ *
9
+ * Called once at browser-host boot. Feature-detected (`CSS.registerProperty` is not universal) and
10
+ * idempotent — registering the same property twice throws a `SyntaxError`, so each registration is
11
+ * guarded in its own try/catch and a module-level flag short-circuits repeat calls.
12
+ */
13
+ /**
14
+ * Register `--field-density` and its compact alias `--d` as typed `<number>` custom properties so
15
+ * consumers can transition/animate them on the compositor. Safe to call repeatedly: a no-op once
16
+ * registered, when `CSS.registerProperty` is unavailable, or when a property is already registered
17
+ * (the per-property throw is swallowed). Returns the names actually registered by this call.
18
+ */
19
+ export declare function registerFieldProperties(): string[];
20
+ /**
21
+ * Reset the module-level "already registered" latch. Test-only seam — there is no production reason
22
+ * to re-run registration within a single document. Underscore-prefixed; not part of the frozen API.
23
+ */
24
+ export declare function _resetFieldPropertiesForTest(): void;
25
+ //# sourceMappingURL=register-properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-properties.d.ts","sourceRoot":"","sources":["../src/register-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAiBlD;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * registerFieldProperties — register the engine's field-density channels as typed, compositor-
3
+ * interpolable CSS custom properties via `CSS.registerProperty`. Once a property is registered with
4
+ * `syntax: '<number>'`, the browser can interpolate it on the compositor thread, so consumers can
5
+ * `transition`/`animate` `var(--field-density)` (and its compact alias `var(--d)`) smoothly instead
6
+ * of getting an all-or-nothing swap (untyped custom properties are treated as `<custom-ident>` and
7
+ * jump rather than tween).
8
+ *
9
+ * Called once at browser-host boot. Feature-detected (`CSS.registerProperty` is not universal) and
10
+ * idempotent — registering the same property twice throws a `SyntaxError`, so each registration is
11
+ * guarded in its own try/catch and a module-level flag short-circuits repeat calls.
12
+ */
13
+ /** The density channels written by the feedback registry that benefit from typed interpolation. */
14
+ const DENSITY_PROPERTIES = ['--field-density', '--d'];
15
+ let registered = false;
16
+ /**
17
+ * Register `--field-density` and its compact alias `--d` as typed `<number>` custom properties so
18
+ * consumers can transition/animate them on the compositor. Safe to call repeatedly: a no-op once
19
+ * registered, when `CSS.registerProperty` is unavailable, or when a property is already registered
20
+ * (the per-property throw is swallowed). Returns the names actually registered by this call.
21
+ */
22
+ export function registerFieldProperties() {
23
+ if (registered)
24
+ return [];
25
+ registered = true;
26
+ const css = globalThis.CSS;
27
+ if (!css || typeof css.registerProperty !== 'function')
28
+ return [];
29
+ const done = [];
30
+ for (const name of DENSITY_PROPERTIES) {
31
+ try {
32
+ css.registerProperty({ name, syntax: '<number>', inherits: true, initialValue: '0' });
33
+ done.push(name);
34
+ }
35
+ catch {
36
+ // Already registered (registering twice throws) or rejected by the engine — graceful no-op.
37
+ }
38
+ }
39
+ return done;
40
+ }
41
+ /**
42
+ * Reset the module-level "already registered" latch. Test-only seam — there is no production reason
43
+ * to re-run registration within a single document. Underscore-prefixed; not part of the frozen API.
44
+ */
45
+ export function _resetFieldPropertiesForTest() {
46
+ registered = false;
47
+ }
48
+ //# sourceMappingURL=register-properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-properties.js","sourceRoot":"","sources":["../src/register-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,mGAAmG;AACnG,MAAM,kBAAkB,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAU,CAAC;AAE/D,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB;IACrC,IAAI,UAAU;QAAE,OAAO,EAAE,CAAC;IAC1B,UAAU,GAAG,IAAI,CAAC;IAElB,MAAM,GAAG,GAAI,UAAiF,CAAC,GAAG,CAAC;IACnG,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC;IAElE,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;YACtF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,4FAA4F;QAC9F,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,4BAA4B;IAC1C,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC"}
@@ -26,9 +26,10 @@
26
26
  * - `annotate()` is idempotent — re-calling disposes the previous span set first, then re-measures.
27
27
  * - The engine picks the spans up on its next scan: call `field.rescan()` (or re-run the platform
28
28
  * scan) after `annotate()` and after disposing.
29
- * - Resize/reflow honesty: the spans are a static snapshot in page coordinates. Callers re-call
30
- * `annotate()` (and rescan) when the text reflows — wiring a ResizeObserver is deliberately NOT
31
- * this slice's job and is noted as the follow-up.
29
+ * - Resize/reflow honesty: the spans are a static snapshot in page coordinates. By default callers
30
+ * re-call `annotate()` (and rescan) when the text reflows. Opt into `observe: true` to wire a
31
+ * debounced `ResizeObserver` on the source that re-measures the spans automatically on resize;
32
+ * the observer is torn down by the same disposer that removes the spans.
32
33
  * - Reduced motion is irrelevant here: this is geometry only; it animates nothing.
33
34
  * - SSR-safe: no module-top DOM access; everything reaches the DOM through the passed element's
34
35
  * `ownerDocument`.
@@ -46,13 +47,23 @@ export interface TextBodiesOptions {
46
47
  body?: 'wall' | 'shear';
47
48
  /** `data-strength` written on each span. Default 1. */
48
49
  strength?: number;
50
+ /**
51
+ * Re-annotate automatically when the source resizes. When `true` (or a debounce in ms), `annotate()`
52
+ * wires a debounced `ResizeObserver` on the source; each resize disposes the previous spans and
53
+ * re-measures fresh boxes, so the boundary stays glued to the reflowed text. Off by default (the
54
+ * spans remain a one-time snapshot). The observer is registered on the source's `ResizeObserver`
55
+ * global; in environments without one (SSR / old runtimes) it's silently skipped. Cleaned up by the
56
+ * disposer `annotate()` returns. Default debounce `100`ms when `observe: true`.
57
+ */
58
+ observe?: boolean | number;
49
59
  }
50
60
  export interface TextBodiesHandle {
51
61
  /** The boxes measured at creation time (viewport coordinates, zero-size fragments dropped). */
52
62
  boxes: DOMRect[];
53
63
  /**
54
- * Create the boundary spans (re-measuring fresh boxes) and return a disposer that removes them.
55
- * Idempotent: calling again first disposes the previous set.
64
+ * Create the boundary spans (re-measuring fresh boxes) and return a disposer that removes them
65
+ * (and, when `observe` is set, disconnects the ResizeObserver). Idempotent: calling again first
66
+ * disposes the previous set.
56
67
  */
57
68
  annotate(): () => void;
58
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"text-bodies.d.ts","sourceRoot":"","sources":["../src/text-bodies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,8GAA8G;IAC9G,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;;OAGG;IACH,QAAQ,IAAI,MAAM,IAAI,CAAC;CACxB;AA2DD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CA0D1F"}
1
+ {"version":3,"file":"text-bodies.d.ts","sourceRoot":"","sources":["../src/text-bodies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,MAAM,MAAM,qBAAqB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,8GAA8G;IAC9G,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;;;OAIG;IACH,QAAQ,IAAI,MAAM,IAAI,CAAC;CACxB;AA2DD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CA0F1F"}
@@ -26,9 +26,10 @@
26
26
  * - `annotate()` is idempotent — re-calling disposes the previous span set first, then re-measures.
27
27
  * - The engine picks the spans up on its next scan: call `field.rescan()` (or re-run the platform
28
28
  * scan) after `annotate()` and after disposing.
29
- * - Resize/reflow honesty: the spans are a static snapshot in page coordinates. Callers re-call
30
- * `annotate()` (and rescan) when the text reflows — wiring a ResizeObserver is deliberately NOT
31
- * this slice's job and is noted as the follow-up.
29
+ * - Resize/reflow honesty: the spans are a static snapshot in page coordinates. By default callers
30
+ * re-call `annotate()` (and rescan) when the text reflows. Opt into `observe: true` to wire a
31
+ * debounced `ResizeObserver` on the source that re-measures the spans automatically on resize;
32
+ * the observer is torn down by the same disposer that removes the spans.
32
33
  * - Reduced motion is irrelevant here: this is geometry only; it animates nothing.
33
34
  * - SSR-safe: no module-top DOM access; everything reaches the DOM through the passed element's
34
35
  * `ownerDocument`.
@@ -106,9 +107,11 @@ export function textBodies(el, opts = {}) {
106
107
  const granularity = opts.granularity ?? 'word';
107
108
  const body = opts.body ?? 'shear';
108
109
  const strength = opts.strength ?? 1;
110
+ const observe = opts.observe ?? false;
111
+ const observeDelay = typeof observe === 'number' ? observe : 100;
109
112
  let disposeCurrent = null;
110
- const annotate = () => {
111
- disposeCurrent?.(); // idempotent: one live span set per handle
113
+ /** Build one span set from a fresh measurement and return its remover. */
114
+ const render = () => {
112
115
  const doc = el.ownerDocument;
113
116
  const view = doc.defaultView;
114
117
  const sx = view?.scrollX ?? 0;
@@ -146,8 +149,36 @@ export function textBodies(el, opts = {}) {
146
149
  container.appendChild(span);
147
150
  }
148
151
  doc.body.appendChild(container);
152
+ return () => container.parentNode?.removeChild(container);
153
+ };
154
+ const annotate = () => {
155
+ disposeCurrent?.(); // idempotent: one live span set per handle
156
+ let removeSpans = render();
157
+ // Opt-in: re-measure on source resize, debounced, so the boundary tracks the reflowed text.
158
+ // Skipped where ResizeObserver is unavailable (SSR / older runtimes) — the snapshot still stands.
159
+ let ro = null;
160
+ let timer = null;
161
+ const RO = el.ownerDocument.defaultView
162
+ ?.ResizeObserver;
163
+ if (observe && typeof RO === 'function') {
164
+ ro = new RO(() => {
165
+ if (timer != null)
166
+ clearTimeout(timer);
167
+ timer = setTimeout(() => {
168
+ timer = null;
169
+ removeSpans();
170
+ removeSpans = render();
171
+ }, observeDelay);
172
+ });
173
+ ro.observe(el);
174
+ }
149
175
  const dispose = () => {
150
- container.parentNode?.removeChild(container);
176
+ if (timer != null)
177
+ clearTimeout(timer);
178
+ timer = null;
179
+ ro?.disconnect();
180
+ ro = null;
181
+ removeSpans();
151
182
  if (disposeCurrent === dispose)
152
183
  disposeCurrent = null;
153
184
  };
@@ -1 +1 @@
1
- {"version":3,"file":"text-bodies.js","sourceRoot":"","sources":["../src/text-bodies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"text-bodies.js","sourceRoot":"","sources":["../src/text-bodies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Creates a Worker-backed render bridge. Call attachOffthreadRender(field, canvas) to
3
+ * transfer the canvas to the worker and drive it from field.readParticles() each frame.
4
+ * Returns a teardown function.
5
+ *
6
+ * Requires OffscreenCanvas support (Chrome 69+, Firefox 105+). Falls back gracefully
7
+ * (returns null) when not available, so callers can fall back to main-thread render.
8
+ */
9
+ import type { FieldHandle } from '@fundamental-engine/core';
10
+ export interface OffthreadBridgeResult {
11
+ teardown: () => void;
12
+ supported: boolean;
13
+ }
14
+ export declare function attachOffthreadRender(field: FieldHandle, canvas: HTMLCanvasElement, opts?: {
15
+ dpr?: number;
16
+ }): OffthreadBridgeResult;
17
+ //# sourceMappingURL=offthread-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offthread-bridge.d.ts","sourceRoot":"","sources":["../../src/worker/offthread-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,iBAAiB,EACzB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1B,qBAAqB,CAqDvB"}
@@ -0,0 +1,47 @@
1
+ /** Particle buffer stride: [x, y, z, heat, size] per particle. */
2
+ const PARTICLE_STRIDE = 5;
3
+ export function attachOffthreadRender(field, canvas, opts = {}) {
4
+ // Feature-detect OffscreenCanvas
5
+ if (typeof OffscreenCanvas === 'undefined' || !canvas.transferControlToOffscreen) {
6
+ return { teardown: () => { }, supported: false };
7
+ }
8
+ const dpr = opts.dpr ?? window.devicePixelRatio ?? 1;
9
+ const offscreen = canvas.transferControlToOffscreen();
10
+ const worker = new Worker(new URL('./render-worker.js', import.meta.url), { type: 'module' });
11
+ worker.postMessage({ type: 'init', canvas: offscreen }, [offscreen]);
12
+ let frameN = 0;
13
+ let pending = false;
14
+ let raf = null;
15
+ // Shared particle buffer — allocated once, grown if needed
16
+ let buf = new Float32Array(1000 * PARTICLE_STRIDE);
17
+ function tick() {
18
+ raf = requestAnimationFrame(tick);
19
+ if (pending)
20
+ return; // worker still rendering previous frame
21
+ const n = field.particleCount();
22
+ if (n * PARTICLE_STRIDE > buf.length)
23
+ buf = new Float32Array(n * PARTICLE_STRIDE * 2);
24
+ field.readParticles(buf);
25
+ pending = true;
26
+ worker.postMessage({
27
+ type: 'frame',
28
+ particles: buf.slice(0, n * PARTICLE_STRIDE),
29
+ count: n,
30
+ W: canvas.width / dpr,
31
+ H: canvas.height / dpr,
32
+ dpr,
33
+ frameN: frameN++,
34
+ });
35
+ }
36
+ worker.addEventListener('message', () => { pending = false; });
37
+ tick();
38
+ return {
39
+ supported: true,
40
+ teardown: () => {
41
+ if (raf != null)
42
+ cancelAnimationFrame(raf);
43
+ worker.terminate();
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=offthread-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offthread-bridge.js","sourceRoot":"","sources":["../../src/worker/offthread-bridge.ts"],"names":[],"mappings":"AAUA,kEAAkE;AAClE,MAAM,eAAe,GAAG,CAAC,CAAC;AAO1B,MAAM,UAAU,qBAAqB,CACnC,KAAkB,EAClB,MAAyB,EACzB,OAAyB,EAAE;IAE3B,iCAAiC;IACjC,IAAI,OAAO,eAAe,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE,CAAC;QACjF,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,MAAM,CAAC,0BAA0B,EAAE,CAAC;IAEtD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAC9C,EAAE,IAAI,EAAE,QAAQ,EAAE,CACnB,CAAC;IAEF,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,SAAoC,CAAC,CAAC,CAAC;IAEhG,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,GAAG,GAAkB,IAAI,CAAC;IAE9B,2DAA2D;IAC3D,IAAI,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,GAAG,eAAe,CAAC,CAAC;IAEnD,SAAS,IAAI;QACX,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,OAAO;YAAE,OAAO,CAAC,wCAAwC;QAE7D,MAAM,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,eAAe,GAAG,GAAG,CAAC,MAAM;YAAE,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC;QACtF,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAEzB,OAAO,GAAG,IAAI,CAAC;QACf,MAAM,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC;YAC5C,KAAK,EAAE,CAAC;YACR,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,GAAG;YACrB,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,GAAG;YACtB,GAAG;YACH,MAAM,EAAE,MAAM,EAAE;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC;IAEP,OAAO;QACL,SAAS,EAAE,IAAI;QACf,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,GAAG,IAAI,IAAI;gBAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Off-main-thread render worker. Receives particle data each frame via postMessage,
3
+ * draws to an OffscreenCanvas using the canvas2d API.
4
+ * Protocol: main → worker: { type:'frame', particles: Float32Array, count: number,
5
+ * W: number, H: number, dpr: number, frameN: number }
6
+ * worker → main: { type:'done', frameN: number }
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=render-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-worker.d.ts","sourceRoot":"","sources":["../../src/worker/render-worker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Off-main-thread render worker. Receives particle data each frame via postMessage,
3
+ * draws to an OffscreenCanvas using the canvas2d API.
4
+ * Protocol: main → worker: { type:'frame', particles: Float32Array, count: number,
5
+ * W: number, H: number, dpr: number, frameN: number }
6
+ * worker → main: { type:'done', frameN: number }
7
+ */
8
+ let ctx = null;
9
+ self.addEventListener('message', (e) => {
10
+ const msg = e.data;
11
+ if (msg.type === 'init') {
12
+ ctx = msg.canvas.getContext('2d');
13
+ return;
14
+ }
15
+ if (msg.type === 'frame' && ctx) {
16
+ const { particles, count, W, H, dpr, frameN, accent } = msg;
17
+ ctx.clearRect(0, 0, W * dpr, H * dpr);
18
+ ctx.save();
19
+ ctx.scale(dpr, dpr);
20
+ // draw particles: stride 5 [x, y, z, heat, size]
21
+ for (let i = 0; i < count; i++) {
22
+ const base = i * 5;
23
+ const x = particles[base];
24
+ const y = particles[base + 1];
25
+ const heat = particles[base + 3];
26
+ const size = particles[base + 4];
27
+ const alpha = 0.4 + heat * 0.6;
28
+ const radius = Math.max(1, size);
29
+ ctx.beginPath();
30
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
31
+ // simple heat colour: cool = accent, hot = white
32
+ const r = Math.round(80 + heat * 175);
33
+ const g = Math.round(120 + heat * 135);
34
+ const b = Math.round(255 - heat * 80);
35
+ ctx.fillStyle = `rgba(${r},${g},${b},${alpha.toFixed(2)})`;
36
+ ctx.fill();
37
+ }
38
+ ctx.restore();
39
+ self.postMessage({ type: 'done', frameN });
40
+ }
41
+ });
42
+ export {};
43
+ //# sourceMappingURL=render-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-worker.js","sourceRoot":"","sources":["../../src/worker/render-worker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,IAAI,GAAG,GAA6C,IAAI,CAAC;AAEzD,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAe,EAAE,EAAE;IACnD,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;IACnB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACxB,GAAG,GAAI,GAAG,CAAC,MAA0B,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,EAAE,CAAC;QAChC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAC5D,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;QACtC,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACpB,iDAAiD;QACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,GAAG,CAAC,CAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,GAAG,CAAC,CAAE,CAAC;YAClC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,GAAG,CAAC,CAAE,CAAC;YAClC,MAAM,KAAK,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACjC,GAAG,CAAC,SAAS,EAAE,CAAC;YAChB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACtC,iDAAiD;YACjD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;YACtC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;YACtC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;YAC3D,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;QACD,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * X-Ray: press the hotkey (default '?') on any page to reveal a live field readout —
3
+ * active bodies, particle count, energy snapshot, and force vector under the cursor.
4
+ * mountXRay(field, host, opts?) returns a teardown function.
5
+ */
6
+ import type { FieldHandle } from '@fundamental-engine/core';
7
+ export interface XRayOptions {
8
+ /** Key that toggles the overlay. Default '?' */
9
+ hotkey?: string;
10
+ /** Corner to anchor the panel. Default 'bottom-right' */
11
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
12
+ }
13
+ export declare function mountXRay(field: FieldHandle, container: ParentNode & EventTarget, opts?: XRayOptions): () => void;
14
+ //# sourceMappingURL=x-ray.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-ray.d.ts","sourceRoot":"","sources":["../src/x-ray.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;CACtE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,GAAG,WAAW,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,IAAI,CAiErH"}
package/dist/x-ray.js ADDED
@@ -0,0 +1,66 @@
1
+ export function mountXRay(field, container, opts = {}) {
2
+ const hotkey = opts.hotkey ?? '?';
3
+ const pos = opts.position ?? 'bottom-right';
4
+ let panel = null;
5
+ let rafId = null;
6
+ let cursorX = 0;
7
+ let cursorY = 0;
8
+ function positionStyle() {
9
+ const [v, h] = pos.split('-');
10
+ return `position:fixed;${v}:16px;${h}:16px;z-index:99999;`;
11
+ }
12
+ function tick() {
13
+ if (!panel)
14
+ return;
15
+ const n = field.particleCount();
16
+ const sample = field.sample?.(cursorX, cursorY);
17
+ const energy = field.energy?.();
18
+ panel.innerHTML = `
19
+ <div style="font:11px/1.4 monospace;color:#e2e8f0;padding:12px 14px;min-width:220px">
20
+ <div style="color:#a0c4ff;font-weight:700;margin-bottom:8px;letter-spacing:.04em">⊕ FIELD X-RAY</div>
21
+ <div>particles <b style="color:#ffd166">${n}</b></div>
22
+ ${energy ? `<div>kinetic <b style="color:#ffd166">${energy.kinetic.toFixed(3)}</b> thermal <b style="color:#ffd166">${energy.thermal.toFixed(3)}</b></div>` : ''}
23
+ ${sample ? `<div>force @ cursor fx <b style="color:#06d6a0">${sample.x.toFixed(3)}</b> fy <b style="color:#06d6a0">${sample.y.toFixed(3)}</b></div>` : ''}
24
+ <div style="margin-top:6px;color:#718096;font-size:10px">press ${hotkey} to close · move cursor for force probe</div>
25
+ </div>
26
+ `;
27
+ rafId = requestAnimationFrame(tick);
28
+ }
29
+ function open() {
30
+ if (panel)
31
+ return;
32
+ panel = document.createElement('div');
33
+ panel.setAttribute('data-field-xray', '');
34
+ panel.style.cssText = positionStyle() + 'background:rgba(10,15,28,.88);border:1px solid rgba(160,196,255,.18);border-radius:10px;backdrop-filter:blur(12px);box-shadow:0 8px 32px rgba(0,0,0,.5);';
35
+ document.body.appendChild(panel);
36
+ tick();
37
+ }
38
+ function close() {
39
+ if (rafId != null) {
40
+ cancelAnimationFrame(rafId);
41
+ rafId = null;
42
+ }
43
+ panel?.remove();
44
+ panel = null;
45
+ }
46
+ function onKey(e) {
47
+ const key = e.key;
48
+ if (key === hotkey) {
49
+ panel ? close() : open();
50
+ }
51
+ if (key === 'Escape')
52
+ close();
53
+ }
54
+ function onMove(e) {
55
+ cursorX = e.clientX;
56
+ cursorY = e.clientY;
57
+ }
58
+ container.addEventListener('keydown', onKey);
59
+ container.addEventListener('mousemove', onMove);
60
+ return () => {
61
+ close();
62
+ container.removeEventListener('keydown', onKey);
63
+ container.removeEventListener('mousemove', onMove);
64
+ };
65
+ }
66
+ //# sourceMappingURL=x-ray.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-ray.js","sourceRoot":"","sources":["../src/x-ray.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fundamental-engine/dom",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "The platform-adjacent layer for Fundamental — native-first registries for measurement, semantic state, feedback, relationships, visual-semantic bindings, and overlays. The browser primitives Fundamental wishes existed, built on the ones it has.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,7 +46,7 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@fundamental-engine/core": "0.8.0"
49
+ "@fundamental-engine/core": "0.9.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "typescript": "^5.9.3"