@symbiote-native/engine 0.5.0 → 1.0.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 (91) hide show
  1. package/README.md +39 -14
  2. package/android/CMakeLists.txt +51 -0
  3. package/android/build.gradle +90 -0
  4. package/android/src/main/AndroidManifest.xml +1 -0
  5. package/android/src/main/cpp/SymbioteEngineJni.cpp +72 -0
  6. package/android/src/main/java/dev/symbiotenative/engine/SymbioteEngineModule.kt +43 -0
  7. package/android/src/main/java/dev/symbiotenative/engine/SymbioteEnginePackage.kt +35 -0
  8. package/build/accessibility-info/shared.js +1 -1
  9. package/build/accessibility-props.d.ts +1 -8
  10. package/build/accessibility-props.js +13 -16
  11. package/build/animated/animations/composition.d.ts +1 -1
  12. package/build/animated/animations/composition.js +18 -4
  13. package/build/animated/easing.d.ts +3 -2
  14. package/build/animated/easing.js +17 -88
  15. package/build/animated/event.js +6 -1
  16. package/build/animated/host-binding.d.ts +1 -1
  17. package/build/animated/host-binding.js +19 -4
  18. package/build/animated/index.d.ts +1 -1
  19. package/build/animated/mock.d.ts +1 -19
  20. package/build/animated/props.js +1 -1
  21. package/build/animated/rgba.js +16 -50
  22. package/build/events/index.js +88 -40
  23. package/build/fabric-props.d.ts +1 -1
  24. package/build/fabric-props.js +116 -184
  25. package/build/fabric.d.ts +9 -0
  26. package/build/fabric.js +32 -0
  27. package/build/host-access.d.ts +125 -0
  28. package/build/host-access.js +280 -0
  29. package/build/host-behavior.d.ts +84 -21
  30. package/build/host-behavior.js +196 -30
  31. package/build/image-source-write.d.ts +16 -0
  32. package/build/image-source-write.js +65 -0
  33. package/build/imperative.d.ts +49 -0
  34. package/build/imperative.js +258 -0
  35. package/build/index.d.ts +14 -7
  36. package/build/index.js +53 -10
  37. package/build/mutation-buffer.d.ts +222 -0
  38. package/build/mutation-buffer.js +491 -0
  39. package/build/native-engine.d.ts +182 -0
  40. package/build/native-engine.js +178 -0
  41. package/build/native-tree-host.d.ts +25 -0
  42. package/build/native-tree-host.js +66 -0
  43. package/build/node.d.ts +172 -57
  44. package/build/node.js +839 -383
  45. package/build/pan-responder/index.js +27 -52
  46. package/build/platform-color/index.d.ts +1 -1
  47. package/build/platform-color/index.js +11 -4
  48. package/build/process-background-image/index.js +30 -566
  49. package/build/process-background-longhands.d.ts +4 -0
  50. package/build/process-background-longhands.js +44 -0
  51. package/build/process-box-shadow/index.js +23 -187
  52. package/build/process-filter.js +27 -300
  53. package/build/process-transform/index.d.ts +1 -1
  54. package/build/process-transform/index.js +25 -107
  55. package/build/process-transform-origin/index.d.ts +1 -1
  56. package/build/process-transform-origin/index.js +29 -102
  57. package/build/registry.d.ts +36 -0
  58. package/build/registry.js +73 -0
  59. package/build/sound-manager/index.d.ts +3 -0
  60. package/build/sound-manager/index.js +36 -0
  61. package/build/structured-style.d.ts +10 -0
  62. package/build/structured-style.js +180 -0
  63. package/build/style-registry/index.d.ts +14 -0
  64. package/build/style-registry/index.js +60 -11
  65. package/build/surface.d.ts +31 -2
  66. package/build/surface.js +138 -56
  67. package/build/text-input-state.d.ts +1 -0
  68. package/build/text-input-state.js +17 -3
  69. package/build/tree-host.d.ts +307 -0
  70. package/build/tree-host.js +211 -0
  71. package/build/view-config.js +4 -4
  72. package/codegen-specs/NativeSymbioteEngine.ts +27 -0
  73. package/cpp/SymbioteDebug.cpp +51 -0
  74. package/cpp/SymbioteDebug.h +54 -0
  75. package/cpp/SymbioteEngineBindings.cpp +232 -0
  76. package/cpp/SymbioteEngineBindings.h +59 -0
  77. package/cpp/SymbioteFabricProps.cpp +2619 -0
  78. package/cpp/SymbioteFabricProps.h +223 -0
  79. package/cpp/SymbioteTree.cpp +2478 -0
  80. package/cpp/SymbioteTree.h +257 -0
  81. package/ios/SymbioteEngineModule.h +25 -0
  82. package/ios/SymbioteEngineModule.mm +44 -0
  83. package/package.json +31 -3
  84. package/react-native.config.cjs +23 -0
  85. package/symbiote-engine.podspec +42 -0
  86. package/build/animated/bezier.d.ts +0 -1
  87. package/build/animated/bezier.js +0 -102
  88. package/build/commit.d.ts +0 -49
  89. package/build/commit.js +0 -1058
  90. package/build/tags.d.ts +0 -2
  91. package/build/tags.js +0 -40
@@ -0,0 +1,258 @@
1
+ // The imperative half of what `commit.ts` used to export — everything an app or an adapter reaches
2
+ // for OUTSIDE a render: measure, view commands, accessibility events, the Animated fast path.
3
+ //
4
+ // It survived the tree's removal unchanged in SHAPE, because every one of these was already written
5
+ // against three fields — a Fabric handle, a tag, a root tag — and never against the walk. What
6
+ // changed is where those come from: `committedOf(node)` read an `IMirror` on the node, and the tree
7
+ // HOST answers now (`tree-host.ts`) — native on device, the TypeScript applier headlessly.
8
+ //
9
+ // `undefined` is the ORDINARY state here, not an error. An adapter that wires an imperative call at
10
+ // lifecycle time runs before `completeRoot` under an async-batched commit (Vue and Svelte schedule
11
+ // it on a microtask), so the node has no handle yet. Every function either defers (`whenCommitted`)
12
+ // or logs and returns — never throws.
13
+ import { dlog, isDebug } from './debug.js';
14
+ import { clearPublishedStyle, writeProp } from './node.js';
15
+ import { flattenStyle } from './style/index.js';
16
+ import { flushOps, treeHost } from './tree-host.js';
17
+ /**
18
+ * What Fabric currently holds for `node`, or `undefined` before its first commit.
19
+ *
20
+ * Flushes first: an imperative call can land between a mutation and its commit, and the host cannot
21
+ * answer about ops it has not been handed.
22
+ *
23
+ * `undefined` is the ORDINARY state, not an error — and it is also what a WRAPPED node gets. The host
24
+ * keys on the handle OBJECT, so a Vue `reactive()` / deep-`ref()` Proxy around a host element misses
25
+ * and every function below degrades to its log. Hold host nodes with `shallowRef`.
26
+ */
27
+ function committedRecordOf(node) {
28
+ flushOps();
29
+ return treeHost()?.committedRecordOf(node);
30
+ }
31
+ // Surfaces that have asked for a commit this task, and the callback that performs one. Registered
32
+ // by `surface.ts` rather than imported from it: a surface owns its own commit, and reaching into it
33
+ // from here would put the cycle back that this split exists to remove.
34
+ const pendingRoots = new Set();
35
+ let commitSurface;
36
+ let forgetSurface;
37
+ let flushScheduled = false;
38
+ export function registerSurfaceCommit(commit, forget) {
39
+ commitSurface = commit;
40
+ forgetSurface = forget;
41
+ }
42
+ export function flushNativeProps() {
43
+ flushScheduled = false;
44
+ if (pendingRoots.size === 0)
45
+ return;
46
+ const roots = [...pendingRoots];
47
+ pendingRoots.clear();
48
+ for (const rootTag of roots)
49
+ commitSurface?.(rootTag);
50
+ }
51
+ /**
52
+ * Publish a node whose props changed OUTSIDE any renderer mutation.
53
+ *
54
+ * Recording is not publishing. Every other write reaches Fabric because the framework's own commit
55
+ * follows it; a change driven by a NATIVE EVENT has no such follow-up — the press path's
56
+ * `setNodePressed` is the first caller that is not `setNativeProps`.
57
+ *
58
+ * Queued rather than committed on the spot: several writes in one task publish together at the
59
+ * microtask boundary, one commit per surface.
60
+ */
61
+ export function requestCommitFor(node) {
62
+ const record = committedRecordOf(node);
63
+ if (record === undefined) {
64
+ dlog('requestCommitFor skipped: node not committed');
65
+ return;
66
+ }
67
+ requestCommitForRoot(record.rootTag);
68
+ }
69
+ /**
70
+ * The same request, for a caller that already holds the node's record.
71
+ *
72
+ * `committedRecordOf` crosses the host boundary, and `setNativeProps` fetches the record two lines
73
+ * before it calls this — so asking again was two crossings for one fact, on the path an
74
+ * `AnimatedProps` leaf runs once per frame per animated node. Measured at 2 of the 3 crossings a
75
+ * frame made (`__tests__/animated-frame-cost.test.ts`).
76
+ */
77
+ function requestCommitForRoot(rootTag) {
78
+ pendingRoots.add(rootTag);
79
+ if (!flushScheduled) {
80
+ flushScheduled = true;
81
+ queueMicrotask(flushNativeProps);
82
+ }
83
+ }
84
+ export function disposeRoot(rootTag) {
85
+ // Drop anything still queued for this surface: its flush is a microtask away and would otherwise
86
+ // commit into a container that no longer exists.
87
+ pendingRoots.delete(rootTag);
88
+ forgetSurface?.(rootTag);
89
+ dlog(`root disposed root=${rootTag}`);
90
+ }
91
+ /** The committed reactTag, stable across clone-on-write — what the native Animated driver binds. */
92
+ export function getNativeTag(node) {
93
+ return committedRecordOf(node)?.tag;
94
+ }
95
+ /**
96
+ * The node's current native handle, in kind identical to React's `stateNode.node`.
97
+ *
98
+ * OPAQUE. Under the native host it is a `ShadowNode`, under a headless one whatever that host
99
+ * committed — see `ICommittedRecord.handle`. It used to be typed `IFabricNode`, a brand with no
100
+ * members, so a caller can do exactly as much with it as before.
101
+ */
102
+ export function getNativeNode(node) {
103
+ return committedRecordOf(node)?.handle;
104
+ }
105
+ // Actions waiting for their node's first commit. An adapter that wires an imperative call at
106
+ // lifecycle time can run BEFORE completeRoot under an async-batched commit, so the node has no
107
+ // handle yet and the call would silently no-op. Each waiter retries after a commit and is dropped
108
+ // once it runs. React commits synchronously, so its actions run inline and never land here.
109
+ const pendingCommitWaiters = new Set();
110
+ /** Called by the commit path once a batch has published. */
111
+ export function notifyCommitted() {
112
+ for (const waiter of pendingCommitWaiters) {
113
+ if (waiter())
114
+ pendingCommitWaiters.delete(waiter);
115
+ }
116
+ }
117
+ /**
118
+ * Run `action` once `node` has a committed Fabric handle — immediately if it already does, else
119
+ * after the commit that assigns one. Returns a cancel fn (drop the retry, e.g. on unmount).
120
+ */
121
+ export function whenCommitted(node, action) {
122
+ const attempt = () => {
123
+ if (committedRecordOf(node) === undefined)
124
+ return false;
125
+ action();
126
+ return true;
127
+ };
128
+ if (!attempt())
129
+ pendingCommitWaiters.add(attempt);
130
+ return () => {
131
+ pendingCommitWaiters.delete(attempt);
132
+ };
133
+ }
134
+ export function dispatchViewCommand(node, commandName, args) {
135
+ const record = committedRecordOf(node);
136
+ if (record === undefined) {
137
+ dlog(`dispatchViewCommand "${commandName}" skipped: node not committed`);
138
+ return;
139
+ }
140
+ dlog(`dispatchViewCommand "${commandName}"`);
141
+ treeHost()?.dispatchCommand(node, commandName, args);
142
+ }
143
+ export function sendAccessibilityEvent(node, eventType) {
144
+ const record = committedRecordOf(node);
145
+ if (record === undefined) {
146
+ dlog(`sendAccessibilityEvent "${eventType}" skipped: node not committed`);
147
+ return;
148
+ }
149
+ treeHost()?.sendAccessibilityEvent(node, eventType);
150
+ }
151
+ export function measure(node, callback) {
152
+ const record = committedRecordOf(node);
153
+ if (record === undefined) {
154
+ dlog('measure skipped: node not committed');
155
+ return;
156
+ }
157
+ treeHost()?.measure(node, callback);
158
+ }
159
+ export function measureInWindow(node, callback) {
160
+ const record = committedRecordOf(node);
161
+ if (record === undefined) {
162
+ dlog('measureInWindow skipped: node not committed');
163
+ return;
164
+ }
165
+ treeHost()?.measureInWindow(node, callback);
166
+ }
167
+ // RN's public signature is (relative, onSuccess, onFail) but the native slot wants the fail
168
+ // callback first, so the order is swapped here.
169
+ export function measureLayout(node, relativeTo, onSuccess, onFail = () => { }) {
170
+ const record = committedRecordOf(node);
171
+ const relativeRecord = committedRecordOf(relativeTo);
172
+ if (record === undefined || relativeRecord === undefined) {
173
+ dlog('measureLayout skipped: a node is not committed');
174
+ return;
175
+ }
176
+ treeHost()?.measureLayout(node, relativeTo, onFail, onSuccess);
177
+ }
178
+ /**
179
+ * Tell native that JS has taken the gesture, or given it up.
180
+ *
181
+ * Through the HOST like the five above it, never through the Fabric slot: under the native tree
182
+ * host the committed handle is our placeholder, and `nativeFabricUIManager.setIsJSResponder` unwraps
183
+ * only a `ShadowNode` reference it minted itself.
184
+ */
185
+ export function setIsJSResponder(node, isResponder, blockNativeResponder) {
186
+ if (committedRecordOf(node) === undefined) {
187
+ dlog('setIsJSResponder skipped: node not committed');
188
+ return;
189
+ }
190
+ treeHost()?.setIsJSResponder(node, isResponder, blockNativeResponder);
191
+ }
192
+ /** The node's CURRENT prop value, as the host holds it. The behaviors' one read. */
193
+ export function propOf(node, key) {
194
+ flushOps();
195
+ return treeHost()?.propOf(node, key);
196
+ }
197
+ // Per-frame prop write for the JS-driven Animated path, and the one write that bypasses the
198
+ // declarative style. RN flushes an animation frame with an in-place `instance.setNativeProps(...)`;
199
+ // Fabric is persistent, so a frame is one scoped commit instead.
200
+ //
201
+ // IT NO LONGER BYPASSES ANYTHING, and the correction it used to owe the host is gone with the
202
+ // bypass. This wrote to Fabric directly once, so the host had to be told what had been sent behind
203
+ // its back or its next diff would be computed against a stale base. The write is an ordinary op now
204
+ // — the commit that carries it updates that record itself. Telling the host EARLY was strictly
205
+ // worse than not telling it: `noteNativePropsBypass` folded the values into `committedProps` before
206
+ // the commit ran, so the diff found nothing to send and the write never reached Fabric at all.
207
+ //
208
+ // One correction survives, because it is about the ENGINE's own state rather than the host's:
209
+ // `parts.published` is cleared, so `pushClassStyle`'s guard cannot turn away the re-push that
210
+ // RESTORES the declarative style this frame just overwrote. The guard is exact, and an app handing
211
+ // over a hoisted style constant (StyleSheet.create, a module-level object) would otherwise never
212
+ // get it back.
213
+ export function setNativeProps(node, partial) {
214
+ const record = committedRecordOf(node);
215
+ if (record === undefined) {
216
+ dlog('setNativeProps skipped: node not committed');
217
+ return;
218
+ }
219
+ const merged = {};
220
+ for (const [key, value] of Object.entries(partial)) {
221
+ if (key === 'style') {
222
+ // A partial style override MERGES onto the standing style (RN semantics):
223
+ // setNativeProps({style:{backgroundColor}}) recolors without dropping height or radius.
224
+ // Transient: the next declarative commit re-applies the full style.
225
+ merged.style = {
226
+ ...flattenStyle(treeHost()?.propOf(node, 'style')),
227
+ ...flattenStyle(value),
228
+ };
229
+ }
230
+ else {
231
+ merged[key] = value;
232
+ // This path used to owe the aria gate that `setProp` carried, since it bypasses it. There is
233
+ // no gate to owe any more: the fold is the device's rule and it recomputes presence from the
234
+ // bag. See `node.ts`'s note at the old choke point.
235
+ }
236
+ }
237
+ for (const [key, value] of Object.entries(merged)) {
238
+ // `writeProp`, not `recordSetProp`: this is the path with no `routeProp` in front of it, so a
239
+ // function reaches the wire from here and nowhere else. `AnimatedProps.__getValue()` copies
240
+ // every key its leaf holds, `panHandlers` included.
241
+ writeProp(node, key, value);
242
+ }
243
+ if (merged.style !== undefined)
244
+ clearPublishedStyle(node);
245
+ // GATED, and this is the one place in the engine where "per frame" is the right unit to worry
246
+ // about. An `AnimatedProps` leaf calls this once per frame per animated node, so the template
247
+ // string and the `Object.keys` array it builds are 60 allocations a second per node — times the
248
+ // list, for a list that animates its rows. F-61 dismissed 347 ungated arguments because none of
249
+ // them was on a path that repeats; this one is, and F-61 had it in its own in-loop list and
250
+ // priced it as "runs once".
251
+ if (isDebug()) {
252
+ dlog(`setNativeProps root=${record.rootTag} tag=${record.tag} keys=${Object.keys(partial)}`);
253
+ }
254
+ // Queued, not committed: every write made in this task publishes together at the microtask
255
+ // boundary. With the record already in hand — asking for it again is a second crossing for a
256
+ // fact this function fetched four lines up.
257
+ requestCommitForRoot(record.rootTag);
258
+ }
package/build/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { createElement, createRawText, createAnchor, ANCHOR_COMPONENT, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle, setNodeHidden, setNodeComponent, setNodePressed, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node';
1
+ export { createElement, createRawText, createAnchor, ANCHOR_COMPONENT, isAnchor, createVoid, VOID_COMPONENT, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle, isSameShallowStyle, getPublishedStyle, setNodeHidden, setNodeComponent, setNodePressed, setNodeUnderlayShown, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, takePropKeyTally, } from './node';
2
+ export { parentOf, childrenOf, firstChildOf, nextSiblingOf, isTextContainer, isRawTextNode, componentOf, textOf, propOf, propsOf, committedPayloadOf, } from './host-access';
2
3
  export { setAnimatedBehaviorStyle } from './animated/host-binding';
3
4
  export { isEventFor } from './view-config';
4
5
  export { registerComponent, setNativeViewConfigSource } from './registry';
@@ -11,10 +12,15 @@ export type { IComponentRegistration, INativeEventBinding, INativeViewConfig, IN
11
12
  export type { ISymbioteNode, ISymbioteEvent, IListener } from './node';
12
13
  export { SymbioteSurface, createSurface } from './surface';
13
14
  export { setEventDispatcher } from './dispatch';
14
- export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, readCommitProfile, } from './commit';
15
- export type { ICommitProfile } from './commit';
15
+ export { setColorProcessor, processColor } from './platform-color';
16
+ export { dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, requestCommitFor, } from './imperative';
17
+ export { setTreeHost, treeHost, registerBeforeFlush, readCommitProfile, readSurfaceTelemetry, setNativeDebug, takeNativeDebugLog, } from './tree-host';
18
+ export type { ISurfaceTelemetry } from './tree-host';
19
+ export { nativeTreeHost, installNativeTreeHost } from './native-tree-host';
20
+ export type { ITreeHost, ITreeCensus, ICommittedRecord, ICommitProfile, } from './tree-host';
16
21
  export { registerPostCommit, unregisterPostCommit } from './post-commit';
17
22
  export { ARIA_ALIAS_KEYS, foldAriaProps } from './accessibility-props';
23
+ export { fabricProps } from './fabric-props';
18
24
  export { toPublicInstance } from './host-instance';
19
25
  export type { IHostInstance } from './host-instance';
20
26
  export { PlatformColor, DynamicColorIOS, isOpaqueColorValue, } from './platform-color';
@@ -47,8 +53,9 @@ export { getNativeModule, getEnforcingNativeModule } from './native-modules';
47
53
  export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource, } from './native-events';
48
54
  export type { IEventSubscription, IEventEmitterModule, INativeEventListener, IDeviceEventSource, } from './native-events';
49
55
  export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, createAnimatedLeafLifecycle, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated';
50
- export type { IAnimatedLeafLifecycle, IValueXY, IRgbaValue, IColorInput, IEventConfig, IEventListener, IAnimatedEventHandler, INativeEventAttachment, IValueListener, IEasingFunction, IInterpolationConfig, IExtrapolateType, IAnimation, IEndCallback, IEndResult, ICompositeAnimation, ITimingConfig, ISpringConfig, IDecayConfig, IParallelConfig, ILoopAnimationConfig, INativeNodeConfig, INativeAnimationConfig, INativeEventMapping, IPlatformConfig, } from './animated';
56
+ export type { IAnimatedLeafLifecycle, IValueXY, IRgbaValue, IColorInput, IEventConfig, IEventListener, IAnimatedEventHandler, INativeEventAttachment, IValueListener, IEasing, IEasingFunction, IInterpolationConfig, IExtrapolateType, IAnimation, IEndCallback, IEndResult, ICompositeAnimation, ITimingConfig, ISpringConfig, IDecayConfig, IParallelConfig, ILoopAnimationConfig, INativeNodeConfig, INativeAnimationConfig, INativeEventMapping, IPlatformConfig, } from './animated';
51
57
  export { getSlot } from './fabric';
58
+ export { resetSlot } from './fabric';
52
59
  export type { IFabricSlot, IFabricNode, IFabricChildSet, IFabricProps, IFabricEventHandler, IRootTag, IMeasureOnSuccess, IMeasureInWindowOnSuccess, IMeasureLayoutOnSuccess, } from './fabric';
53
60
  export { Alert } from './alert';
54
61
  export type { IAlertType, IAlertButtonStyle, IAlertButton, IAlertButtons, IAlertOptions, } from './alert';
@@ -64,6 +71,7 @@ export { Linking } from './linking';
64
71
  export type { IUrlEvent } from './linking';
65
72
  export { Vibration } from './vibration';
66
73
  export { ToastAndroid } from './toast-android';
74
+ export { SoundManager } from './sound-manager';
67
75
  export { Settings } from './settings';
68
76
  export { I18nManager } from './i18n-manager';
69
77
  export type { II18nManagerConstants } from './i18n-manager';
@@ -79,7 +87,7 @@ export { createAppRegistry } from './app-registry';
79
87
  export type { IAppRegistry, ICreateAppRegistryResult, IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from './app-registry';
80
88
  export { Keyboard, KEYBOARD_EVENT } from './keyboard';
81
89
  export type { IKeyboardEventName, IKeyboardEvent, IKeyboardMetrics, } from './keyboard';
82
- export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from './text-input-state';
90
+ export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, focusTextInput, } from './text-input-state';
83
91
  export { LayoutAnimation } from './layout-animation';
84
92
  export type { ILayoutAnimationType, ILayoutAnimationProperty, ILayoutAnimationConfig, ILayoutAnimationAnim, ILayoutAnimationTypes, ILayoutAnimationProperties, } from './layout-animation';
85
93
  export { BackHandler } from './back-handler';
@@ -91,7 +99,6 @@ export type { IAccessibilityChangeEvent, IAccessibilityChangeEventName, IAccessi
91
99
  export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from './status-bar';
92
100
  export { hideTransition, STATUS_BAR_MANAGER, ANIMATED_HIDE_TRANSITION, STATIC_HIDE_TRANSITION, } from './status-bar/shared';
93
101
  export type { IStatusBarProps, IStatusBarStyle, IStatusBarAnimation, IStatusBarImperative, } from './status-bar/shared';
94
- export { registerHostBehavior, hasHostBehaviors, hostBehaviorFor, clearHostBehaviors, appListenerFor, addDerivedNode, } from './host-behavior';
102
+ export { registerHostBehavior, hasHostBehaviors, hostBehaviorFor, clearHostBehaviors, appListenerFor, addDerivedNode, SLOT_DERIVED_ALL, } from './host-behavior';
95
103
  export type { IClaimMode, IHostBehavior, IPayloadFold } from './host-behavior';
96
- export { requestCommitFor } from './commit';
97
104
  export { setBehaviorListener, markPropsDirty } from './node';
package/build/index.js CHANGED
@@ -7,7 +7,25 @@ export { createElement, createRawText, createAnchor,
7
7
  // Exported so a PRIMITIVE that renders no view of its own can be born with it — RN's
8
8
  // TouchableNativeFeedback clones onto its single child and commits nothing
9
9
  // (TouchableNativeFeedback.js:339) — rather than being converted after the fact.
10
- ANCHOR_COMPONENT, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle, setNodeHidden, setNodeComponent, setNodePressed, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node.js';
10
+ ANCHOR_COMPONENT, isAnchor, createVoid,
11
+ // The component name of a node whose ENTIRE subtree the commit walk drops — unlike
12
+ // `ANCHOR_COMPONENT`, which hoists its children up in its place, a void node contributes neither
13
+ // itself nor them. For a primitive whose whole component renders nothing on this platform —
14
+ // `input-accessory-view` on Android, `InputAccessoryView.js`'s `return null`.
15
+ VOID_COMPONENT, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle,
16
+ // Exported for the ONE adapter that has to build style objects rather than receive them: Angular's
17
+ // `ɵɵstyleMap` hands over keys, so its renderer allocates a fresh object per node and needs to
18
+ // recognise one it has already published. A second copy of this comparator in the adapter is the
19
+ // mirror shape this codebase deletes on sight — and its deliberate conservatism (a nested value
20
+ // reports "not the same") is exactly right for that use too.
21
+ isSameShallowStyle, getPublishedStyle, setNodeHidden, setNodeComponent, setNodePressed, setNodeUnderlayShown, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, takePropKeyTally, } from './node.js';
22
+ // Host access — the DOM read half Fabric does not ship. Adapters route their seam's
23
+ // parentNode/nextSibling/firstChild through these instead of reading a node's fields, which is
24
+ // what keeps the retained tree's shape ours to change (symbiote-fabric-cxx-surface §9).
25
+ export { parentOf, childrenOf, firstChildOf, nextSiblingOf, isTextContainer, isRawTextNode, componentOf, textOf, propOf, propsOf,
26
+ // A TEST read, exported off the package root because the itest fixtures reach it that way — the
27
+ // real payload builder lives in C++ and this is the only complete view of what it produced.
28
+ committedPayloadOf, } from './host-access.js';
11
29
  // For a HOST BEHAVIOR that owns an animated style layer on its own node — TouchableOpacity's press
12
30
  // fade, which RN drives from an `Animated.View` the tag replaces.
13
31
  export { setAnimatedBehaviorStyle } from './animated/host-binding.js';
@@ -24,7 +42,23 @@ export { InteractionManager, Events as InteractionManagerEvents, } from './inter
24
42
  export { default as PanResponder } from './pan-responder/index.js';
25
43
  export { SymbioteSurface, createSurface } from './surface.js';
26
44
  export { setEventDispatcher } from './dispatch.js';
27
- export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, readCommitProfile, } from './commit.js';
45
+ // `setColorProcessor` / `processColor` were only RE-exported by the old `commit.ts`; they point at
46
+ // their real home now.
47
+ export { setColorProcessor, processColor } from './platform-color/index.js';
48
+ export { dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, requestCommitFor, } from './imperative.js';
49
+ // The tree host: the seam a runtime installs to answer about the tree JS does not hold. `setTreeHost`
50
+ // is what `installFabric()` (@symbiote-native/test-utils) calls with the TypeScript applier.
51
+ export { setTreeHost, treeHost, registerBeforeFlush, readCommitProfile, readSurfaceTelemetry, setNativeDebug, takeNativeDebugLog, } from './tree-host.js';
52
+ // The native host, exported for the same audience as `setTreeHost` — a HOST author, not an app.
53
+ // `installNativeTreeHost` is not on any app path: `getSlot()` already calls it, and it is here so a
54
+ // bring-up probe can install one explicitly against a hand-built set of bindings.
55
+ export { nativeTreeHost, installNativeTreeHost } from './native-tree-host.js';
56
+ // The OPCODES and the recorder are deliberately NOT here. They are the wire contract between this
57
+ // package and whatever implements the tree, so their audience is a HOST author — the C++ and the
58
+ // TypeScript applier — not an app. They live on the `@symbiote-native/engine/mutation-buffer`
59
+ // subpath, for the same reason `state-style` does: a name on this barrel is public API on all five
60
+ // adapters at once, with no edit to any of them
61
+ // (`.claude/rules/adapter-parity-audit.md`, "A build-tool-facing symbol belongs on a SUBPATH").
28
62
  // "A commit just reached completeRoot." The one seam that means the same thing under every
29
63
  // adapter: React commits synchronously inside its own commit phase, while Vue / Svelte / Angular
30
64
  // schedule completeRoot on a microtask, so each framework's own after-render hook fires at a
@@ -32,10 +66,14 @@ export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibility
32
66
  // across adapters has to hang off this, not off a per-framework lifecycle hook, or it measures a
33
67
  // different quantity in each one under the same name.
34
68
  export { registerPostCommit, unregisterPostCommit } from './post-commit.js';
35
- // The aria/role -> accessibility* fold. Lives here rather than in a component wrapper because a
36
- // LOWERED element has no wrapper: `fabricProps` runs it on the way to the payload, so every path
37
- // gets it. `core/components`' typed `resolveAccessibilityProps` delegates to this one.
69
+ // The aria/role -> accessibility* fold. Lives here rather than in a component wrapper because a tag
70
+ // has none: `fabricProps` runs it on the way to the payload, so every path gets it.
71
+ // `core/components`' typed `resolveAccessibilityProps` delegates to this one.
38
72
  export { ARIA_ALIAS_KEYS, foldAriaProps } from './accessibility-props.js';
73
+ // The payload builder, exported for the HOST rather than for an app: the engine holds no tree, so
74
+ // whoever built the bag calls this on the way to `createNode`. Headlessly that is the TypeScript
75
+ // applier; on device it will be the C++ one, which does not have it yet.
76
+ export { fabricProps } from './fabric-props.js';
39
77
  // The public instance every host node already is (React's getPublicInstance, the Vue renderer's
40
78
  // createElement): the imperative measure/setNativeProps/focus API, on the shared node prototype.
41
79
  // toPublicInstance is the identity that names the seam — see ./host-instance.
@@ -61,6 +99,10 @@ export { getNativeModule, getEnforcingNativeModule } from './native-modules/inde
61
99
  export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource, } from './native-events.js';
62
100
  export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, createAnimatedLeafLifecycle, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated/index.js';
63
101
  export { getSlot } from './fabric.js';
102
+ // Test seam, not app API: forget the bound slot so a
103
+ // fixture can install a different host and be believed. Exported now that the harness lives in
104
+ // another package (`@symbiote-native/test-utils`) and can no longer reach `./fabric` directly.
105
+ export { resetSlot } from './fabric.js';
64
106
  // Imperative runtime modules: framework-agnostic native-bridge consumers (no visual, no
65
107
  // lifecycle), moved here from @symbiote-native/react so every adapter re-exports the SAME module.
66
108
  // The native module a JS API talks to is chosen per platform and can only be confirmed on a
@@ -76,6 +118,7 @@ export { ActionSheetIOS } from './action-sheet-ios/index.js';
76
118
  export { Linking } from './linking';
77
119
  export { Vibration } from './vibration';
78
120
  export { ToastAndroid } from './toast-android/index.js';
121
+ export { SoundManager } from './sound-manager/index.js';
79
122
  export { Settings } from './settings/index.js';
80
123
  export { I18nManager } from './i18n-manager/index.js';
81
124
  // Device-state / event modules (Dimensions, Appearance, AppState, Keyboard, …).
@@ -90,7 +133,7 @@ export { AppState } from './app-state/index.js';
90
133
  // framework-specific seam — how to build a runnable from a component provider).
91
134
  export { createAppRegistry } from './app-registry/index.js';
92
135
  export { Keyboard, KEYBOARD_EVENT } from './keyboard/index.js';
93
- export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from './text-input-state.js';
136
+ export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, focusTextInput, } from './text-input-state.js';
94
137
  export { LayoutAnimation } from './layout-animation/index.js';
95
138
  export { BackHandler } from './back-handler/index.js';
96
139
  export { PermissionsAndroid, PERMISSIONS, RESULTS, } from './permissions-android/index.js';
@@ -99,10 +142,10 @@ export { AccessibilityInfo } from './accessibility-info';
99
142
  // .ios re-export would otherwise duplicate-export the type symbols).
100
143
  export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from './status-bar';
101
144
  export { hideTransition, STATUS_BAR_MANAGER, ANIMATED_HIDE_TRANSITION, STATIC_HIDE_TRANSITION, } from './status-bar/shared.js';
102
- export { registerHostBehavior, hasHostBehaviors, hostBehaviorFor, clearHostBehaviors, appListenerFor, addDerivedNode, } from './host-behavior.js';
103
- export { requestCommitFor } from './commit.js';
145
+ export { registerHostBehavior, hasHostBehaviors, hostBehaviorFor, clearHostBehaviors, appListenerFor, addDerivedNode, SLOT_DERIVED_ALL, } from './host-behavior.js';
104
146
  // `markPropsDirty` is a behavior's only way to say "the fold reads state I just changed". Every
105
147
  // other dirtying route goes through a prop write, and a behavior whose payload is DERIVED — the
106
- // sticky header's debounced translateY lives in its own runtime, not in `node.props` — has no
107
- // prop to write. Pair it with `requestCommitFor`: dirtying is not publishing.
148
+ // sticky header's debounced translateY lives in its own runtime, not in the node's props — has no
149
+ // prop to write. Pair it with `requestCommitFor` (exported off `./imperative` above): dirtying is
150
+ // not publishing.
108
151
  export { setBehaviorListener, markPropsDirty } from './node.js';