@symbiote-native/engine 1.3.0 → 1.3.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.
- package/build/accessibility-props.d.ts +0 -11
- package/build/accessibility-props.js +30 -68
- package/build/animated/graph.js +1 -1
- package/build/animated/leaf-lifecycle.js +2 -2
- package/build/asset-source-resolver.d.ts +2 -0
- package/build/asset-source-resolver.js +13 -0
- package/build/back-handler/index.d.ts +1 -5
- package/build/back-handler/index.js +0 -6
- package/build/debug.js +8 -22
- package/build/dispatch.js +3 -9
- package/build/events/index.js +2 -2
- package/build/fabric-props.js +74 -179
- package/build/fabric.d.ts +0 -13
- package/build/fabric.js +18 -38
- package/build/host-access.d.ts +1 -128
- package/build/host-access.js +96 -205
- package/build/host-behavior.d.ts +0 -100
- package/build/host-behavior.js +125 -311
- package/build/image-loader.js +10 -23
- package/build/image-source-resolver.js +3 -7
- package/build/image-source-write.d.ts +0 -11
- package/build/image-source-write.js +14 -34
- package/build/imperative.d.ts +0 -28
- package/build/imperative.js +42 -92
- package/build/index.d.ts +1 -0
- package/build/index.js +24 -37
- package/build/mutation-buffer.d.ts +0 -177
- package/build/mutation-buffer.js +137 -308
- package/build/native-engine.d.ts +0 -102
- package/build/native-engine.js +38 -98
- package/build/native-events.js +9 -18
- package/build/native-tree-host.d.ts +0 -21
- package/build/native-tree-host.js +14 -31
- package/build/node.d.ts +0 -212
- package/build/node.js +338 -774
- package/build/post-commit.js +3 -8
- package/build/process-aspect-ratio.js +3 -7
- package/build/process-background-longhands.js +10 -19
- package/build/process-filter.js +11 -19
- package/build/process-font-variant.js +3 -7
- package/build/registry.d.ts +0 -33
- package/build/registry.js +22 -57
- package/build/report-error.js +4 -18
- package/build/structured-style.d.ts +0 -9
- package/build/structured-style.js +16 -31
- package/build/styles.js +3 -6
- package/build/surface.d.ts +0 -26
- package/build/surface.js +29 -76
- package/build/text-input-state.js +4 -8
- package/build/touch-history.js +5 -11
- package/build/tree-host.d.ts +0 -270
- package/build/tree-host.js +63 -153
- package/build/view-config.js +17 -37
- package/package.json +2 -2
package/build/node.d.ts
CHANGED
|
@@ -20,55 +20,15 @@ export interface ISymbioteNode {
|
|
|
20
20
|
component: string;
|
|
21
21
|
readonly isText: boolean;
|
|
22
22
|
listeners: Map<string, IListener> | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* Whether this node's host behavior declared `afterCommit`.
|
|
25
|
-
*
|
|
26
|
-
* Read on every prop write, exactly as `hasAriaAlias` beside it is and for the same reason: the
|
|
27
|
-
* alternative is a Set lookup per write, on the hottest path in the engine. What it gates is the
|
|
28
|
-
* NARROWING of the post-commit beat — the hook runs for nodes whose props moved rather than for
|
|
29
|
-
* every mounted behavior, which is what took TextInput's `propOf` off every commit (F-67).
|
|
30
|
-
*
|
|
31
|
-
* Set once at `createElement`, by `attachHostBehavior`. Not sticky in the `hasAriaAlias` sense:
|
|
32
|
-
* it describes the behavior's shape, and a behavior is attached once and detached whole.
|
|
33
|
-
*/
|
|
34
23
|
hasCommitHook: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Whether this node's three image-source props are resolved on the way IN — see
|
|
37
|
-
* `image-source-write.ts` for why the asset lookup happens at write time and not in the payload.
|
|
38
|
-
*
|
|
39
|
-
* A boolean read per write, same shape and same reason as `hasCommitHook` above. It has to be
|
|
40
|
-
* gated on the NODE rather than applied to the key everywhere, because the resolution normalises
|
|
41
|
-
* to Image's ARRAY shape: a `WebView` or a third-party video view also spells `source`, and
|
|
42
|
-
* wrapping theirs would hand native a shape it does not read.
|
|
43
|
-
*
|
|
44
|
-
* Set once at `createElement`, by `attachHostBehavior`, for the behavior that declares it.
|
|
45
|
-
*/
|
|
46
24
|
resolvesImageSources: boolean;
|
|
47
25
|
nativeIdWinsOverId: boolean;
|
|
48
26
|
payloadFold: IPayloadFold | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* The behavior that attached to this node, or `undefined` for the vast majority that have none.
|
|
51
|
-
*
|
|
52
|
-
* A field for the same reason `payloadFold` above it is one, and set on the same line: every
|
|
53
|
-
* reader is a per-node path at list scale — the teardown sweep touches every node of a removed
|
|
54
|
-
* subtree, and `routeProp`'s slot/owned-listener questions run per prop write. A `WeakMap` probe
|
|
55
|
-
* is the dearest way to ask a question whose answer is almost always "none".
|
|
56
|
-
*
|
|
57
|
-
* Owned by `host-behavior.ts`; `attachHostBehavior` is the only writer.
|
|
58
|
-
*/
|
|
59
27
|
hostBehavior: IHostBehavior | undefined;
|
|
60
28
|
styleParts: IClassStyleParts | undefined;
|
|
61
29
|
childHost: ISymbioteNode | undefined;
|
|
62
30
|
wrapper: ISymbioteNode | undefined;
|
|
63
31
|
mayHaveChildren: boolean;
|
|
64
|
-
/**
|
|
65
|
-
* Whether the teardown sweep has released this node and not seen it come back.
|
|
66
|
-
*
|
|
67
|
-
* Owned by `host-behavior.ts` — see `detachOne` / `reattachHostBehaviors`. A field rather than
|
|
68
|
-
* the `WeakSet` it was, because the sweep reads and writes it for EVERY node of a removed
|
|
69
|
-
* subtree (ten thousand on a thousand-row clear) and every insert reads it to decide whether to
|
|
70
|
-
* walk at all, which is the ~9 000-call path of a create.
|
|
71
|
-
*/
|
|
72
32
|
isTornDown: boolean;
|
|
73
33
|
slot: number;
|
|
74
34
|
slotBatch: number;
|
|
@@ -88,26 +48,7 @@ export interface ISymbioteNode {
|
|
|
88
48
|
}): void;
|
|
89
49
|
flashScrollIndicators(): void;
|
|
90
50
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Mint an element and record its creation.
|
|
93
|
-
*
|
|
94
|
-
* The node object IS the handle: it is what the ops address, what the host attaches its native node
|
|
95
|
-
* to, and what Fabric hands back as an event target. Nothing else is allocated.
|
|
96
|
-
*/
|
|
97
51
|
export declare function createElement(component: string, isText?: boolean, tag?: string): ISymbioteNode;
|
|
98
|
-
/**
|
|
99
|
-
* `tag` mirrors `createElement`'s, and a raw text needs it for the same reason an element does: the
|
|
100
|
-
* behavior registry is keyed by tag, so a node that does not hand one over cannot have a rule.
|
|
101
|
-
*
|
|
102
|
-
* A raw text carrying a tag looks odd and is not. It has no props an app can write — its whole
|
|
103
|
-
* payload is `text` — but its CONTENT can still be a function of the platform rather than of the
|
|
104
|
-
* app: Button renders its title uppercased on Android (`Button.js:352-353`), which is a user-agent
|
|
105
|
-
* decision about a control, not anything the app asked for. That rule needs the node to be
|
|
106
|
-
* identifiable, and a tag is how this codebase identifies one.
|
|
107
|
-
*
|
|
108
|
-
* Defaulted to the raw-text component, so every existing caller is unchanged and pays the same
|
|
109
|
-
* lookup miss `createElement` already pays for a node nobody registered.
|
|
110
|
-
*/
|
|
111
52
|
export declare function createRawText(text: string, tag?: string): ISymbioteNode;
|
|
112
53
|
export declare function isSymbioteNode(value: unknown): value is ISymbioteNode;
|
|
113
54
|
export declare function debugNodeId(node: ISymbioteNode): number;
|
|
@@ -115,91 +56,20 @@ export declare const ANCHOR_COMPONENT = "#anchor";
|
|
|
115
56
|
export declare function createAnchor(): ISymbioteNode;
|
|
116
57
|
export declare const VOID_COMPONENT = "#void";
|
|
117
58
|
export declare function createVoid(): ISymbioteNode;
|
|
118
|
-
/**
|
|
119
|
-
* The sentinel a SURFACE's own root node carries, so `parentOf` can stop there.
|
|
120
|
-
*
|
|
121
|
-
* A top-level node must answer `undefined` for its parent, and adapters depend on the exact miss:
|
|
122
|
-
* Angular reads `null` as "defer, `<ng-content>` will place this" (answering the surface once
|
|
123
|
-
* mounted every FlatList cell at top level), while Vue and Solid spell `?? surface` at their call
|
|
124
|
-
* sites and would be handed an object that is not the `SymbioteSurface` they compare against. One
|
|
125
|
-
* component name, read in JS, keeps all three right without a second structure.
|
|
126
|
-
*
|
|
127
|
-
* It is a JS-side name only. What goes over the wire is `RCTView`, because this node is REAL.
|
|
128
|
-
*/
|
|
129
59
|
export declare const SURFACE_COMPONENT = "#surface";
|
|
130
|
-
/**
|
|
131
|
-
* One persistent root view per surface, mirroring RN's own AppContainer — `renderApplication` wraps
|
|
132
|
-
* the app in `<View style={{flex:1}} pointerEvents="box-none">`.
|
|
133
|
-
*
|
|
134
|
-
* It is not decoration. Without `flex: 1` a non-flex root collapses to content height, and without
|
|
135
|
-
* `box-none` a touch landing outside the app's own children has no escape. Living here rather than
|
|
136
|
-
* in each adapter's `mount()` gives every framework a full-screen root for free and keeps layout in
|
|
137
|
-
* the shared layer (`<adapters_stay_thin>`).
|
|
138
|
-
*
|
|
139
|
-
* The surface therefore commits as ONE node rather than hoisting its children into the child set —
|
|
140
|
-
* which is why the host materializes the node `OP_COMMIT` names instead of walking its children. An
|
|
141
|
-
* anchor in that position still hoists, so the host handles both without a special case.
|
|
142
|
-
*/
|
|
143
60
|
export declare function createSurfaceRoot(): ISymbioteNode;
|
|
144
61
|
export declare function isAnchor(node: ISymbioteNode): boolean;
|
|
145
|
-
/**
|
|
146
|
-
* Change which Fabric view a node commits as, keeping the node's identity.
|
|
147
|
-
*
|
|
148
|
-
* The POLICY stays out of the engine: which prop decides, and which view it decides between, lives
|
|
149
|
-
* in `HOST_PRIMITIVES` and is read by `resolveIntrinsicTag` in `@symbiote-native/components`. The
|
|
150
|
-
* engine only knows how to swap the name — the same split every other spec-driven fold has here.
|
|
151
|
-
*
|
|
152
|
-
* A no-op when the name is unchanged, so a renderer may call it on every update without comparing
|
|
153
|
-
* first.
|
|
154
|
-
*
|
|
155
|
-
* The JS field and the op BOTH move, and both are load-bearing. `node.component` is what the aria
|
|
156
|
-
* fold, the behavior registry and `fabricProps` key on; the op is what makes the host re-create the
|
|
157
|
-
* node under the new name, since no prop write moves a node between native views.
|
|
158
|
-
*/
|
|
159
62
|
export declare function setNodeComponent(node: ISymbioteNode, component: string): void;
|
|
160
63
|
export declare function takePropStats(): {
|
|
161
64
|
writes: number;
|
|
162
65
|
};
|
|
163
66
|
export declare function takePropKeyTally(): ReadonlyMap<string, number>;
|
|
164
67
|
export declare function setProp(node: ISymbioteNode, key: string, value: unknown): void;
|
|
165
|
-
/**
|
|
166
|
-
* The one place a prop reaches the wire, and the only place that can keep a function off it.
|
|
167
|
-
*
|
|
168
|
-
* `setNativeProps` calls this rather than `recordSetProp` for that reason — it is the path that has
|
|
169
|
-
* no `routeProp` in front of it.
|
|
170
|
-
*/
|
|
171
68
|
export declare function writeProp(node: ISymbioteNode, key: string, value: unknown): void;
|
|
172
69
|
/** What `propOf` consults before asking the host. `undefined` when nothing was stashed. */
|
|
173
70
|
export declare function functionPropOf(node: ISymbioteNode, key: string): unknown;
|
|
174
|
-
/**
|
|
175
|
-
* The same stash, whole — what `propsOf` layers over the host's answer.
|
|
176
|
-
*
|
|
177
|
-
* `undefined` rather than an empty Map for a node that stashed nothing, which is nearly every node:
|
|
178
|
-
* the caller then hands back the host's own object instead of copying it.
|
|
179
|
-
*/
|
|
180
71
|
export declare function functionPropsOf(node: ISymbioteNode): ReadonlyMap<string, unknown> | undefined;
|
|
181
|
-
/**
|
|
182
|
-
* "Rebuild this node's payload — the fold reads state I just changed."
|
|
183
|
-
*
|
|
184
|
-
* A behavior whose payload is DERIVED has no prop to write: the sticky header's debounced
|
|
185
|
-
* translateY lives in its own runtime, not on the node, so nothing names the node and the host
|
|
186
|
-
* never marks it. This is the one route that says so directly.
|
|
187
|
-
*
|
|
188
|
-
* Dirtying is not publishing — pair it with `requestCommitFor` (imperative.ts).
|
|
189
|
-
*/
|
|
190
72
|
export declare function markPropsDirty(node: ISymbioteNode): void;
|
|
191
|
-
/**
|
|
192
|
-
* Install a listener the BEHAVIOR owns, bypassing the ownership check.
|
|
193
|
-
*
|
|
194
|
-
* `setEventListener` diverts an owned name into the stash, which is right for an app listener and
|
|
195
|
-
* circular for the behavior's own dispatcher — it would stash itself and never occupy the slot it
|
|
196
|
-
* exists to hold. This is the one writer allowed past that gate.
|
|
197
|
-
*
|
|
198
|
-
* `undefined` removes it, gate flag included. A behavior whose dispatcher is conditional needs
|
|
199
|
-
* that as much as it needs the install: ScrollView takes the owner's `layout` only while the app
|
|
200
|
-
* or an inverted sticky header wants it, and a one-way installer leaves `onLayout: true` standing
|
|
201
|
-
* in the payload of a ScrollView that no longer reads the event.
|
|
202
|
-
*/
|
|
203
73
|
export declare function setBehaviorListener(node: ISymbioteNode, name: string, listener: IListener | undefined): void;
|
|
204
74
|
export declare function setEventListener(node: ISymbioteNode, name: string, value: unknown): void;
|
|
205
75
|
export interface IClassStyleParts {
|
|
@@ -212,84 +82,12 @@ export interface IClassStyleParts {
|
|
|
212
82
|
activeStyleFromCallback: boolean;
|
|
213
83
|
published: readonly unknown[] | undefined;
|
|
214
84
|
}
|
|
215
|
-
/**
|
|
216
|
-
* Is this rebuilt style the same style, key for key?
|
|
217
|
-
*
|
|
218
|
-
* A component body that writes its style inline hands over a FRESH object every render, equal to
|
|
219
|
-
* the one already standing — the commonest shape any app produces, and one `Object.is` cannot see.
|
|
220
|
-
* Without this the write crosses into the host, becomes a `folly::dynamic`, and is only THEN found
|
|
221
|
-
* to be unchanged. Measured on `build-release` (`no-op-rerender-cost.itest.ts`), 1 000 rows
|
|
222
|
-
* re-rendered with nothing changed: 9.7 ms against 0.3 ms for the same app with its style hoisted,
|
|
223
|
-
* and 5.2 ms of that was the conversion. The cheapest place to refuse a write is the earliest place
|
|
224
|
-
* that can see it is a no-op.
|
|
225
|
-
*
|
|
226
|
-
* SHALLOW AND CONSERVATIVE, both deliberately. A nested value (a transform list, a shadow, a style
|
|
227
|
-
* array) reports "not the same" rather than being compared deeply, because a deep compare makes this
|
|
228
|
-
* guard cost the size of the style — which is the cost it exists to avoid. Those keep crossing and
|
|
229
|
-
* the host's own `diffProps` refuses them exactly as before, so being wrong here is slow, never
|
|
230
|
-
* incorrect.
|
|
231
|
-
*
|
|
232
|
-
* `undefined` on either side also reports "not the same", which is what lets the key COUNT stand in
|
|
233
|
-
* for a key-set comparison: equal counts plus every key of `next` matching a defined value in
|
|
234
|
-
* `standing` cannot leave a key unaccounted for.
|
|
235
|
-
*/
|
|
236
85
|
export declare function isSameShallowStyle(next: unknown, standing: unknown): boolean;
|
|
237
|
-
/**
|
|
238
|
-
* Stop a node painting without unmounting it, or let it paint again.
|
|
239
|
-
*
|
|
240
|
-
* The seam React's `Activity`/`Suspense` reach for through `hideInstance`/`unhideInstance`. It
|
|
241
|
-
* lives in the engine rather than an adapter because the reversibility problem — restoring the
|
|
242
|
-
* author's style byte for byte — belongs to whoever owns the style merge, and that is here.
|
|
243
|
-
*/
|
|
244
86
|
export declare function setNodeHidden(node: ISymbioteNode, hidden: boolean): void;
|
|
245
|
-
/**
|
|
246
|
-
* Put a node into (or out of) its pressed state, so `.x:active` rules apply.
|
|
247
|
-
*
|
|
248
|
-
* The engine-owned half of what `:active` is on the web: the press state resolves BELOW the
|
|
249
|
-
* framework and never crosses into it, which is what lets a pressable be an intrinsic tag rather
|
|
250
|
-
* than a component (`.claude/rules/host-primitive-tier.md`, tier 2). A component is forced only
|
|
251
|
-
* when the TEMPLATE must read the state — `v-slot="{ pressed }"` and the function form of `style`
|
|
252
|
-
* — and this exists so the common case does not have to.
|
|
253
|
-
*
|
|
254
|
-
* Costs nothing when no `:active` rule is registered anywhere: `resolveActiveClassName` hands back
|
|
255
|
-
* the very same object the unpressed path returns, so `isAlreadyPublished` turns the re-push away
|
|
256
|
-
* and the node is never dirtied.
|
|
257
|
-
*/
|
|
258
87
|
export declare function setNodePressed(node: ISymbioteNode, pressed: boolean): void;
|
|
259
|
-
/**
|
|
260
|
-
* Tell the host a behavior's FEEDBACK is showing — TouchableHighlight's underlay, and only that.
|
|
261
|
-
*
|
|
262
|
-
* The sibling of `setNodePressed` and deliberately NOT the same bit. Press state drives `:active`
|
|
263
|
-
* class resolution, which happens in JS because a class name resolves against a JS registry; this
|
|
264
|
-
* drives a rule that lives in C++ (`foldTouchableHighlightUnderlay`), so it crosses as one op rather
|
|
265
|
-
* than resolving to a style here. And the two are genuinely different facts: RN holds the underlay
|
|
266
|
-
* past release so a fast tap still flashes, so `shown` LAGS `pressed` by a `delayPressOut` timer.
|
|
267
|
-
*
|
|
268
|
-
* No style is computed on this side at all, which is the whole point — the two props the rule reads
|
|
269
|
-
* (`underlayColor`, `activeOpacity`) are ones the engine already strips from the payload, so the
|
|
270
|
-
* values and their defaults live in one place instead of being erased in C++ and reached around for
|
|
271
|
-
* in JS.
|
|
272
|
-
*/
|
|
273
88
|
export declare function setNodeUnderlayShown(node: ISymbioteNode, shown: boolean): void;
|
|
274
|
-
/**
|
|
275
|
-
* Forget what was last published, so the next `pushClassStyle` cannot be turned away.
|
|
276
|
-
*
|
|
277
|
-
* The one caller is `setNativeProps` (imperative.ts), which writes the style slot past this file —
|
|
278
|
-
* see the note on `IClassStyleParts.published` for why the restore path depends on this. A no-op for
|
|
279
|
-
* a node nobody has styled, which is why it is not `stylePartsOf(node).published = undefined`: that
|
|
280
|
-
* would allocate the parts on a node that has none.
|
|
281
|
-
*/
|
|
282
89
|
export declare function clearPublishedStyle(node: ISymbioteNode): void;
|
|
283
90
|
export declare function getExplicitStyle(node: ISymbioteNode): unknown;
|
|
284
|
-
/**
|
|
285
|
-
* The `[classStyle, explicitStyle]` pair the node currently PUBLISHES — the same value
|
|
286
|
-
* `commitClassStyle` writes, in the same order, so `flattenStyle` collapses it the way Fabric will.
|
|
287
|
-
*
|
|
288
|
-
* For a caller that wants the merged answer without a host: the pair reaches the payload as an op,
|
|
289
|
-
* and only a host holds ops. A test that has not installed one — `core/css-parser` reaches into the
|
|
290
|
-
* engine by relative path and depends on neither package — can read it here instead of reaching
|
|
291
|
-
* into `styleParts`, which is engine-owned and not a shape anything outside may bind to.
|
|
292
|
-
*/
|
|
293
91
|
export declare function getPublishedStyle(node: ISymbioteNode): readonly unknown[];
|
|
294
92
|
export declare function routeProp(node: ISymbioteNode, key: string, value: unknown): void;
|
|
295
93
|
export declare function setText(node: ISymbioteNode, text: string): void;
|
|
@@ -297,14 +95,4 @@ export declare function appendChild(requestedParent: ISymbioteNode, child: ISymb
|
|
|
297
95
|
export declare function insertBefore(requestedParent: ISymbioteNode, child: ISymbioteNode, beforeChild: ISymbioteNode | null | undefined): void;
|
|
298
96
|
export declare function removeChild(requestedParent: ISymbioteNode, child: ISymbioteNode): void;
|
|
299
97
|
export type { ITreeCensus } from './tree-host';
|
|
300
|
-
/**
|
|
301
|
-
* A structural census of the tree the HOST holds — see `ITreeCensus` (tree-host.ts) for what each
|
|
302
|
-
* number is for and why the anchor count says more about the adapter than about the app.
|
|
303
|
-
*
|
|
304
|
-
* It walks nothing here: the walk needs `props.text` to tell an empty raw text from a real one, and
|
|
305
|
-
* a child list to measure a flatten width, and JS has neither. `undefined` from `treeHost()` means
|
|
306
|
-
* nothing is installed, and the empty census is the honest answer — every probe that reads this
|
|
307
|
-
* asserts against a mounted tree, so a zero from an uninstalled host cannot be mistaken for one from
|
|
308
|
-
* an empty one.
|
|
309
|
-
*/
|
|
310
98
|
export declare function censusRetainedTree(roots: readonly ISymbioteNode[]): ITreeCensus;
|