@fundamental-engine/dom 0.7.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 (44) 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/container-host.d.ts +12 -0
  5. package/dist/container-host.d.ts.map +1 -0
  6. package/dist/container-host.js +60 -0
  7. package/dist/container-host.js.map +1 -0
  8. package/dist/feedback.d.ts +21 -0
  9. package/dist/feedback.d.ts.map +1 -1
  10. package/dist/feedback.js +18 -0
  11. package/dist/feedback.js.map +1 -1
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/lint.d.ts +55 -1
  17. package/dist/lint.d.ts.map +1 -1
  18. package/dist/lint.js +185 -1
  19. package/dist/lint.js.map +1 -1
  20. package/dist/perf.d.ts +31 -4
  21. package/dist/perf.d.ts.map +1 -1
  22. package/dist/perf.js +57 -4
  23. package/dist/perf.js.map +1 -1
  24. package/dist/register-properties.d.ts +25 -0
  25. package/dist/register-properties.d.ts.map +1 -0
  26. package/dist/register-properties.js +48 -0
  27. package/dist/register-properties.js.map +1 -0
  28. package/dist/text-bodies.d.ts +16 -5
  29. package/dist/text-bodies.d.ts.map +1 -1
  30. package/dist/text-bodies.js +37 -6
  31. package/dist/text-bodies.js.map +1 -1
  32. package/dist/worker/offthread-bridge.d.ts +17 -0
  33. package/dist/worker/offthread-bridge.d.ts.map +1 -0
  34. package/dist/worker/offthread-bridge.js +47 -0
  35. package/dist/worker/offthread-bridge.js.map +1 -0
  36. package/dist/worker/render-worker.d.ts +9 -0
  37. package/dist/worker/render-worker.d.ts.map +1 -0
  38. package/dist/worker/render-worker.js +43 -0
  39. package/dist/worker/render-worker.js.map +1 -0
  40. package/dist/x-ray.d.ts +14 -0
  41. package/dist/x-ray.d.ts.map +1 -0
  42. package/dist/x-ray.js +66 -0
  43. package/dist/x-ray.js.map +1 -0
  44. package/package.json +2 -2
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"}