@symbiote-native/engine 1.2.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.
Files changed (110) hide show
  1. package/android/CMakeLists.txt +31 -1
  2. package/android/build.gradle +4 -1
  3. package/build/accessibility-info/index.android.js +21 -17
  4. package/build/accessibility-info/index.ios.js +2 -0
  5. package/build/accessibility-info/shared.d.ts +1 -1
  6. package/build/accessibility-props.d.ts +0 -11
  7. package/build/accessibility-props.js +30 -68
  8. package/build/alert/shared.d.ts +1 -1
  9. package/build/alert/shared.js +3 -7
  10. package/build/animated/graph.js +1 -1
  11. package/build/animated/leaf-lifecycle.js +2 -2
  12. package/build/app-state/index.d.ts +1 -1
  13. package/build/app-state/index.js +35 -27
  14. package/build/asset-source-resolver.d.ts +2 -0
  15. package/build/asset-source-resolver.js +13 -0
  16. package/build/back-handler/index.d.ts +7 -6
  17. package/build/back-handler/index.js +19 -16
  18. package/build/debug.js +8 -22
  19. package/build/dispatch.js +3 -9
  20. package/build/events/index.js +12 -3
  21. package/build/fabric-props.js +75 -180
  22. package/build/fabric.d.ts +2 -8
  23. package/build/fabric.js +27 -33
  24. package/build/host-access.d.ts +1 -128
  25. package/build/host-access.js +96 -205
  26. package/build/host-behavior.d.ts +1 -100
  27. package/build/host-behavior.js +125 -311
  28. package/build/image-loader.d.ts +4 -2
  29. package/build/image-loader.js +24 -48
  30. package/build/image-source-resolver.js +3 -7
  31. package/build/image-source-write.d.ts +1 -12
  32. package/build/image-source-write.js +28 -36
  33. package/build/imperative.d.ts +0 -28
  34. package/build/imperative.js +42 -92
  35. package/build/index.d.ts +3 -2
  36. package/build/index.js +30 -43
  37. package/build/invariant.d.ts +1 -0
  38. package/build/invariant.js +10 -0
  39. package/build/keyboard/index.js +11 -32
  40. package/build/linking/index.android.js +5 -3
  41. package/build/linking/shared.d.ts +1 -1
  42. package/build/linking/shared.js +16 -19
  43. package/build/mutation-buffer.d.ts +0 -177
  44. package/build/mutation-buffer.js +137 -308
  45. package/build/native-engine.d.ts +0 -102
  46. package/build/native-engine.js +38 -98
  47. package/build/native-events.d.ts +5 -0
  48. package/build/native-events.js +30 -18
  49. package/build/native-tree-host.d.ts +0 -21
  50. package/build/native-tree-host.js +14 -31
  51. package/build/node.d.ts +0 -212
  52. package/build/node.js +354 -774
  53. package/build/permissions-android/index.android.d.ts +59 -0
  54. package/build/permissions-android/index.android.js +47 -0
  55. package/build/permissions-android/index.d.ts +1 -115
  56. package/build/permissions-android/index.ios.d.ts +59 -0
  57. package/build/permissions-android/index.ios.js +31 -0
  58. package/build/permissions-android/index.js +3 -184
  59. package/build/permissions-android/shared.d.ts +63 -0
  60. package/build/permissions-android/shared.js +66 -0
  61. package/build/platform/index.android.js +3 -5
  62. package/build/platform/index.ios.js +3 -3
  63. package/build/platform/shared.d.ts +4 -0
  64. package/build/platform/shared.js +9 -0
  65. package/build/platform-color/index.android.d.ts +4 -0
  66. package/build/platform-color/index.android.js +7 -0
  67. package/build/platform-color/index.d.ts +2 -20
  68. package/build/platform-color/index.js +1 -45
  69. package/build/platform-color/shared.d.ts +21 -0
  70. package/build/platform-color/shared.js +41 -0
  71. package/build/post-commit.js +3 -8
  72. package/build/process-aspect-ratio.js +3 -7
  73. package/build/process-background-longhands.js +10 -19
  74. package/build/process-filter.js +11 -19
  75. package/build/process-font-variant.js +3 -7
  76. package/build/registry.d.ts +0 -33
  77. package/build/registry.js +22 -57
  78. package/build/report-error.js +4 -18
  79. package/build/settings/index.android.d.ts +6 -0
  80. package/build/settings/index.android.js +21 -0
  81. package/build/settings/index.d.ts +1 -8
  82. package/build/settings/index.ios.d.ts +8 -0
  83. package/build/settings/index.ios.js +122 -0
  84. package/build/settings/index.js +3 -122
  85. package/build/share/index.android.js +9 -32
  86. package/build/share/index.ios.js +14 -15
  87. package/build/share/shared.d.ts +4 -2
  88. package/build/share/shared.js +7 -10
  89. package/build/status-bar/index.android.js +1 -1
  90. package/build/status-bar/index.ios.js +4 -3
  91. package/build/structured-style.d.ts +0 -9
  92. package/build/structured-style.js +16 -31
  93. package/build/styles.js +3 -6
  94. package/build/surface.d.ts +0 -26
  95. package/build/surface.js +29 -76
  96. package/build/text-input-state.js +4 -8
  97. package/build/toast-android/index.android.d.ts +10 -0
  98. package/build/toast-android/index.android.js +108 -0
  99. package/build/toast-android/index.d.ts +1 -10
  100. package/build/toast-android/index.ios.d.ts +10 -0
  101. package/build/toast-android/index.ios.js +19 -0
  102. package/build/toast-android/index.js +3 -108
  103. package/build/touch-history.js +5 -11
  104. package/build/tree-host.d.ts +0 -270
  105. package/build/tree-host.js +63 -153
  106. package/build/view-config.js +17 -37
  107. package/cpp/SymbioteFabricProps.cpp +204 -120
  108. package/cpp/SymbioteFabricProps.h +5 -0
  109. package/cpp/SymbioteTree.cpp +20 -6
  110. package/package.json +2 -2
@@ -1,27 +1,11 @@
1
1
  import type { ISymbioteNode } from './node';
2
- /**
3
- * A pure props -> props mapping a behavior applies on the way to the Fabric payload.
4
- *
5
- * It exists because a tag has no component body, and a wrapper's body is where the per-primitive
6
- * prop FOLDS live — TextInput's W3C aliases (`inputMode` -> `keyboardType`, `readOnly` ->
7
- * `editable`), Pressable's `disabled` -> `accessibilityState`. Every one of those was silently
8
- * dropped the moment the wrapper went: the raw alias reached Fabric as a key no ViewConfig
9
- * declares, so nothing threw and nothing rendered differently in a headless test — only the device
10
- * showed a numeric keyboard that never appeared.
11
- *
12
- * NOT a hook on `setProp`, for the same reason `afterCommit` is not: `setProp` is the hottest path
13
- * in the engine. This runs once per node per payload build, and only for a node whose behavior
14
- * supplied one.
15
- *
16
- * MUST be pure and MUST NOT mutate its input — `node.props` is the live bag, and the folds beside
17
- * this one return their input by identity when there is nothing to do.
18
- */
19
2
  export type IPayloadFold = (props: Readonly<Record<string, unknown>>) => Record<string, unknown>;
20
3
  export type IClaimMode = 'beside' | 'wrap';
21
4
  export interface IHostBehavior {
22
5
  readonly ownedListeners?: readonly string[];
23
6
  readonly slotProps?: Readonly<Record<string, string>>;
24
7
  readonly slotPropsExcept?: readonly string[];
8
+ readonly slotValueFor?: (slotKey: string, value: unknown) => unknown;
25
9
  readonly slotTakesNoChildren?: boolean;
26
10
  readonly slotDerived?: readonly string[];
27
11
  readonly claimedChildren?: Readonly<Record<string, IClaimMode>>;
@@ -32,64 +16,13 @@ export interface IHostBehavior {
32
16
  onOwnedListenerChange?(node: ISymbioteNode, name: string, wired: boolean): void;
33
17
  afterCommit?(node: ISymbioteNode): void;
34
18
  detach(node: ISymbioteNode): void;
35
- /**
36
- * This primitive's own prop folds. See IPayloadFold.
37
- *
38
- * NO PRODUCTION BEHAVIOR DECLARES ONE since 2026-09-18 — the sticky header's was the last, and it
39
- * is `foldStickyHeaderProps` in `SymbioteFabricProps.cpp` now. So this reads as a leftover, and
40
- * the question this codebase asks of one is what it REACHES rather than who uses it today. Two
41
- * answers, and either alone would keep it:
42
- *
43
- * - It is the JS ARM of every cost measurement in `tag-rule-cost.itest.ts`. That file prices a
44
- * rule by running it on both sides of the wire with the payloads asserted equal key by key
45
- * first; without a fold there is no second arm, and the ~9-31 us-per-node figures every port in
46
- * this migration was justified by could not be taken again.
47
- * - It is the declared seam a third-party behavior would extend. A tag rule is ours to write in
48
- * C++; a package that ships its own primitive has no such option.
49
- *
50
- * What it is NOT any more is where a Symbiote primitive puts its platform props. A new one that
51
- * reaches for this is one whose rule belongs in the engine — read `SymbioteFabricProps.h` first.
52
- */
53
19
  readonly foldPayload?: IPayloadFold;
54
- /**
55
- * Resolve `source` / `defaultSource` / `loadingIndicatorSource` on the way IN — Image's, and only
56
- * Image's. See `image-source-write.ts`.
57
- *
58
- * It is declared here rather than inferred from the tag because it is a statement about what the
59
- * primitive's props MEAN, which is exactly what a behavior is for. And it is a flag rather than a
60
- * function: `routeProp` is the hottest path in the engine, so what it can afford per write is a
61
- * boolean read on the node, not a call into a behavior.
62
- */
63
20
  readonly resolvesImageSources?: boolean;
64
- /**
65
- * Flips `id`/`nativeID` precedence to nativeID-over-id — TouchableWithoutFeedback's, and only
66
- * its. See `routeIdAlias` in `node.ts` for why the flip exists and which vendor file demands it.
67
- */
68
21
  readonly nativeIdWinsOverId?: boolean;
69
22
  }
70
23
  export declare function registerHostBehavior(component: string, behavior: IHostBehavior): void;
71
24
  export declare function hostBehaviorFor(tag: string): IHostBehavior | undefined;
72
25
  export declare function hasHostBehaviors(): boolean;
73
- /**
74
- * Has a behavior ever ATTACHED to a node, as opposed to a behavior TYPE having been registered?
75
- *
76
- * `hasBehaviors` answers the second, and it is on from module load in every app: registering
77
- * `Pressable` arms it whether or not one is ever mounted. It gates `createElement`'s attach probe
78
- * correctly — a node has to be offered to the registry to find out. It gates the TEARDOWN SWEEP
79
- * wrongly, and that is expensive: the sweep crosses every removed node into JS, which on a
80
- * 1 000-row clear is ten thousand handles. Measured on `build-release`
81
- * (`teardown-sweep-cost.itest.ts`): 1.8 ms with the sweep off against 6.3 ms with it on, i.e. 3.2x,
82
- * all of it inside the commit. `Clear` is the one row where stock React Native beats every adapter.
83
- *
84
- * Nothing the sweep does can matter before the first attach, and the four collections say so:
85
- * `node.hostBehavior` is written only by `attachHostBehavior`; `awaitingCommit` and `committedEachTime` are
86
- * written only inside a `behavior.` branch; `parked` only by `detachAnimatedProps`, which has its
87
- * own gate. The one remaining effect is marking `isTornDown`, which exists so a later re-insert knows
88
- * to re-arm — and there is nothing to re-arm.
89
- *
90
- * MONOTONE, deliberately: it turns on and never off, so it needs no accounting on a `WeakMap` that
91
- * has no size and no destructor. Being late is the only way it can be wrong, and it cannot be late.
92
- */
93
26
  export declare function hasAttachedBehaviors(): boolean;
94
27
  export declare function slotPropNameFor(node: ISymbioteNode, key: string): string | undefined;
95
28
  export declare function slotTakesChildren(node: ISymbioteNode): boolean;
@@ -98,48 +31,16 @@ export declare function derivedNodesOf(owner: ISymbioteNode): readonly ISymbiote
98
31
  export declare function notifyOwnedListenerChange(node: ISymbioteNode, name: string, wired: boolean): void;
99
32
  export declare function notifyChildInserted(node: ISymbioteNode, child: ISymbioteNode): void;
100
33
  export declare function claimModeFor(node: ISymbioteNode, component: string): IClaimMode | undefined;
101
- /**
102
- * Every owner key feeds the slot. The spelling for a `cloneElement` primitive, whose slot is not
103
- * derived from a named set at all — see `IHostBehavior.slotDerived`.
104
- *
105
- * A sentinel in the SAME array rather than a second field, so `slotDerivesFrom` stays one lookup and
106
- * a behavior that wants both spellings cannot express a contradiction.
107
- */
108
34
  export declare const SLOT_DERIVED_ALL = "*";
109
35
  export declare function slotDerivesFrom(node: ISymbioteNode, key: string): boolean;
110
36
  export declare function ownsListener(node: ISymbioteNode, name: string): boolean;
111
37
  export declare function stashAppListener(node: ISymbioteNode, name: string, listener: unknown): void;
112
38
  export declare function appListenerFor(node: ISymbioteNode, name: string): unknown;
113
39
  export declare function attachHostBehavior(node: ISymbioteNode, tag: string): void;
114
- /**
115
- * Run the deferred half of every behavior whose node has now been committed. Called from the commit
116
- * path immediately after `completeRoot`, where fresh Fabric tags have just been assigned.
117
- *
118
- * `isCommitted` is passed in for the same no-cycle reason — `committedOf` lives in `commit.ts`. A
119
- * still-uncommitted node stays in the set: a create superseded before it ever reached Fabric waits
120
- * for the commit that lands it, and `detachSubtree` drops it if that commit never comes.
121
- */
122
40
  export declare function runDeferredAttaches(isCommitted: (node: ISymbioteNode) => boolean): void;
123
- /**
124
- * Arm a node's recurring hook for the next commit.
125
- *
126
- * Called from `setProp` — gated there on `node.hasCommitHook`, a boolean field beside
127
- * `hasAriaAlias` on the same hidden class, so a node without a recurring hook pays one load and
128
- * one branch per write and never reaches this.
129
- */
130
41
  export declare function noteCommitHookNodeChanged(node: ISymbioteNode): void;
131
42
  export declare function runCommittedHooks(isCommitted: (node: ISymbioteNode) => boolean): void;
132
43
  export declare function markDetachCandidate(node: ISymbioteNode): void;
133
- /**
134
- * Whether the sweep has anything to do — asked BEFORE its arguments are built.
135
- *
136
- * The sweep's own first line already returns on an empty candidate set, and that was not enough:
137
- * its caller passes `surface.children`, which is a GETTER that crosses to the host, allocates the
138
- * whole top-level list and filters it into a second array. On a surface holding four thousand rows
139
- * that ran on every commit, including the ones with nothing to sweep, because an argument is
140
- * evaluated before the guard inside the callee can decline. Same shape as the `dlog` arguments that
141
- * cost Angular 5-10% while emitting nothing.
142
- */
143
44
  export declare function hasDetachCandidates(): boolean;
144
45
  export declare function sweepDetachedBehaviors(topLevel: readonly ISymbioteNode[], onDetached: (node: ISymbioteNode) => void): void;
145
46
  export declare function teardownSubtree(node: ISymbioteNode, onDetached: (node: ISymbioteNode) => void): void;