@fundamental-engine/elements 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Experimental platform-backed runtime for `<field-root>` (Phase D: runtime platform unification).
3
+ *
4
+ * D1 establishes the *path*, not the migration: when the experimental flag is on, the element starts
5
+ * a `@fundamental-engine/platform` runtime alongside the legacy `createField` engine. For now it only measures
6
+ * the scan root each frame on the six-phase scheduler — a foothold the later phases fill in (D2 moves
7
+ * body scanning onto MeasurementRegistry, D3 feedback onto FeedbackRegistry, D4 shadow, D5
8
+ * relationships). Default is OFF, so behavior is unchanged until D6 flips it.
9
+ *
10
+ * The legacy engine still owns everything visible in D1; the platform adds nothing observable, which
11
+ * is exactly the parity guarantee: flag on and flag off render identically.
12
+ */
13
+ import { createFieldPlatform, QualityGovernor } from '@fundamental-engine/platform';
14
+ import { bodyElements, REGISTER_BODY, UNREGISTER_BODY, } from '@fundamental-engine/core';
15
+ /**
16
+ * Sync the scan root's body elements into the MeasurementRegistry (D2). New `[data-body]` /
17
+ * `[data-preset]` / `[data-intent]` / `[data-field-role]` elements are registered for measurement;
18
+ * disconnected ones are pruned by the read phase. Returns how many were newly registered. Pure given
19
+ * the sink + root — the selector is core's `bodyElements`, so the platform never drifts from the
20
+ * legacy scanner. Note (D2): an element that loses its body attribute while staying connected is not
21
+ * yet unregistered — a later refinement; today the legacy engine remains the source of truth for
22
+ * rendering, so this is measurement-only and has no observable effect.
23
+ */
24
+ export function syncBodies(sink, root) {
25
+ let added = 0;
26
+ for (const el of bodyElements(root)) {
27
+ if (!sink.has(el)) {
28
+ sink.register(el, { role: 'body' });
29
+ added++;
30
+ }
31
+ }
32
+ return added;
33
+ }
34
+ /**
35
+ * Register a shadow-DOM host for measurement from a `register-body` event detail (D4). The host's
36
+ * custom `getRect` (for closed roots / inner cores) flows straight into MeasurementRegistry's rect
37
+ * override. Pure given the sink + detail. `syncBodies`' `if (!has)` guard means it won't clobber a
38
+ * host registered here, so the two discovery paths coexist (the legacy engine still drives the
39
+ * body's simulation; the platform owns its geometry).
40
+ */
41
+ export function registerShadowBody(sink, detail) {
42
+ if (detail?.element)
43
+ sink.register(detail.element, { role: 'shadow-body', getRect: detail.getRect });
44
+ }
45
+ /** Unregister a shadow-DOM host from measurement on its `unregister-body` event (D4). Pure. */
46
+ export function unregisterShadowBody(sink, detail) {
47
+ if (detail?.element)
48
+ sink.unregister(detail.element);
49
+ }
50
+ /**
51
+ * Relationship discovery is heavier than body syncing (it builds graph edges from every native
52
+ * link), so the runtime re-discovers on a throttle rather than every frame (D5). Pure.
53
+ */
54
+ export function shouldDiscoverRelationships(frame, every = 30) {
55
+ return frame % every === 0;
56
+ }
57
+ // ── the flag ──────────────────────────────────────────────────────────────────────
58
+ // D6: the platform runtime is now the DEFAULT (parity proven across D1-D5). Every <field-root> runs
59
+ // it alongside the legacy engine, which still simulates + renders while the platform owns
60
+ // measurement, feedback writes, shadow registration, and the relationship graph. Opt a single
61
+ // element back onto the pure-legacy path with experimental-platform="off", or globally with
62
+ // usePlatformRuntime(false). D7 trims the now-redundant legacy DOM glue.
63
+ let runtimeDefault = true;
64
+ /** Enable (or disable) the platform runtime for every `<field-root>` by default (D6: default on). */
65
+ export function usePlatformRuntime(on = true) {
66
+ runtimeDefault = on;
67
+ }
68
+ /** Whether the platform runtime is the current default. */
69
+ export function isPlatformRuntimeDefault() {
70
+ return runtimeDefault;
71
+ }
72
+ /**
73
+ * Decide whether an element should use the platform runtime: an explicit `experimental-platform`
74
+ * attribute opts a single element in/out (`="off"` forces the legacy path), otherwise the global
75
+ * default applies (on since D6). Pure — the element's only branch point.
76
+ */
77
+ export function shouldUsePlatformRuntime(el, def = runtimeDefault) {
78
+ if (el.hasAttribute('experimental-platform'))
79
+ return el.getAttribute('experimental-platform') !== 'off';
80
+ return def;
81
+ }
82
+ /**
83
+ * Build a feedback sink (D3) that routes the engine's per-body channels through the platform's
84
+ * FeedbackRegistry. The eased density value is the engine's own — only the *write* moves — so the
85
+ * signal is preserved exactly. Writes apply on the platform's write phase (its scheduler tick).
86
+ *
87
+ * Since #228 the sink contract is the engine's ONLY write path: with no sink configured,
88
+ * `createField` installs an internal default sink (`core/feedback-sink.ts`) whose direct writes are
89
+ * byte-identical to the engine's historical behavior. This platform sink replaces that default when
90
+ * the runtime is on, moving the same channels onto FeedbackRegistry (write-phase batching,
91
+ * `cssWritesLastFrame()` accounting, governor throttling).
92
+ */
93
+ export function makeFeedbackSink(platform) {
94
+ const litArmed = new WeakSet();
95
+ // match the legacy engine's 3-decimal var formatting exactly, so the platform path is byte-identical.
96
+ const f3 = (n) => n.toFixed(3);
97
+ return (el, ch) => {
98
+ // density → --d (original) + --field-density
99
+ if (ch.density !== undefined)
100
+ platform.feedback.set(el, { '--d': f3(ch.density), '--field-density': f3(ch.density) });
101
+ // heatmap density → --field-heatmap-density
102
+ if (ch.heatmapDensity !== undefined)
103
+ platform.feedback.set(el, { '--field-heatmap-density': f3(ch.heatmapDensity) });
104
+ // accretion load → --load + --mass (back-compat alias)
105
+ if (ch.load !== undefined)
106
+ platform.feedback.set(el, { '--load': f3(ch.load), '--mass': f3(ch.load) });
107
+ // measured thermodynamics (workover v0.3) → the bare names, mirroring the engine's default
108
+ // sink exactly. These are engine-MEASURED local thermodynamics; the platform's
109
+ // `--field-entropy` / `--field-coherence` pipeline lanes (system-contracts §6) are
110
+ // INFERRED interaction metrics — different signals, deliberately different names.
111
+ if (ch.entropy !== undefined)
112
+ platform.feedback.set(el, { '--entropy': f3(ch.entropy) });
113
+ if (ch.coherence !== undefined)
114
+ platform.feedback.set(el, { '--coherence': f3(ch.coherence) });
115
+ if (ch.temperature !== undefined)
116
+ platform.feedback.set(el, { '--temperature': f3(ch.temperature) });
117
+ // lit → --lit (continuous) + a thresholded field:lit/field:dim (discrete, hysteretic) via state
118
+ if (ch.lit !== undefined) {
119
+ platform.feedback.set(el, { '--lit': f3(ch.lit) });
120
+ if (!litArmed.has(el)) {
121
+ litArmed.add(el);
122
+ platform.feedback.threshold(el, 'field:lit', { metric: 'lit', enter: 0.5, exit: 0.4, exitEvent: 'field:dim' });
123
+ }
124
+ platform.state.set(el, 'lit', ch.lit); // numeric — the threshold compares the raw value
125
+ }
126
+ };
127
+ }
128
+ /**
129
+ * Start the platform runtime over a scan root. Thin DOM glue (rAF + viewport size); SSR-safe — with
130
+ * no `window` it returns a created-but-idle platform. D2+ register bodies/feedback/relationships
131
+ * here; D1 measures only the root.
132
+ */
133
+ export function startPlatformRuntime(root) {
134
+ const platform = createFieldPlatform(root);
135
+ platform.measure.register(root, { role: 'field-root' });
136
+ // Bound Visual tier: discover declarative [data-field-visual-for] visuals at start so the
137
+ // platform's default state mirroring covers them (the registry re-copies on every source
138
+ // style write; dynamically added visuals need a platform.visuals.scan()).
139
+ platform.visuals.scan(root);
140
+ // D2: the discover phase syncs body elements into MeasurementRegistry each frame, so the platform
141
+ // measures the same bodies the legacy scanner finds (geometry only — still no observable change).
142
+ platform.on('discover', (ctx) => {
143
+ syncBodies(platform.measure, root);
144
+ // D5: maintain the relationship graph from the page's native links (throttled — see above).
145
+ if (shouldDiscoverRelationships(ctx.frame))
146
+ platform.relationships.discover(root);
147
+ });
148
+ // D4: shadow-DOM hosts join via composed field:register-body / field:unregister-body events.
149
+ // The host's getRect (for closed roots) flows into MeasurementRegistry's rect override. Listening
150
+ // on the document catches the composed events that bubble out of any shadow tree.
151
+ const doc = root.ownerDocument ?? (typeof document !== 'undefined' ? document : null);
152
+ const detailOf = (e) => e.detail;
153
+ const onRegister = (e) => registerShadowBody(platform.measure, detailOf(e));
154
+ const onUnregister = (e) => unregisterShadowBody(platform.measure, detailOf(e));
155
+ const wired = [];
156
+ if (doc) {
157
+ doc.addEventListener(REGISTER_BODY, onRegister);
158
+ doc.addEventListener(UNREGISTER_BODY, onUnregister);
159
+ wired.push([REGISTER_BODY, onRegister], [UNREGISTER_BODY, onUnregister]);
160
+ }
161
+ const unwireShadow = () => {
162
+ if (doc)
163
+ for (const [name, fn] of wired)
164
+ doc.removeEventListener(name, fn);
165
+ };
166
+ if (typeof window === 'undefined' || typeof requestAnimationFrame === 'undefined') {
167
+ return { platform, attachHandle: () => { }, destroy: unwireShadow };
168
+ }
169
+ let raf = 0;
170
+ let handle = null;
171
+ let lastTs = 0;
172
+ let frame = 0;
173
+ const governor = new QualityGovernor();
174
+ // A frame gap this large is a discontinuity (background tab, system sleep, a debugger pause),
175
+ // not a budget overrun — feeding it would spike the governor for free.
176
+ const DISCONTINUITY_MS = 500;
177
+ // write phase: --field-scroll-v on :root (once handle is attached). Written directly rather
178
+ // than through FeedbackRegistry — it's a page-global, not a per-body channel — so it does NOT
179
+ // count toward feedback.cssWritesLastFrame(). The unchanged-value guard keeps idle frames
180
+ // (scrollV pinned at 0.000) mutation-free.
181
+ let lastScrollV = '';
182
+ platform.on('write', () => {
183
+ if (!handle)
184
+ return;
185
+ const sv = handle.scrollV().toFixed(3);
186
+ if (sv === lastScrollV)
187
+ return;
188
+ lastScrollV = sv;
189
+ (root.ownerDocument ?? document).documentElement.style.setProperty('--field-scroll-v', sv);
190
+ });
191
+ // rAF stops while a tab is backgrounded; the first frame back would otherwise read as a huge
192
+ // overrun. Reset the timing baseline and re-detect from full quality.
193
+ const onVisibility = () => {
194
+ lastTs = 0;
195
+ governor.reset();
196
+ };
197
+ document.addEventListener('visibilitychange', onVisibility);
198
+ const loop = (t) => {
199
+ const duration = lastTs ? t - lastTs : 0;
200
+ lastTs = t;
201
+ frame++;
202
+ // Tier 2/3 degradation (the governor's built-in consumer): throttle the platform's own tick
203
+ // — measurement, feedback writes, relationship discovery — to every 2nd / 4th frame. The
204
+ // engine keeps simulating at full rate; only the platform's DOM read/write cadence drops.
205
+ // Engine-side responses (render simplification, particle caps) are the embedder's to wire
206
+ // via the field:quality-tier event.
207
+ const stride = governor.tier >= 3 ? 4 : governor.tier === 2 ? 2 : 1;
208
+ if (frame % stride === 0)
209
+ platform.tick(t, { width: window.innerWidth, height: window.innerHeight });
210
+ if (duration > 0 && duration < DISCONTINUITY_MS && handle) {
211
+ const newTier = governor.feed(duration);
212
+ if (newTier !== undefined) {
213
+ root.dispatchEvent(new CustomEvent('field:quality-tier', {
214
+ bubbles: true, composed: true,
215
+ detail: { tier: newTier, durationMs: Math.round(duration) },
216
+ }));
217
+ }
218
+ }
219
+ raf = requestAnimationFrame(loop);
220
+ };
221
+ raf = requestAnimationFrame(loop);
222
+ return {
223
+ platform,
224
+ attachHandle(h) {
225
+ handle = h;
226
+ governor.reset();
227
+ },
228
+ destroy() {
229
+ if (raf)
230
+ cancelAnimationFrame(raf);
231
+ raf = 0;
232
+ handle = null;
233
+ document.removeEventListener('visibilitychange', onVisibility);
234
+ unwireShadow();
235
+ // Registry teardown: the VisualBindingRegistry holds live MutationObservers (one per
236
+ // mirrored source) that the browser keeps firing — and keeps the registry, plus every
237
+ // observed element, alive long after this runtime is gone. setMirroring(false) disconnects
238
+ // and clears them all; the remaining registry maps hold no external refs and GC with the
239
+ // platform object once the host element drops its reference (disconnectedCallback / rebuild).
240
+ platform.visuals.setMirroring(false);
241
+ },
242
+ };
243
+ }
244
+ //# sourceMappingURL=platform-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-runtime.js","sourceRoot":"","sources":["../src/platform-runtime.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@fundamental-engine/elements",
3
+ "version": "0.5.1",
4
+ "description": "Web-component keystone for Fundamental — the <field-root> custom element + declarative data-body bodies.",
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/elements"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/zachshallbetter/fundamental-engine/issues"
16
+ },
17
+ "keywords": [
18
+ "Fundamental",
19
+ "web-components",
20
+ "custom-elements",
21
+ "particles",
22
+ "physics",
23
+ "canvas",
24
+ "field"
25
+ ],
26
+ "sideEffects": [
27
+ "./dist/index.js"
28
+ ],
29
+ "files": [
30
+ "dist",
31
+ "custom-elements.json",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "main": "./dist/index.js",
36
+ "types": "./dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "import": "./dist/index.js"
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "engines": {
45
+ "node": ">=18"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "dependencies": {
51
+ "@fundamental-engine/platform": "0.5.1",
52
+ "@fundamental-engine/vanilla": "0.5.1",
53
+ "@fundamental-engine/core": "0.5.1"
54
+ },
55
+ "devDependencies": {
56
+ "typescript": "^5.9.3"
57
+ },
58
+ "customElements": "custom-elements.json",
59
+ "scripts": {
60
+ "build": "tsc -p tsconfig.json",
61
+ "typecheck": "tsc -p tsconfig.json --noEmit",
62
+ "test": "node --test"
63
+ }
64
+ }