@fundamental-engine/dom 0.7.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +107 -0
  3. package/dist/apply-recipe.d.ts +103 -0
  4. package/dist/apply-recipe.d.ts.map +1 -0
  5. package/dist/apply-recipe.js +271 -0
  6. package/dist/apply-recipe.js.map +1 -0
  7. package/dist/bind-data.d.ts +72 -0
  8. package/dist/bind-data.d.ts.map +1 -0
  9. package/dist/bind-data.js +164 -0
  10. package/dist/bind-data.js.map +1 -0
  11. package/dist/browser-host.d.ts +11 -0
  12. package/dist/browser-host.d.ts.map +1 -0
  13. package/dist/browser-host.js +41 -0
  14. package/dist/browser-host.js.map +1 -0
  15. package/dist/contours.d.ts +79 -0
  16. package/dist/contours.d.ts.map +1 -0
  17. package/dist/contours.js +88 -0
  18. package/dist/contours.js.map +1 -0
  19. package/dist/env.d.ts +39 -0
  20. package/dist/env.d.ts.map +1 -0
  21. package/dist/env.js +47 -0
  22. package/dist/env.js.map +1 -0
  23. package/dist/export-dom.d.ts +7 -0
  24. package/dist/export-dom.d.ts.map +1 -0
  25. package/dist/export-dom.js +28 -0
  26. package/dist/export-dom.js.map +1 -0
  27. package/dist/feedback.d.ts +57 -0
  28. package/dist/feedback.d.ts.map +1 -0
  29. package/dist/feedback.js +134 -0
  30. package/dist/feedback.js.map +1 -0
  31. package/dist/field-nav.d.ts +35 -0
  32. package/dist/field-nav.d.ts.map +1 -0
  33. package/dist/field-nav.js +82 -0
  34. package/dist/field-nav.js.map +1 -0
  35. package/dist/flip.d.ts +31 -0
  36. package/dist/flip.d.ts.map +1 -0
  37. package/dist/flip.js +65 -0
  38. package/dist/flip.js.map +1 -0
  39. package/dist/governor.d.ts +37 -0
  40. package/dist/governor.d.ts.map +1 -0
  41. package/dist/governor.js +72 -0
  42. package/dist/governor.js.map +1 -0
  43. package/dist/index.d.ts +39 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +42 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lint.d.ts +78 -0
  48. package/dist/lint.d.ts.map +1 -0
  49. package/dist/lint.js +153 -0
  50. package/dist/lint.js.map +1 -0
  51. package/dist/measurement.d.ts +44 -0
  52. package/dist/measurement.d.ts.map +1 -0
  53. package/dist/measurement.js +95 -0
  54. package/dist/measurement.js.map +1 -0
  55. package/dist/metrics.d.ts +70 -0
  56. package/dist/metrics.d.ts.map +1 -0
  57. package/dist/metrics.js +119 -0
  58. package/dist/metrics.js.map +1 -0
  59. package/dist/overlays.d.ts +48 -0
  60. package/dist/overlays.d.ts.map +1 -0
  61. package/dist/overlays.js +48 -0
  62. package/dist/overlays.js.map +1 -0
  63. package/dist/perf.d.ts +62 -0
  64. package/dist/perf.d.ts.map +1 -0
  65. package/dist/perf.js +94 -0
  66. package/dist/perf.js.map +1 -0
  67. package/dist/platform.d.ts +40 -0
  68. package/dist/platform.d.ts.map +1 -0
  69. package/dist/platform.js +61 -0
  70. package/dist/platform.js.map +1 -0
  71. package/dist/relationships.d.ts +79 -0
  72. package/dist/relationships.d.ts.map +1 -0
  73. package/dist/relationships.js +155 -0
  74. package/dist/relationships.js.map +1 -0
  75. package/dist/schedule.d.ts +84 -0
  76. package/dist/schedule.d.ts.map +1 -0
  77. package/dist/schedule.js +91 -0
  78. package/dist/schedule.js.map +1 -0
  79. package/dist/state.d.ts +36 -0
  80. package/dist/state.d.ts.map +1 -0
  81. package/dist/state.js +113 -0
  82. package/dist/state.js.map +1 -0
  83. package/dist/text-bodies.d.ts +71 -0
  84. package/dist/text-bodies.d.ts.map +1 -0
  85. package/dist/text-bodies.js +159 -0
  86. package/dist/text-bodies.js.map +1 -0
  87. package/dist/thread-overlay.d.ts +63 -0
  88. package/dist/thread-overlay.d.ts.map +1 -0
  89. package/dist/thread-overlay.js +110 -0
  90. package/dist/thread-overlay.js.map +1 -0
  91. package/dist/types.d.ts +51 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +7 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/visual-bindings.d.ts +95 -0
  96. package/dist/visual-bindings.d.ts.map +1 -0
  97. package/dist/visual-bindings.js +211 -0
  98. package/dist/visual-bindings.js.map +1 -0
  99. package/package.json +59 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * threadOverlay — the hover-thread SVG overlay extracted from the invisible-fields example
3
+ * runtimes (the `wireThreads`/`centerIn` pattern in the Evidence page, adapted by the Backlog
4
+ * board and the Dependencies spill). Three hand-rolled copies drew the same picture; this is
5
+ * the common core: an absolutely-positioned, `aria-hidden`, pointer-events-none SVG prepended
6
+ * into a host, with one cubic-bezier path per (from → target) edge and the family's `lit` /
7
+ * `cited` class marks on the endpoints.
8
+ *
9
+ * GEOMETRY + CLASSES ONLY — no event wiring. The pages own hover semantics (pointerenter →
10
+ * `draw`, pointerleave → `clear`), reveal pacing, and color choice; this primitive owns the
11
+ * SVG lifecycle and the math.
12
+ *
13
+ * The CSS contract (what the three pages already style, unchanged):
14
+ * - the overlay carries `opts.className` (default `field-threads`; the example family passes
15
+ * `ev-threads`) — pages style `.<className> path { stroke: var(--thread, …); fill: none; }`.
16
+ * - `draw(…, { color })` sets the overlay's `--thread` custom property; omitting `color`
17
+ * removes it, so the page's `var(--thread, fallback)` fallback shows.
18
+ * - the hovered element gains `.lit`, each resolved target gains `.cited`; `clear()` removes
19
+ * both from everything this overlay marked.
20
+ * - inline geometry (position:absolute; inset:0; width/height:100%; pointer-events:none) is
21
+ * written on creation so the overlay covers the host before page CSS loads. The HOST must
22
+ * be a containing block (`position: relative` or similar) — that part stays page CSS.
23
+ *
24
+ * Coordinates are host-relative (the `centerIn` math): the viewBox is sized from the host's
25
+ * current rect at each `draw`, and every path runs center-to-center through the family's
26
+ * midpoint-y cubic — `M ax ay C ax my, bx my, bx by` with `my = (ay + by) / 2`.
27
+ *
28
+ * Geometry is sampled AT DRAW TIME and not observed afterwards: callers must re-draw (or
29
+ * `clear()`) after layout changes — FLIP re-sorts, batch reveals, container resize. The
30
+ * example pages clear on re-sort and re-draw on the next hover; that discipline is the
31
+ * caller's.
32
+ *
33
+ * SSR-safe: construction touches no globals (the SVG is created lazily via
34
+ * `host.ownerDocument` on first `draw`); `clear()`/`destroy()` are no-ops before that.
35
+ */
36
+ export interface ThreadOverlayOptions {
37
+ /** class for the overlay SVG (default `field-threads`; the example family uses `ev-threads`). */
38
+ className?: string;
39
+ }
40
+ export interface ThreadDrawOptions {
41
+ /** value for the overlay's `--thread` custom property (the stroke channel pages style against). Omitted → the property is removed and the page's CSS fallback applies. */
42
+ color?: string;
43
+ }
44
+ export interface ThreadOverlay {
45
+ /**
46
+ * Draw one thread per target: host-relative center-to-center cubic beziers from `from`,
47
+ * marking `from` with `.lit` and each target with `.cited`. Replaces the previous draw
48
+ * (paths and class marks). Reads layout — call outside the platform's write phase.
49
+ */
50
+ draw(from: HTMLElement, targets: readonly HTMLElement[], opts?: ThreadDrawOptions): void;
51
+ /** Empty the overlay's paths and remove every `lit`/`cited` mark this overlay applied. */
52
+ clear(): void;
53
+ /** `clear()` + remove the SVG from the host. `clear()` is a no-op afterwards; a later `draw()` recreates the overlay. */
54
+ destroy(): void;
55
+ }
56
+ /**
57
+ * Create (or adopt) a thread overlay on `host`. If a `svg.<className>` already exists in the
58
+ * host it is reused — so a page that server-renders the overlay shell, or re-inits its
59
+ * runtime, never stacks duplicates. Otherwise the SVG is created lazily on the first `draw`
60
+ * and PREPENDED (the evidence pattern: threads paint under the host's content in DOM order).
61
+ */
62
+ export declare function threadOverlay(host: HTMLElement, opts?: ThreadOverlayOptions): ThreadOverlay;
63
+ //# sourceMappingURL=thread-overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-overlay.d.ts","sourceRoot":"","sources":["../src/thread-overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,MAAM,WAAW,oBAAoB;IACnC,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,0KAA0K;IAC1K,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACzF,0FAA0F;IAC1F,KAAK,IAAI,IAAI,CAAC;IACd,yHAAyH;IACzH,OAAO,IAAI,IAAI,CAAC;CACjB;AAQD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE,oBAAyB,GAAG,aAAa,CA8D/F"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * threadOverlay — the hover-thread SVG overlay extracted from the invisible-fields example
3
+ * runtimes (the `wireThreads`/`centerIn` pattern in the Evidence page, adapted by the Backlog
4
+ * board and the Dependencies spill). Three hand-rolled copies drew the same picture; this is
5
+ * the common core: an absolutely-positioned, `aria-hidden`, pointer-events-none SVG prepended
6
+ * into a host, with one cubic-bezier path per (from → target) edge and the family's `lit` /
7
+ * `cited` class marks on the endpoints.
8
+ *
9
+ * GEOMETRY + CLASSES ONLY — no event wiring. The pages own hover semantics (pointerenter →
10
+ * `draw`, pointerleave → `clear`), reveal pacing, and color choice; this primitive owns the
11
+ * SVG lifecycle and the math.
12
+ *
13
+ * The CSS contract (what the three pages already style, unchanged):
14
+ * - the overlay carries `opts.className` (default `field-threads`; the example family passes
15
+ * `ev-threads`) — pages style `.<className> path { stroke: var(--thread, …); fill: none; }`.
16
+ * - `draw(…, { color })` sets the overlay's `--thread` custom property; omitting `color`
17
+ * removes it, so the page's `var(--thread, fallback)` fallback shows.
18
+ * - the hovered element gains `.lit`, each resolved target gains `.cited`; `clear()` removes
19
+ * both from everything this overlay marked.
20
+ * - inline geometry (position:absolute; inset:0; width/height:100%; pointer-events:none) is
21
+ * written on creation so the overlay covers the host before page CSS loads. The HOST must
22
+ * be a containing block (`position: relative` or similar) — that part stays page CSS.
23
+ *
24
+ * Coordinates are host-relative (the `centerIn` math): the viewBox is sized from the host's
25
+ * current rect at each `draw`, and every path runs center-to-center through the family's
26
+ * midpoint-y cubic — `M ax ay C ax my, bx my, bx by` with `my = (ay + by) / 2`.
27
+ *
28
+ * Geometry is sampled AT DRAW TIME and not observed afterwards: callers must re-draw (or
29
+ * `clear()`) after layout changes — FLIP re-sorts, batch reveals, container resize. The
30
+ * example pages clear on re-sort and re-draw on the next hover; that discipline is the
31
+ * caller's.
32
+ *
33
+ * SSR-safe: construction touches no globals (the SVG is created lazily via
34
+ * `host.ownerDocument` on first `draw`); `clear()`/`destroy()` are no-ops before that.
35
+ */
36
+ const SVG_NS = 'http://www.w3.org/2000/svg';
37
+ /** An element's center in host-rect coordinates (the family's `centerIn`). */
38
+ function centerIn(el, hostRect) {
39
+ const r = el.getBoundingClientRect();
40
+ return { x: r.left - hostRect.left + r.width / 2, y: r.top - hostRect.top + r.height / 2 };
41
+ }
42
+ /**
43
+ * Create (or adopt) a thread overlay on `host`. If a `svg.<className>` already exists in the
44
+ * host it is reused — so a page that server-renders the overlay shell, or re-inits its
45
+ * runtime, never stacks duplicates. Otherwise the SVG is created lazily on the first `draw`
46
+ * and PREPENDED (the evidence pattern: threads paint under the host's content in DOM order).
47
+ */
48
+ export function threadOverlay(host, opts = {}) {
49
+ const className = opts.className ?? 'field-threads';
50
+ const selector = 'svg.' + className.trim().split(/\s+/).join('.');
51
+ let svg = null;
52
+ const marked = new Set();
53
+ const ensure = () => {
54
+ if (svg)
55
+ return svg;
56
+ svg = host.querySelector(selector);
57
+ if (!svg) {
58
+ svg = host.ownerDocument.createElementNS(SVG_NS, 'svg');
59
+ svg.setAttribute('class', className);
60
+ svg.setAttribute('aria-hidden', 'true');
61
+ // cover the host even before page CSS loads; the host supplies the containing block.
62
+ svg.style.setProperty('position', 'absolute');
63
+ svg.style.setProperty('inset', '0');
64
+ svg.style.setProperty('width', '100%');
65
+ svg.style.setProperty('height', '100%');
66
+ svg.style.setProperty('pointer-events', 'none');
67
+ host.prepend(svg);
68
+ }
69
+ return svg;
70
+ };
71
+ const unmark = () => {
72
+ for (const el of marked)
73
+ el.classList.remove('lit', 'cited');
74
+ marked.clear();
75
+ };
76
+ const draw = (from, targets, drawOpts = {}) => {
77
+ const overlay = ensure();
78
+ unmark();
79
+ const box = host.getBoundingClientRect();
80
+ overlay.setAttribute('viewBox', `0 0 ${box.width} ${box.height}`);
81
+ if (drawOpts.color != null && drawOpts.color !== '')
82
+ overlay.style.setProperty('--thread', drawOpts.color);
83
+ else
84
+ overlay.style.removeProperty('--thread');
85
+ const a = centerIn(from, box);
86
+ from.classList.add('lit');
87
+ marked.add(from);
88
+ let d = '';
89
+ for (const t of targets) {
90
+ t.classList.add('cited');
91
+ marked.add(t);
92
+ const b = centerIn(t, box);
93
+ const my = (a.y + b.y) / 2;
94
+ d += `<path d="M${a.x} ${a.y} C ${a.x} ${my}, ${b.x} ${my}, ${b.x} ${b.y}"/>`;
95
+ }
96
+ overlay.innerHTML = d;
97
+ };
98
+ const clear = () => {
99
+ if (svg)
100
+ svg.innerHTML = '';
101
+ unmark();
102
+ };
103
+ const destroy = () => {
104
+ clear();
105
+ svg?.remove();
106
+ svg = null;
107
+ };
108
+ return { draw, clear, destroy };
109
+ }
110
+ //# sourceMappingURL=thread-overlay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-overlay.js","sourceRoot":"","sources":["../src/thread-overlay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @fundamental-engine/dom — shared contracts for the platform-adjacent registries. These describe the
3
+ * native primitives Fundamental wishes the browser had (frame-stable geometry, typed element state,
4
+ * relationships, visual-semantic pairing) built on the ones it has. Pure data shapes; no DOM here.
5
+ */
6
+ /** A measured rectangle in a coordinate space, with the centre precomputed. */
7
+ export interface FieldRect {
8
+ x: number;
9
+ y: number;
10
+ width: number;
11
+ height: number;
12
+ cx: number;
13
+ cy: number;
14
+ top: number;
15
+ right: number;
16
+ bottom: number;
17
+ left: number;
18
+ }
19
+ export type CoordinateSpace = 'viewport' | 'document' | 'field-root' | 'canvas';
20
+ /** One element's frame-stable measurement. */
21
+ export interface FieldMeasurement {
22
+ element: Element;
23
+ rect: FieldRect;
24
+ visible: boolean;
25
+ /** fraction of the element's area within the viewport, ∈ [0,1]. */
26
+ visibilityRatio: number;
27
+ coordinateSpace: CoordinateSpace;
28
+ /** the frame time this snapshot was taken. */
29
+ timestamp: number;
30
+ }
31
+ /** A typed, observable element state value — numeric/boolean/string/vector2 (NOT ARIA). */
32
+ export type FieldStateValue = {
33
+ type: 'number';
34
+ value: number;
35
+ } | {
36
+ type: 'boolean';
37
+ value: boolean;
38
+ } | {
39
+ type: 'string';
40
+ value: string;
41
+ } | {
42
+ type: 'vector2';
43
+ x: number;
44
+ y: number;
45
+ };
46
+ /** A viewport box for visibility computation (so measurement is testable without a window). */
47
+ export interface Viewport {
48
+ width: number;
49
+ height: number;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;AAEhF,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2FAA2F;AAC3F,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9C,+FAA+F;AAC/F,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fundamental-engine/dom — shared contracts for the platform-adjacent registries. These describe the
3
+ * native primitives Fundamental wishes the browser had (frame-stable geometry, typed element state,
4
+ * relationships, visual-semantic pairing) built on the ones it has. Pure data shapes; no DOM here.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * VisualBindingRegistry — bind an expressive visual layer (SVG, Canvas, WebGL) to its semantic DOM
3
+ * source without duplicating meaning or harming accessibility. The native primitive Fundamental wishes
4
+ * existed: a declarative "this visual represents that semantic element; don't double-expose it".
5
+ *
6
+ * The semantic source stays real HTML; the visual is `aria-hidden` unless it carries independent
7
+ * meaning. `lint()` flags orphan visuals and accessibility hazards.
8
+ *
9
+ * Declarative authoring: mark the visual with `data-field-visual-for` (id/selector of the semantic
10
+ * source) and `data-field-visual-role`, then call `scan(root)` to register it. This is the bridge from
11
+ * semantic HTML + data attributes → VisualBindingRegistry
12
+ * It does NOT extract glyph outlines or generate vector geometry — it only binds an authored visual
13
+ * layer to its source so the field can lint and inspect the pairing.
14
+ *
15
+ * State mirroring (Body Matter Interaction — the Bound Visual tier): the element absorbs field
16
+ * matter; the visual layer shows what that absorption means; the semantic text remains the source
17
+ * of meaning. CSS custom properties don't cross to siblings, so with mirroring enabled
18
+ * (`setMirroring(true)` — the platform default) every `representation`/`measurement` visual
19
+ * receives its source's feedback channels (`--d`/`--field-density`, `--load`/`--mass`, the measured
20
+ * metrics — see MIRRORED_CHANNELS) copied onto its own inline style: an aria-hidden SVG beside a
21
+ * sink heading thickens its contours from `var(--load)` exactly as if it were the body itself.
22
+ * Change-gated via a MutationObserver on the source's style attribute — no polling, no frame cost
23
+ * while the field is quiet.
24
+ */
25
+ export type VisualRole = 'decorative' | 'representation' | 'debug' | 'relationship' | 'measurement';
26
+ export interface VisualBinding {
27
+ visual: Element;
28
+ semanticSource: Element | null;
29
+ role: VisualRole;
30
+ accessibility: {
31
+ ariaHidden: boolean;
32
+ /** does this role require a semantic source to exist? */
33
+ semanticSourceRequired: boolean;
34
+ /** would screen readers see duplicate text from the visual? (source-bound but not hidden) */
35
+ duplicateSemantics: boolean;
36
+ };
37
+ }
38
+ export interface VisualLintWarning {
39
+ visual: Element;
40
+ code: 'orphan-representation' | 'visual-not-hidden' | 'duplicate-semantics';
41
+ severity: 'warning' | 'error';
42
+ message: string;
43
+ }
44
+ /** A warning raised while scanning the DOM for declarative bindings (resolution-time, not a11y). */
45
+ export interface VisualBindingScanWarning {
46
+ element: Element;
47
+ /** 'unresolved-source' | 'missing-source' | 'invalid-role' */
48
+ reason: string;
49
+ value?: string;
50
+ }
51
+ export interface VisualBindingScanResult {
52
+ total: number;
53
+ bound: number;
54
+ unresolved: number;
55
+ warnings: VisualBindingScanWarning[];
56
+ }
57
+ /** The feedback channels a bound visual mirrors from its semantic source — the engine's write-back
58
+ * lanes (density, sink load, causality, measured metrics). One list, shared with the docs. */
59
+ export declare const MIRRORED_CHANNELS: readonly string[];
60
+ export declare class VisualBindingRegistry {
61
+ private readonly bindings;
62
+ private mirroring;
63
+ private readonly observers;
64
+ /** Bind a visual layer to a semantic source. `representation`/`relationship` need a source. */
65
+ bind(opts: {
66
+ visual: Element;
67
+ source?: Element | null;
68
+ role: VisualRole;
69
+ }): VisualBinding;
70
+ /**
71
+ * Turn source→visual state mirroring on or off for every current and future binding (the Bound
72
+ * Visual tier of Body Matter Interaction). On: each `representation`/`measurement` visual gets an
73
+ * immediate copy of its source's MIRRORED_CHANNELS plus a style-attribute observer that re-copies
74
+ * whenever the engine writes the source (change-gated — quiet field, zero work). Off: observers
75
+ * disconnect; already-mirrored values are left in place (the visual keeps its last honest state).
76
+ */
77
+ setMirroring(on: boolean): void;
78
+ /** Copy the source's current feedback channels onto the visual's inline style (one pass). */
79
+ mirrorNow(visual: Element): void;
80
+ private watch;
81
+ private unwatch;
82
+ /**
83
+ * Discover declarative bindings under `root`: elements carrying `data-field-visual-for` (the source
84
+ * id/selector) and/or `data-field-visual-role`. Calls `bind()` for each. Idempotent — bindings are
85
+ * keyed by the visual element, so re-scanning updates role/source/aria-hidden without duplicating,
86
+ * and disconnected visuals are pruned. `resolve` defaults to a document-backed resolver.
87
+ */
88
+ scan(root: ParentNode, resolve?: (ref: string) => Element | null): VisualBindingScanResult;
89
+ get(visual: Element): VisualBinding | undefined;
90
+ all(): VisualBinding[];
91
+ get size(): number;
92
+ /** Accessibility lint over the bindings (visual-language §16 rules). */
93
+ lint(): VisualLintWarning[];
94
+ }
95
+ //# sourceMappingURL=visual-bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-bindings.d.ts","sourceRoot":"","sources":["../src/visual-bindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,gBAAgB,GAAG,OAAO,GAAG,cAAc,GAAG,aAAa,CAAC;AAOpG,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,aAAa,EAAE;QACb,UAAU,EAAE,OAAO,CAAC;QACpB,yDAAyD;QACzD,sBAAsB,EAAE,OAAO,CAAC;QAChC,6FAA6F;QAC7F,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,uBAAuB,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;IAC5E,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oGAAoG;AACpG,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACtC;AAID;+FAC+F;AAC/F,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAU9C,CAAC;AA8BF,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAElE,+FAA+F;IAC/F,IAAI,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,aAAa;IAmBzF;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAU/B,6FAA6F;IAC7F,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAYhC,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,OAAO;IAQf;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAAG,IAA4B,GAAG,uBAAuB;IAwCjH,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS;IAI/C,GAAG,IAAI,aAAa,EAAE;IAItB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,wEAAwE;IACxE,IAAI,IAAI,iBAAiB,EAAE;CAc5B"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * VisualBindingRegistry — bind an expressive visual layer (SVG, Canvas, WebGL) to its semantic DOM
3
+ * source without duplicating meaning or harming accessibility. The native primitive Fundamental wishes
4
+ * existed: a declarative "this visual represents that semantic element; don't double-expose it".
5
+ *
6
+ * The semantic source stays real HTML; the visual is `aria-hidden` unless it carries independent
7
+ * meaning. `lint()` flags orphan visuals and accessibility hazards.
8
+ *
9
+ * Declarative authoring: mark the visual with `data-field-visual-for` (id/selector of the semantic
10
+ * source) and `data-field-visual-role`, then call `scan(root)` to register it. This is the bridge from
11
+ * semantic HTML + data attributes → VisualBindingRegistry
12
+ * It does NOT extract glyph outlines or generate vector geometry — it only binds an authored visual
13
+ * layer to its source so the field can lint and inspect the pairing.
14
+ *
15
+ * State mirroring (Body Matter Interaction — the Bound Visual tier): the element absorbs field
16
+ * matter; the visual layer shows what that absorption means; the semantic text remains the source
17
+ * of meaning. CSS custom properties don't cross to siblings, so with mirroring enabled
18
+ * (`setMirroring(true)` — the platform default) every `representation`/`measurement` visual
19
+ * receives its source's feedback channels (`--d`/`--field-density`, `--load`/`--mass`, the measured
20
+ * metrics — see MIRRORED_CHANNELS) copied onto its own inline style: an aria-hidden SVG beside a
21
+ * sink heading thickens its contours from `var(--load)` exactly as if it were the body itself.
22
+ * Change-gated via a MutationObserver on the source's style attribute — no polling, no frame cost
23
+ * while the field is quiet.
24
+ */
25
+ const VISUAL_ROLES = ['decorative', 'representation', 'debug', 'relationship', 'measurement'];
26
+ const isVisualRole = (v) => v != null && VISUAL_ROLES.includes(v);
27
+ /** roles that re-present existing meaning and therefore require a semantic source. */
28
+ const requiresSource = (role) => role === 'representation' || role === 'relationship';
29
+ const ariaHidden = (el) => el.getAttribute('aria-hidden') === 'true';
30
+ /** The feedback channels a bound visual mirrors from its semantic source — the engine's write-back
31
+ * lanes (density, sink load, causality, measured metrics). One list, shared with the docs. */
32
+ export const MIRRORED_CHANNELS = [
33
+ '--d',
34
+ '--field-density',
35
+ '--load',
36
+ '--mass',
37
+ '--lit',
38
+ '--entropy',
39
+ '--coherence',
40
+ '--temperature',
41
+ '--field-heatmap-density',
42
+ ];
43
+ /** roles that re-present source state and therefore receive mirrored feedback channels. */
44
+ const mirrorsState = (b) => b.semanticSource != null && (b.role === 'representation' || b.role === 'measurement');
45
+ /** Build the default document-backed source resolver for a scan root (the §"resolution policy"). */
46
+ function defaultResolver(root) {
47
+ const doc = root.nodeType === 9 ? root : (root.ownerDocument ?? null);
48
+ const trySelector = (host, sel) => {
49
+ if (!host || typeof host.querySelector !== 'function')
50
+ return null;
51
+ try {
52
+ return host.querySelector(sel);
53
+ }
54
+ catch {
55
+ return null; // invalid selector → not a crash
56
+ }
57
+ };
58
+ return (ref) => {
59
+ if (!ref)
60
+ return null;
61
+ if (ref.startsWith('#'))
62
+ return trySelector(root, ref) ?? trySelector(doc, ref);
63
+ // bare value: prefer getElementById, then fall back to a (validated) selector
64
+ const byId = doc?.getElementById?.(ref) ?? null;
65
+ if (byId)
66
+ return byId;
67
+ return trySelector(root, ref);
68
+ };
69
+ }
70
+ export class VisualBindingRegistry {
71
+ bindings = new Map();
72
+ mirroring = false;
73
+ observers = new Map();
74
+ /** Bind a visual layer to a semantic source. `representation`/`relationship` need a source. */
75
+ bind(opts) {
76
+ const required = requiresSource(opts.role);
77
+ const hidden = ariaHidden(opts.visual);
78
+ const b = {
79
+ visual: opts.visual,
80
+ semanticSource: opts.source ?? null,
81
+ role: opts.role,
82
+ accessibility: {
83
+ ariaHidden: hidden,
84
+ semanticSourceRequired: required,
85
+ // a source-bound visual that is NOT hidden re-exposes the source's meaning to AT
86
+ duplicateSemantics: required && !hidden && !!opts.source,
87
+ },
88
+ };
89
+ this.bindings.set(opts.visual, b);
90
+ if (this.mirroring)
91
+ this.watch(b);
92
+ return b;
93
+ }
94
+ /**
95
+ * Turn source→visual state mirroring on or off for every current and future binding (the Bound
96
+ * Visual tier of Body Matter Interaction). On: each `representation`/`measurement` visual gets an
97
+ * immediate copy of its source's MIRRORED_CHANNELS plus a style-attribute observer that re-copies
98
+ * whenever the engine writes the source (change-gated — quiet field, zero work). Off: observers
99
+ * disconnect; already-mirrored values are left in place (the visual keeps its last honest state).
100
+ */
101
+ setMirroring(on) {
102
+ this.mirroring = on;
103
+ if (!on) {
104
+ for (const obs of this.observers.values())
105
+ obs.disconnect();
106
+ this.observers.clear();
107
+ return;
108
+ }
109
+ for (const b of this.bindings.values())
110
+ this.watch(b);
111
+ }
112
+ /** Copy the source's current feedback channels onto the visual's inline style (one pass). */
113
+ mirrorNow(visual) {
114
+ const b = this.bindings.get(visual);
115
+ if (!b || !mirrorsState(b))
116
+ return;
117
+ const src = b.semanticSource;
118
+ const dst = b.visual;
119
+ if (!src.style?.getPropertyValue || !dst.style?.setProperty)
120
+ return; // non-styled host (tests, SSR)
121
+ for (const channel of MIRRORED_CHANNELS) {
122
+ const value = src.style.getPropertyValue(channel);
123
+ if (value !== '' && value !== dst.style.getPropertyValue(channel))
124
+ dst.style.setProperty(channel, value);
125
+ }
126
+ }
127
+ watch(b) {
128
+ this.unwatch(b.visual);
129
+ if (!mirrorsState(b))
130
+ return;
131
+ this.mirrorNow(b.visual);
132
+ if (typeof MutationObserver === 'undefined' || !b.semanticSource)
133
+ return;
134
+ const obs = new MutationObserver(() => this.mirrorNow(b.visual));
135
+ obs.observe(b.semanticSource, { attributes: true, attributeFilter: ['style'] });
136
+ this.observers.set(b.visual, obs);
137
+ }
138
+ unwatch(visual) {
139
+ const obs = this.observers.get(visual);
140
+ if (obs) {
141
+ obs.disconnect();
142
+ this.observers.delete(visual);
143
+ }
144
+ }
145
+ /**
146
+ * Discover declarative bindings under `root`: elements carrying `data-field-visual-for` (the source
147
+ * id/selector) and/or `data-field-visual-role`. Calls `bind()` for each. Idempotent — bindings are
148
+ * keyed by the visual element, so re-scanning updates role/source/aria-hidden without duplicating,
149
+ * and disconnected visuals are pruned. `resolve` defaults to a document-backed resolver.
150
+ */
151
+ scan(root, resolve = defaultResolver(root)) {
152
+ // navigation hygiene: drop bindings whose visual OR source left the DOM (and stop mirroring
153
+ // them). Pruning only on the visual leaves a MutationObserver pinned to a removed source —
154
+ // holding that detached source subtree alive for as long as the visual stays mounted.
155
+ for (const [el, b] of this.bindings)
156
+ if (el.isConnected === false || b.semanticSource?.isConnected === false) {
157
+ this.unwatch(el);
158
+ this.bindings.delete(el);
159
+ }
160
+ const visuals = [...root.querySelectorAll('[data-field-visual-for], [data-field-visual-role], [data-visual-for]')];
161
+ const warnings = [];
162
+ let unresolved = 0;
163
+ for (const visual of visuals) {
164
+ const value = visual.getAttribute('data-field-visual-for') ?? visual.getAttribute('data-visual-for');
165
+ const roleAttr = visual.getAttribute('data-field-visual-role');
166
+ let role;
167
+ if (roleAttr == null) {
168
+ role = 'representation'; // role omitted but selected via data-field-visual-for → representation
169
+ }
170
+ else if (isVisualRole(roleAttr)) {
171
+ role = roleAttr;
172
+ }
173
+ else {
174
+ role = 'representation'; // invalid role → default + warn
175
+ warnings.push({ element: visual, reason: 'invalid-role', value: roleAttr });
176
+ }
177
+ const source = value ? resolve(value) : null;
178
+ if (requiresSource(role) && !source) {
179
+ unresolved++;
180
+ warnings.push({ element: visual, reason: value ? 'unresolved-source' : 'missing-source', value: value ?? undefined });
181
+ }
182
+ this.bind({ visual, source, role });
183
+ }
184
+ return { total: visuals.length, bound: visuals.length, unresolved, warnings };
185
+ }
186
+ get(visual) {
187
+ return this.bindings.get(visual);
188
+ }
189
+ all() {
190
+ return [...this.bindings.values()];
191
+ }
192
+ get size() {
193
+ return this.bindings.size;
194
+ }
195
+ /** Accessibility lint over the bindings (visual-language §16 rules). */
196
+ lint() {
197
+ const out = [];
198
+ for (const b of this.bindings.values()) {
199
+ if (b.accessibility.semanticSourceRequired && !b.semanticSource)
200
+ out.push({ visual: b.visual, code: 'orphan-representation', severity: 'error', message: `a ${b.role} visual must bind a semantic source` });
201
+ else if (!b.accessibility.ariaHidden) {
202
+ if (requiresSource(b.role))
203
+ out.push({ visual: b.visual, code: 'duplicate-semantics', severity: 'warning', message: `a ${b.role} visual must be aria-hidden so assistive tech reads only the semantic source` });
204
+ else
205
+ out.push({ visual: b.visual, code: 'visual-not-hidden', severity: 'warning', message: `a ${b.role} visual with no independent meaning should be aria-hidden` });
206
+ }
207
+ }
208
+ return out;
209
+ }
210
+ }
211
+ //# sourceMappingURL=visual-bindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-bindings.js","sourceRoot":"","sources":["../src/visual-bindings.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@fundamental-engine/dom",
3
+ "version": "0.7.0",
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
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Zach Shallbetter <hi@zachshallbetter.com> (https://zachshallbetter.com)",
8
+ "homepage": "https://fundamental-engine.com",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/zachshallbetter/fundamental-engine.git",
12
+ "directory": "packages/dom"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/zachshallbetter/fundamental-engine/issues"
16
+ },
17
+ "keywords": [
18
+ "Fundamental",
19
+ "dom",
20
+ "measurement",
21
+ "relationships",
22
+ "state",
23
+ "feedback",
24
+ "overlays",
25
+ "web"
26
+ ],
27
+ "sideEffects": false,
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "main": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
42
+ "engines": {
43
+ "node": ">=18"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "@fundamental-engine/core": "0.7.0"
50
+ },
51
+ "devDependencies": {
52
+ "typescript": "^5.9.3"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.json",
56
+ "typecheck": "tsc -p tsconfig.json --noEmit",
57
+ "test": "node --test"
58
+ }
59
+ }