@symbiote-native/engine 0.2.0 → 0.4.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.
- package/README.md +24 -11
- package/build/accessibility-props.d.ts +19 -0
- package/build/accessibility-props.js +209 -0
- package/build/action-sheet-ios/index.js +4 -1
- package/build/animated/animations/composition.js +3 -1
- package/build/animated/animations/spring-config.js +4 -1
- package/build/animated/animations/spring.js +23 -9
- package/build/animated/animations/timing.js +3 -2
- package/build/animated/bezier.js +2 -1
- package/build/animated/color.js +4 -2
- package/build/animated/event.js +7 -3
- package/build/animated/graph.js +8 -3
- package/build/animated/index.d.ts +2 -2
- package/build/animated/index.js +2 -2
- package/build/animated/interpolation.js +7 -2
- package/build/animated/mock.js +1 -1
- package/build/animated/native/native-animated.js +1 -1
- package/build/animated/operators.js +27 -6
- package/build/animated/props.js +1 -1
- package/build/animated/rgba.js +18 -3
- package/build/animated/style.js +13 -3
- package/build/animated/value-xy.d.ts +8 -5
- package/build/animated/value-xy.js +4 -1
- package/build/app-registry/index.d.ts +1 -0
- package/build/app-registry/index.js +15 -5
- package/build/appearance/index.js +4 -1
- package/build/commit.d.ts +35 -0
- package/build/commit.js +613 -74
- package/build/debug.js +10 -4
- package/build/events/index.js +142 -88
- package/build/fabric-props.js +171 -11
- package/build/fabric.d.ts +10 -3
- package/build/fabric.js +11 -2
- package/build/host-behavior.d.ts +47 -0
- package/build/host-behavior.js +262 -0
- package/build/host-instance/index.d.ts +2 -10
- package/build/host-instance/index.js +13 -46
- package/build/image-loader.js +3 -2
- package/build/index.d.ts +24 -17
- package/build/index.js +27 -13
- package/build/interaction-manager/index.js +2 -1
- package/build/layout-animation/index.js +12 -4
- package/build/native-events.js +2 -1
- package/build/native-modules/index.js +3 -1
- package/build/node.d.ts +121 -2
- package/build/node.js +623 -41
- package/build/pan-responder/index.js +20 -9
- package/build/permissions-android/index.js +3 -1
- package/build/platform/index.android.d.ts +1 -1
- package/build/platform/index.android.js +1 -1
- package/build/platform/index.ios.d.ts +1 -1
- package/build/platform-color/index.js +3 -1
- package/build/post-commit.d.ts +1 -0
- package/build/post-commit.js +6 -0
- package/build/process-background-image/index.js +30 -9
- package/build/process-filter.js +11 -4
- package/build/registry.js +10 -2
- package/build/report-error.js +4 -1
- package/build/share/index.android.js +1 -1
- package/build/share/index.ios.js +1 -1
- package/build/status-bar/index.android.js +3 -4
- package/build/status-bar/index.ios.js +1 -1
- package/build/style-registry/index.d.ts +11 -2
- package/build/style-registry/index.js +223 -169
- package/build/style-registry/scope.d.ts +15 -1
- package/build/style-registry/scope.js +29 -27
- package/build/styles.d.ts +11 -1
- package/build/surface.d.ts +1 -1
- package/build/surface.js +8 -0
- package/build/tags.d.ts +1 -0
- package/build/tags.js +31 -1
- package/build/touch-history.js +9 -2
- package/build/vibration/index.ios.js +1 -1
- package/build/view-config.js +20 -2
- package/package.json +12 -2
|
@@ -42,7 +42,7 @@ const ANIMATION_PROPERTY = {
|
|
|
42
42
|
// (`FabricUIManager?.configureNextLayoutAnimation` in LayoutAnimation.js) before
|
|
43
43
|
// calling it, no `as` cast needed.
|
|
44
44
|
function hasConfigureNextLayoutAnimation(value) {
|
|
45
|
-
return isRecord(value) && typeof value.configureNextLayoutAnimation === 'function';
|
|
45
|
+
return (isRecord(value) && typeof value.configureNextLayoutAnimation === 'function');
|
|
46
46
|
}
|
|
47
47
|
// Resolved FRESH on every configureNext, deliberately NOT memoized. Either mechanism can
|
|
48
48
|
// come and go at runtime (the Fabric global installs during bootstrap; a TurboModule can be
|
|
@@ -93,9 +93,15 @@ const Presets = {
|
|
|
93
93
|
linear: createLayoutAnimation(PRESET_DURATION.linear, ANIMATION_TYPE.linear, ANIMATION_PROPERTY.opacity),
|
|
94
94
|
spring: {
|
|
95
95
|
duration: PRESET_DURATION.spring,
|
|
96
|
-
create: {
|
|
96
|
+
create: {
|
|
97
|
+
type: ANIMATION_TYPE.linear,
|
|
98
|
+
property: ANIMATION_PROPERTY.opacity,
|
|
99
|
+
},
|
|
97
100
|
update: { type: ANIMATION_TYPE.spring, springDamping: SPRING_DAMPING },
|
|
98
|
-
delete: {
|
|
101
|
+
delete: {
|
|
102
|
+
type: ANIMATION_TYPE.linear,
|
|
103
|
+
property: ANIMATION_PROPERTY.opacity,
|
|
104
|
+
},
|
|
99
105
|
},
|
|
100
106
|
};
|
|
101
107
|
// ---- enabled gate --------------------------------------------------------
|
|
@@ -154,7 +160,9 @@ function configureNext(config, onAnimationDidEnd, onAnimationDidFail) {
|
|
|
154
160
|
class LayoutAnimationImpl {
|
|
155
161
|
// Frozen so callers can't mutate the shared type/property tables.
|
|
156
162
|
Types = Object.freeze({ ...ANIMATION_TYPE });
|
|
157
|
-
Properties = Object.freeze({
|
|
163
|
+
Properties = Object.freeze({
|
|
164
|
+
...ANIMATION_PROPERTY,
|
|
165
|
+
});
|
|
158
166
|
Presets = Presets;
|
|
159
167
|
// Methods (not class fields) so they stay overridable under
|
|
160
168
|
// useDefineForClassFields.
|
package/build/native-events.js
CHANGED
|
@@ -70,7 +70,8 @@ export function setDeviceEventSource(source) {
|
|
|
70
70
|
// would throw "undefined is not a function" — the `?.` guards the module, not a
|
|
71
71
|
// missing method. Mirrors RN's NativeEventEmitter constructor probe.
|
|
72
72
|
function hasObserveCounters(module) {
|
|
73
|
-
return typeof module.addListener === 'function' &&
|
|
73
|
+
return (typeof module.addListener === 'function' &&
|
|
74
|
+
typeof module.removeListeners === 'function');
|
|
74
75
|
}
|
|
75
76
|
// Subscribe to events for one native module. Mirrors RN's NativeEventEmitter: each
|
|
76
77
|
// `addListener` also pings the module's `addListener` counter, and removal pings
|
|
@@ -110,7 +110,9 @@ export function createDeviceEventModule(config) {
|
|
|
110
110
|
installDeviceEventHub();
|
|
111
111
|
const resolved = getModule();
|
|
112
112
|
const bindModule = config.bindModuleToEmitter ?? true;
|
|
113
|
-
const boundModule = bindModule && resolved !== null && hasEventEmitterShape(resolved)
|
|
113
|
+
const boundModule = bindModule && resolved !== null && hasEventEmitterShape(resolved)
|
|
114
|
+
? resolved
|
|
115
|
+
: undefined;
|
|
114
116
|
emitter = new NativeEventEmitter(boundModule);
|
|
115
117
|
config.onEmitterCreated?.(emitter, resolved);
|
|
116
118
|
}
|
package/build/node.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { IFabricNode, IFabricProps, IRootTag, IMeasureOnSuccess, IMeasureInWindowOnSuccess, IMeasureLayoutOnSuccess } from './fabric';
|
|
2
|
+
import { type IClassNameValue } from './style-registry';
|
|
3
|
+
import { type IPayloadFold } from './host-behavior';
|
|
1
4
|
declare const BRAND: unique symbol;
|
|
2
5
|
export declare const RAW_TEXT_COMPONENT = "RCTRawText";
|
|
3
6
|
export declare const TEXT_COMPONENT = "RCTText";
|
|
@@ -13,26 +16,142 @@ export type IListener = (event: ISymbioteEvent) => unknown;
|
|
|
13
16
|
export declare function isSymbioteEvent(value: unknown): value is ISymbioteEvent;
|
|
14
17
|
export interface ISymbioteNode {
|
|
15
18
|
readonly [BRAND]: true;
|
|
16
|
-
|
|
19
|
+
component: string;
|
|
17
20
|
readonly isText: boolean;
|
|
18
21
|
props: Record<string, unknown>;
|
|
19
22
|
listeners: Map<string, IListener> | undefined;
|
|
20
23
|
children: ISymbioteNode[];
|
|
21
24
|
parent: ISymbioteNode | undefined;
|
|
25
|
+
dirty: boolean;
|
|
26
|
+
propsDirty: boolean;
|
|
27
|
+
hasAriaAlias: boolean;
|
|
28
|
+
payloadFold: IPayloadFold | undefined;
|
|
29
|
+
structureDirty: boolean;
|
|
30
|
+
committed: IMirror | undefined;
|
|
31
|
+
styleParts: IClassStyleParts | undefined;
|
|
32
|
+
measure(callback: IMeasureOnSuccess): void;
|
|
33
|
+
measureInWindow(callback: IMeasureInWindowOnSuccess): void;
|
|
34
|
+
measureLayout(relativeToNativeNode: ISymbioteNode | number, onSuccess: IMeasureLayoutOnSuccess, onFail?: () => void): void;
|
|
35
|
+
setNativeProps(nativeProps: Record<string, unknown>): void;
|
|
36
|
+
focus(): void;
|
|
37
|
+
blur(): void;
|
|
22
38
|
}
|
|
23
|
-
export
|
|
39
|
+
export interface IMirror {
|
|
40
|
+
handle: IFabricNode;
|
|
41
|
+
tag: number;
|
|
42
|
+
rootTag: IRootTag;
|
|
43
|
+
props: IFabricProps;
|
|
44
|
+
children: readonly ISymbioteNode[];
|
|
45
|
+
viewName: string;
|
|
46
|
+
parent: ISymbioteNode | undefined;
|
|
47
|
+
owner: ISymbioteNode;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The committed record for `node`, or `undefined` if it has never been committed - or if `node` is
|
|
51
|
+
* not the raw retained node at all.
|
|
52
|
+
*
|
|
53
|
+
* That second case is the reason this is a function rather than a bare `node.committed` read. The
|
|
54
|
+
* engine identifies a node BY IDENTITY, and the classic way to break that is to hand the engine a
|
|
55
|
+
* wrapper instead of the node: a Vue `reactive()`/deep-`ref()` Proxy around a host element is the
|
|
56
|
+
* one that actually happens (see the vue-adapter-reactivity skill; `shallowRef` is the fix).
|
|
57
|
+
*
|
|
58
|
+
* The old WeakMap caught this for free - a Proxy is a different object, so `mirror.get(proxy)` missed
|
|
59
|
+
* and every imperative API bailed with a clear "node not committed". A plain property read does NOT:
|
|
60
|
+
* a Proxy forwards `proxy.committed` straight to the target and hands back a real record, whose
|
|
61
|
+
* `handle` Vue would then deep-wrap on the way out. That handle is a JSI host object; a Proxy around
|
|
62
|
+
* it reaches `cloneNodeWithNewProps` and fails somewhere deep in native, far from the cause.
|
|
63
|
+
*
|
|
64
|
+
* So the identity check that was implicit in the WeakMap is explicit here: a record written on the
|
|
65
|
+
* raw node names it, and `record.owner !== node` means whatever we were handed is not that node.
|
|
66
|
+
* One reference comparison, and the wrap now fails LOUDER than it used to rather than quieter.
|
|
67
|
+
*/
|
|
68
|
+
export declare function committedOf(node: ISymbioteNode): IMirror | undefined;
|
|
69
|
+
export declare function createElement(component: string, isText?: boolean, tag?: string): ISymbioteNode;
|
|
24
70
|
export declare function createRawText(text: string): ISymbioteNode;
|
|
25
71
|
export declare function isSymbioteNode(value: unknown): value is ISymbioteNode;
|
|
26
72
|
export declare function debugNodeId(node: ISymbioteNode): number;
|
|
27
73
|
export declare const ANCHOR_COMPONENT = "#anchor";
|
|
28
74
|
export declare function createAnchor(): ISymbioteNode;
|
|
29
75
|
export declare function isAnchor(node: ISymbioteNode): boolean;
|
|
76
|
+
export declare function isEmptyRawText(node: ISymbioteNode): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Change which Fabric view a node commits as, keeping the node's identity.
|
|
79
|
+
*
|
|
80
|
+
* The commit walk already re-creates a node whose `viewName` no longer matches its committed one —
|
|
81
|
+
* that is how a `<Text>` moving in or out of another `<Text>` flips between RCTText and
|
|
82
|
+
* RCTVirtualText (`commit.ts`, reason `view-kind`). This exposes the same door for a prop-driven
|
|
83
|
+
* view choice, so `intrinsicWhen` is honoured on UPDATE and not only at create.
|
|
84
|
+
*
|
|
85
|
+
* The POLICY stays out of the engine: which prop decides, and which view it decides between, lives
|
|
86
|
+
* in `HOST_PRIMITIVES` and is read by `resolveIntrinsicTag` in `@symbiote-native/components`. The
|
|
87
|
+
* engine only knows how to swap the name — the same split every other spec-driven fold has here.
|
|
88
|
+
*
|
|
89
|
+
* A no-op when the name is unchanged, so a renderer may call it on every update without comparing
|
|
90
|
+
* first.
|
|
91
|
+
*/
|
|
92
|
+
export declare function setNodeComponent(node: ISymbioteNode, component: string): void;
|
|
93
|
+
export declare function markDirty(node: ISymbioteNode): void;
|
|
94
|
+
export declare function markPropsDirty(node: ISymbioteNode): void;
|
|
95
|
+
export declare function markStructureDirty(parent: ISymbioteNode): void;
|
|
96
|
+
export declare function takePropStats(): {
|
|
97
|
+
writes: number;
|
|
98
|
+
noops: number;
|
|
99
|
+
};
|
|
30
100
|
export declare function setProp(node: ISymbioteNode, key: string, value: unknown): void;
|
|
101
|
+
/**
|
|
102
|
+
* Install a listener the BEHAVIOR owns, bypassing the ownership check.
|
|
103
|
+
*
|
|
104
|
+
* `setEventListener` diverts an owned name into the stash, which is right for an app listener and
|
|
105
|
+
* circular for the behavior's own dispatcher — it would stash itself and never occupy the slot it
|
|
106
|
+
* exists to hold. This is the one writer allowed past that gate.
|
|
107
|
+
*/
|
|
108
|
+
export declare function setBehaviorListener(node: ISymbioteNode, name: string, listener: IListener): void;
|
|
31
109
|
export declare function setEventListener(node: ISymbioteNode, name: string, value: unknown): void;
|
|
110
|
+
export interface IClassStyleParts {
|
|
111
|
+
classStyle: unknown;
|
|
112
|
+
explicitStyle: unknown;
|
|
113
|
+
hiddenStyle: unknown;
|
|
114
|
+
className: IClassNameValue | undefined;
|
|
115
|
+
isPressed: boolean;
|
|
116
|
+
activeStyle: unknown;
|
|
117
|
+
activeStyleFromCallback: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Stop a node painting without unmounting it, or let it paint again.
|
|
121
|
+
*
|
|
122
|
+
* The seam React's `Activity`/`Suspense` reach for through `hideInstance`/`unhideInstance`. It
|
|
123
|
+
* lives in the engine rather than an adapter because the reversibility problem — restoring the
|
|
124
|
+
* author's style byte for byte — belongs to whoever owns the style merge, and that is here.
|
|
125
|
+
*/
|
|
126
|
+
export declare function setNodeHidden(node: ISymbioteNode, hidden: boolean): void;
|
|
127
|
+
/**
|
|
128
|
+
* Put a node into (or out of) its pressed state, so `.x:active` rules apply.
|
|
129
|
+
*
|
|
130
|
+
* The engine-owned half of what `:active` is on the web: the press state resolves BELOW the
|
|
131
|
+
* framework and never crosses into it, which is what lets a pressable be an intrinsic tag rather
|
|
132
|
+
* than a component (`.claude/rules/host-primitive-tier.md`, tier 2). A component is forced only
|
|
133
|
+
* when the TEMPLATE must read the state — `v-slot="{ pressed }"` and the function form of `style`
|
|
134
|
+
* — and this exists so the common case does not have to.
|
|
135
|
+
*
|
|
136
|
+
* Costs nothing when no `:active` rule is registered anywhere: `resolveActiveClassName` hands back
|
|
137
|
+
* the very same object the unpressed path returns, so `isAlreadyPublished` turns the re-push away
|
|
138
|
+
* and the node is never dirtied.
|
|
139
|
+
*/
|
|
140
|
+
export declare function setNodePressed(node: ISymbioteNode, pressed: boolean): void;
|
|
32
141
|
export declare function getExplicitStyle(node: ISymbioteNode): unknown;
|
|
33
142
|
export declare function routeProp(node: ISymbioteNode, key: string, value: unknown): void;
|
|
34
143
|
export declare function setText(node: ISymbioteNode, text: string): void;
|
|
35
144
|
export declare function appendChild(parent: ISymbioteNode, child: ISymbioteNode): void;
|
|
36
145
|
export declare function insertBefore(parent: ISymbioteNode, child: ISymbioteNode, beforeChild: ISymbioteNode): void;
|
|
37
146
|
export declare function removeChild(parent: ISymbioteNode, child: ISymbioteNode): void;
|
|
147
|
+
export interface ITreeCensus {
|
|
148
|
+
nodes: number;
|
|
149
|
+
anchors: number;
|
|
150
|
+
emptyRawTexts: number;
|
|
151
|
+
/** Nodes the commit walk actually reconciles: `nodes` minus everything it skips. */
|
|
152
|
+
renderable: number;
|
|
153
|
+
/** children.length of every parent holding at least one skipped child, widest first. */
|
|
154
|
+
flattenWidths: number[];
|
|
155
|
+
}
|
|
156
|
+
export declare function censusRetainedTree(roots: readonly ISymbioteNode[]): ITreeCensus;
|
|
38
157
|
export {};
|