@lynx-js/react 0.111.0 → 0.111.2
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/CHANGELOG.md +58 -0
- package/components/lib/DeferredListItem.d.ts +3 -1
- package/components/lib/DeferredListItem.jsx +4 -2
- package/components/lib/DeferredListItem.jsx.map +1 -1
- package/components/src/DeferredListItem.tsx +5 -3
- package/package.json +6 -1
- package/refresh/.turbo/turbo-build.log +7 -3
- package/refresh/dist/index.js +223 -284
- package/refresh/package.json +3 -4
- package/refresh/rslib.config.ts +24 -0
- package/runtime/debug/index.cjs +8 -0
- package/runtime/debug/index.d.ts +4 -0
- package/runtime/debug/index.js +5 -0
- package/runtime/lib/alog/index.d.ts +1 -0
- package/runtime/lib/alog/index.js +8 -0
- package/runtime/lib/alog/index.js.map +1 -0
- package/runtime/lib/alog/render.d.ts +1 -0
- package/runtime/lib/alog/render.js +19 -0
- package/runtime/lib/alog/render.js.map +1 -0
- package/runtime/lib/backgroundSnapshot.d.ts +1 -0
- package/runtime/lib/backgroundSnapshot.js +31 -17
- package/runtime/lib/backgroundSnapshot.js.map +1 -1
- package/runtime/lib/debug/component-stack.d.ts +33 -0
- package/runtime/lib/debug/component-stack.js +145 -0
- package/runtime/lib/debug/component-stack.js.map +1 -0
- package/runtime/lib/debug/formatPatch.d.ts +2 -0
- package/runtime/lib/debug/formatPatch.js +27 -0
- package/runtime/lib/debug/formatPatch.js.map +1 -0
- package/runtime/lib/debug/printSnapshot.d.ts +1 -1
- package/runtime/lib/debug/printSnapshot.js +0 -4
- package/runtime/lib/debug/printSnapshot.js.map +1 -1
- package/runtime/lib/debug/profile.js +1 -3
- package/runtime/lib/debug/profile.js.map +1 -1
- package/runtime/lib/hydrate.js +11 -7
- package/runtime/lib/hydrate.js.map +1 -1
- package/runtime/lib/lifecycle/patch/commit.js +1 -1
- package/runtime/lib/lifecycle/patch/commit.js.map +1 -1
- package/runtime/lib/lifecycle/patch/snapshotPatch.d.ts +4 -0
- package/runtime/lib/lifecycle/patch/snapshotPatch.js +28 -0
- package/runtime/lib/lifecycle/patch/snapshotPatch.js.map +1 -1
- package/runtime/lib/lynx.js +9 -0
- package/runtime/lib/lynx.js.map +1 -1
- package/runtime/lib/pendingListUpdates.d.ts +2 -1
- package/runtime/lib/pendingListUpdates.js +16 -4
- package/runtime/lib/pendingListUpdates.js.map +1 -1
- package/runtime/lib/renderToOpcodes/constants.d.ts +2 -0
- package/runtime/lib/renderToOpcodes/constants.js +2 -0
- package/runtime/lib/renderToOpcodes/constants.js.map +1 -1
- package/runtime/lib/root.d.ts +6 -0
- package/runtime/lib/root.js +4 -0
- package/runtime/lib/root.js.map +1 -1
- package/runtime/lib/snapshot/platformInfo.js +5 -3
- package/runtime/lib/snapshot/platformInfo.js.map +1 -1
- package/runtime/lib/snapshot/ref.d.ts +2 -2
- package/runtime/lib/snapshot/spread.js +3 -1
- package/runtime/lib/snapshot/spread.js.map +1 -1
- package/runtime/lib/snapshot.js +13 -7
- package/runtime/lib/snapshot.js.map +1 -1
- package/runtime/lib/utils.d.ts +2 -0
- package/runtime/lib/utils.js +23 -2
- package/runtime/lib/utils.js.map +1 -1
- package/testing-library/dist/env/vitest.js +18 -7
- package/testing-library/dist/pure.js +3 -1
- package/testing-library/dist/vitest-global-setup.js +2 -2
- package/transform/dist/wasm.cjs +1 -1
- package/types/react.d.ts +13 -1
- package/worklet-runtime/dist/dev.js +403 -506
- package/worklet-runtime/dist/main.js +1 -517
- package/worklet-runtime/lib/workletRuntime.js +5 -5
- package/worklet-runtime/lib/workletRuntime.js.map +1 -1
- package/runtime/src/backgroundSnapshot.ts +0 -501
- package/runtime/src/compat/componentIs.ts +0 -30
- package/runtime/src/compat/initData.ts +0 -150
- package/runtime/src/compat/lynxComponent.ts +0 -79
- package/runtime/src/debug/debug.ts +0 -9
- package/runtime/src/debug/printSnapshot.ts +0 -28
- package/runtime/src/debug/profile.ts +0 -55
- package/runtime/src/document.ts +0 -84
- package/runtime/src/gesture/processGesture.ts +0 -89
- package/runtime/src/gesture/processGestureBagkround.ts +0 -19
- package/runtime/src/gesture/types.ts +0 -44
- package/runtime/src/hooks/react.ts +0 -62
- package/runtime/src/hooks/useLynxGlobalEventListener.ts +0 -59
- package/runtime/src/hydrate.ts +0 -368
- package/runtime/src/index.ts +0 -94
- package/runtime/src/internal.ts +0 -63
- package/runtime/src/legacy-react-runtime/index.ts +0 -42
- package/runtime/src/lifecycle/destroy.ts +0 -34
- package/runtime/src/lifecycle/event/delayEvents.ts +0 -11
- package/runtime/src/lifecycle/event/delayLifecycleEvents.ts +0 -15
- package/runtime/src/lifecycle/event/jsReady.ts +0 -34
- package/runtime/src/lifecycle/pass.ts +0 -14
- package/runtime/src/lifecycle/patch/commit.ts +0 -214
- package/runtime/src/lifecycle/patch/error.ts +0 -61
- package/runtime/src/lifecycle/patch/isMainThreadHydrationFinished.ts +0 -13
- package/runtime/src/lifecycle/patch/snapshotPatch.ts +0 -65
- package/runtime/src/lifecycle/patch/snapshotPatchApply.ts +0 -145
- package/runtime/src/lifecycle/patch/updateMainThread.ts +0 -64
- package/runtime/src/lifecycle/ref/delay.ts +0 -99
- package/runtime/src/lifecycle/reload.ts +0 -97
- package/runtime/src/lifecycle/render.ts +0 -54
- package/runtime/src/lifecycleConstant.ts +0 -21
- package/runtime/src/list.ts +0 -307
- package/runtime/src/listUpdateInfo.ts +0 -221
- package/runtime/src/lynx/calledByNative.ts +0 -160
- package/runtime/src/lynx/component.ts +0 -113
- package/runtime/src/lynx/dynamic-js.ts +0 -36
- package/runtime/src/lynx/env.ts +0 -109
- package/runtime/src/lynx/injectLepusMethods.ts +0 -53
- package/runtime/src/lynx/lazy-bundle.ts +0 -175
- package/runtime/src/lynx/performance.ts +0 -148
- package/runtime/src/lynx/runWithForce.ts +0 -67
- package/runtime/src/lynx/tt.ts +0 -215
- package/runtime/src/lynx-api.ts +0 -455
- package/runtime/src/lynx.ts +0 -58
- package/runtime/src/opcodes.ts +0 -155
- package/runtime/src/pendingListUpdates.ts +0 -18
- package/runtime/src/renderToOpcodes/constants.ts +0 -24
- package/runtime/src/renderToOpcodes/index.ts +0 -306
- package/runtime/src/root.ts +0 -23
- package/runtime/src/snapshot/dynamicPartType.ts +0 -16
- package/runtime/src/snapshot/event.ts +0 -33
- package/runtime/src/snapshot/gesture.ts +0 -30
- package/runtime/src/snapshot/list.ts +0 -36
- package/runtime/src/snapshot/platformInfo.ts +0 -62
- package/runtime/src/snapshot/ref.ts +0 -139
- package/runtime/src/snapshot/spread.ts +0 -330
- package/runtime/src/snapshot/workletEvent.ts +0 -35
- package/runtime/src/snapshot/workletRef.ts +0 -88
- package/runtime/src/snapshot.ts +0 -634
- package/runtime/src/snapshotInstanceHydrationMap.ts +0 -17
- package/runtime/src/utils.ts +0 -44
- package/runtime/src/worklet/ctx.ts +0 -22
- package/runtime/src/worklet/destroy.ts +0 -16
- package/runtime/src/worklet/execMap.ts +0 -51
- package/runtime/src/worklet/functionCall.ts +0 -42
- package/runtime/src/worklet/functionality.ts +0 -29
- package/runtime/src/worklet/hmr.ts +0 -34
- package/runtime/src/worklet/indexMap.ts +0 -23
- package/runtime/src/worklet/runOnBackground.ts +0 -147
- package/runtime/src/worklet/runOnMainThread.ts +0 -50
- package/runtime/src/worklet/transformToWorklet.ts +0 -26
- package/runtime/src/worklet/workletRef.ts +0 -231
- package/runtime/src/worklet/workletRefPool.ts +0 -29
|
@@ -1,501 +0,0 @@
|
|
|
1
|
-
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Background snapshot implementation that runs in the background thread.
|
|
7
|
-
*
|
|
8
|
-
* This is the mirror of main thread's {@link SnapshotInstance}:
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { Worklet } from '@lynx-js/react/worklet-runtime/bindings';
|
|
12
|
-
|
|
13
|
-
import { processGestureBackground } from './gesture/processGestureBagkround.js';
|
|
14
|
-
import type { GestureKind } from './gesture/types.js';
|
|
15
|
-
import { diffArrayAction, diffArrayLepus } from './hydrate.js';
|
|
16
|
-
import { globalBackgroundSnapshotInstancesToRemove } from './lifecycle/patch/commit.js';
|
|
17
|
-
import type { SnapshotPatch } from './lifecycle/patch/snapshotPatch.js';
|
|
18
|
-
import {
|
|
19
|
-
SnapshotOperation,
|
|
20
|
-
__globalSnapshotPatch,
|
|
21
|
-
initGlobalSnapshotPatch,
|
|
22
|
-
takeGlobalSnapshotPatch,
|
|
23
|
-
} from './lifecycle/patch/snapshotPatch.js';
|
|
24
|
-
import { globalPipelineOptions } from './lynx/performance.js';
|
|
25
|
-
import { DynamicPartType } from './snapshot/dynamicPartType.js';
|
|
26
|
-
import { clearQueuedRefs, queueRefAttrUpdate } from './snapshot/ref.js';
|
|
27
|
-
import type { Ref } from './snapshot/ref.js';
|
|
28
|
-
import { transformSpread } from './snapshot/spread.js';
|
|
29
|
-
import type { SerializedSnapshotInstance, Snapshot } from './snapshot.js';
|
|
30
|
-
import { backgroundSnapshotInstanceManager, snapshotManager, traverseSnapshotInstance } from './snapshot.js';
|
|
31
|
-
import { hydrationMap } from './snapshotInstanceHydrationMap.js';
|
|
32
|
-
import { isDirectOrDeepEqual } from './utils.js';
|
|
33
|
-
import { onPostWorkletCtx } from './worklet/ctx.js';
|
|
34
|
-
|
|
35
|
-
export class BackgroundSnapshotInstance {
|
|
36
|
-
constructor(public type: string) {
|
|
37
|
-
this.__snapshot_def = snapshotManager.values.get(type)!;
|
|
38
|
-
const id = this.__id = backgroundSnapshotInstanceManager.nextId += 1;
|
|
39
|
-
backgroundSnapshotInstanceManager.values.set(id, this);
|
|
40
|
-
|
|
41
|
-
__globalSnapshotPatch?.push(SnapshotOperation.CreateElement, type, id);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
__id: number;
|
|
45
|
-
__values: any[] | undefined;
|
|
46
|
-
__snapshot_def: Snapshot;
|
|
47
|
-
__extraProps?: Record<string, unknown> | undefined;
|
|
48
|
-
|
|
49
|
-
private __parent: BackgroundSnapshotInstance | null = null;
|
|
50
|
-
private __firstChild: BackgroundSnapshotInstance | null = null;
|
|
51
|
-
private __lastChild: BackgroundSnapshotInstance | null = null;
|
|
52
|
-
private __previousSibling: BackgroundSnapshotInstance | null = null;
|
|
53
|
-
private __nextSibling: BackgroundSnapshotInstance | null = null;
|
|
54
|
-
|
|
55
|
-
get parentNode(): BackgroundSnapshotInstance | null {
|
|
56
|
-
return this.__parent;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get nextSibling(): BackgroundSnapshotInstance | null {
|
|
60
|
-
return this.__nextSibling;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// get isConnected() {
|
|
64
|
-
// return !!this.__parent;
|
|
65
|
-
// }
|
|
66
|
-
|
|
67
|
-
contains(child: BackgroundSnapshotInstance): boolean {
|
|
68
|
-
return child.parentNode === this;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// TODO: write tests for this
|
|
72
|
-
// This will be called in `lazy`/`Suspense`.
|
|
73
|
-
// We currently ignore this since we did not find a way to test.
|
|
74
|
-
/* v8 ignore start */
|
|
75
|
-
appendChild(child: BackgroundSnapshotInstance): void {
|
|
76
|
-
return this.insertBefore(child);
|
|
77
|
-
}
|
|
78
|
-
/* v8 ignore stop */
|
|
79
|
-
|
|
80
|
-
insertBefore(
|
|
81
|
-
node: BackgroundSnapshotInstance,
|
|
82
|
-
beforeNode?: BackgroundSnapshotInstance,
|
|
83
|
-
): void {
|
|
84
|
-
__globalSnapshotPatch?.push(
|
|
85
|
-
SnapshotOperation.InsertBefore,
|
|
86
|
-
this.__id,
|
|
87
|
-
node.__id,
|
|
88
|
-
beforeNode?.__id,
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
// If the node already has a parent, remove it from its current parent
|
|
92
|
-
const p = node.__parent;
|
|
93
|
-
if (p) {
|
|
94
|
-
if (node.__previousSibling) {
|
|
95
|
-
node.__previousSibling.__nextSibling = node.__nextSibling;
|
|
96
|
-
} else {
|
|
97
|
-
p.__firstChild = node.__nextSibling;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (node.__nextSibling) {
|
|
101
|
-
node.__nextSibling.__previousSibling = node.__previousSibling;
|
|
102
|
-
} else {
|
|
103
|
-
p.__lastChild = node.__previousSibling;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// If beforeNode is not provided, add the new node as the last child
|
|
108
|
-
if (beforeNode) {
|
|
109
|
-
// If beforeNode is provided, insert the new node before beforeNode
|
|
110
|
-
if (beforeNode.__previousSibling) {
|
|
111
|
-
beforeNode.__previousSibling.__nextSibling = node;
|
|
112
|
-
node.__previousSibling = beforeNode.__previousSibling;
|
|
113
|
-
} else {
|
|
114
|
-
this.__firstChild = node;
|
|
115
|
-
node.__previousSibling = null;
|
|
116
|
-
}
|
|
117
|
-
beforeNode.__previousSibling = node;
|
|
118
|
-
node.__nextSibling = beforeNode;
|
|
119
|
-
node.__parent = this;
|
|
120
|
-
} else {
|
|
121
|
-
if (this.__lastChild) {
|
|
122
|
-
this.__lastChild.__nextSibling = node;
|
|
123
|
-
node.__previousSibling = this.__lastChild;
|
|
124
|
-
} else {
|
|
125
|
-
this.__firstChild = node;
|
|
126
|
-
node.__previousSibling = null;
|
|
127
|
-
}
|
|
128
|
-
this.__lastChild = node;
|
|
129
|
-
node.__parent = this;
|
|
130
|
-
node.__nextSibling = null;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
removeChild(node: BackgroundSnapshotInstance): void {
|
|
135
|
-
__globalSnapshotPatch?.push(
|
|
136
|
-
SnapshotOperation.RemoveChild,
|
|
137
|
-
this.__id,
|
|
138
|
-
node.__id,
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
if (node.__parent !== this) {
|
|
142
|
-
throw new Error('The node to be removed is not a child of this node.');
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
if (node.__previousSibling) {
|
|
146
|
-
node.__previousSibling.__nextSibling = node.__nextSibling;
|
|
147
|
-
} else {
|
|
148
|
-
this.__firstChild = node.__nextSibling;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (node.__nextSibling) {
|
|
152
|
-
node.__nextSibling.__previousSibling = node.__previousSibling;
|
|
153
|
-
} else {
|
|
154
|
-
this.__lastChild = node.__previousSibling;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
node.__parent = null;
|
|
158
|
-
node.__previousSibling = null;
|
|
159
|
-
node.__nextSibling = null;
|
|
160
|
-
|
|
161
|
-
traverseSnapshotInstance(node, v => {
|
|
162
|
-
v.__parent = null;
|
|
163
|
-
v.__previousSibling = null;
|
|
164
|
-
v.__nextSibling = null;
|
|
165
|
-
if (v.__values) {
|
|
166
|
-
v.__snapshot_def.refAndSpreadIndexes?.forEach((i) => {
|
|
167
|
-
const value = v.__values![i] as unknown;
|
|
168
|
-
if (value && (typeof value === 'object' || typeof value === 'function')) {
|
|
169
|
-
if ('__spread' in value && 'ref' in value) {
|
|
170
|
-
queueRefAttrUpdate(value.ref as Ref, null, v.__id, i);
|
|
171
|
-
} else if ('__ref' in value) {
|
|
172
|
-
queueRefAttrUpdate(value as Ref, null, v.__id, i);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
globalBackgroundSnapshotInstancesToRemove.push(v.__id);
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
get childNodes(): BackgroundSnapshotInstance[] {
|
|
182
|
-
const nodes: BackgroundSnapshotInstance[] = [];
|
|
183
|
-
let node = this.__firstChild;
|
|
184
|
-
while (node) {
|
|
185
|
-
nodes.push(node);
|
|
186
|
-
if (node === this.__lastChild) {
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
node = node.__nextSibling;
|
|
190
|
-
}
|
|
191
|
-
return nodes;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
setAttribute(key: string | number, value: unknown): void {
|
|
195
|
-
if (__PROFILE__) {
|
|
196
|
-
console.profile('setAttribute');
|
|
197
|
-
}
|
|
198
|
-
if (key === 'values') {
|
|
199
|
-
if (__globalSnapshotPatch) {
|
|
200
|
-
const oldValues = this.__values;
|
|
201
|
-
if (oldValues) {
|
|
202
|
-
for (let index = 0; index < (value as unknown[]).length; index++) {
|
|
203
|
-
const { needUpdate, valueToCommit } = this.setAttributeImpl(
|
|
204
|
-
(value as unknown[])[index],
|
|
205
|
-
oldValues[index],
|
|
206
|
-
index,
|
|
207
|
-
);
|
|
208
|
-
if (needUpdate) {
|
|
209
|
-
__globalSnapshotPatch.push(
|
|
210
|
-
SnapshotOperation.SetAttribute,
|
|
211
|
-
this.__id,
|
|
212
|
-
index,
|
|
213
|
-
valueToCommit,
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
} else {
|
|
218
|
-
const patch = [];
|
|
219
|
-
const length = (value as unknown[]).length;
|
|
220
|
-
for (let index = 0; index < length; ++index) {
|
|
221
|
-
const { valueToCommit } = this.setAttributeImpl((value as unknown[])[index], null, index);
|
|
222
|
-
patch[index] = valueToCommit;
|
|
223
|
-
}
|
|
224
|
-
__globalSnapshotPatch.push(
|
|
225
|
-
SnapshotOperation.SetAttributes,
|
|
226
|
-
this.__id,
|
|
227
|
-
patch,
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
} else {
|
|
231
|
-
this.__snapshot_def.refAndSpreadIndexes?.forEach((index) => {
|
|
232
|
-
const v = (value as unknown[])[index];
|
|
233
|
-
if (v && (typeof v === 'object' || typeof v === 'function')) {
|
|
234
|
-
if ('__spread' in v && 'ref' in v) {
|
|
235
|
-
queueRefAttrUpdate(null, v.ref as Ref, this.__id, index);
|
|
236
|
-
} else if ('__ref' in v) {
|
|
237
|
-
queueRefAttrUpdate(null, v as Ref, this.__id, index);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
this.__values = value as unknown[];
|
|
243
|
-
if (__PROFILE__) {
|
|
244
|
-
console.profileEnd();
|
|
245
|
-
}
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (typeof key === 'string') {
|
|
250
|
-
(this.__extraProps ??= {})[key] = value;
|
|
251
|
-
} else {
|
|
252
|
-
// old path (`this.setAttribute(0, xxx)`)
|
|
253
|
-
// is reserved as slow path
|
|
254
|
-
(this.__values ??= [])[key] = value;
|
|
255
|
-
}
|
|
256
|
-
__globalSnapshotPatch?.push(
|
|
257
|
-
SnapshotOperation.SetAttribute,
|
|
258
|
-
this.__id,
|
|
259
|
-
key,
|
|
260
|
-
value,
|
|
261
|
-
);
|
|
262
|
-
if (__PROFILE__) {
|
|
263
|
-
console.profileEnd();
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
private setAttributeImpl(newValue: unknown, oldValue: unknown, index: number): {
|
|
268
|
-
needUpdate: boolean;
|
|
269
|
-
valueToCommit: unknown;
|
|
270
|
-
} {
|
|
271
|
-
if (!newValue) {
|
|
272
|
-
// `oldValue` can't be a spread.
|
|
273
|
-
if (oldValue && typeof oldValue === 'object' && '__ref' in oldValue) {
|
|
274
|
-
queueRefAttrUpdate(oldValue as Ref, null, this.__id, index);
|
|
275
|
-
}
|
|
276
|
-
return { needUpdate: oldValue !== newValue, valueToCommit: newValue };
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const newType = typeof newValue;
|
|
280
|
-
if (newType === 'object') {
|
|
281
|
-
const newValueObj = newValue as Record<string, unknown>;
|
|
282
|
-
if ('__spread' in newValueObj) {
|
|
283
|
-
const oldSpread = (oldValue as { __spread?: Record<string, unknown> } | undefined)?.__spread;
|
|
284
|
-
const newSpread = transformSpread(this, index, newValueObj);
|
|
285
|
-
const needUpdate = !isDirectOrDeepEqual(oldSpread, newSpread);
|
|
286
|
-
// use __spread to cache the transform result for next diff
|
|
287
|
-
newValueObj['__spread'] = newSpread;
|
|
288
|
-
queueRefAttrUpdate(
|
|
289
|
-
oldSpread && ((oldValue as { ref?: Ref }).ref),
|
|
290
|
-
newValueObj['ref'] as Ref,
|
|
291
|
-
this.__id,
|
|
292
|
-
index,
|
|
293
|
-
);
|
|
294
|
-
if (needUpdate) {
|
|
295
|
-
for (const key in newSpread) {
|
|
296
|
-
const newSpreadValue = newSpread[key];
|
|
297
|
-
if (!newSpreadValue) {
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
if ((newSpreadValue as { _wkltId?: string })._wkltId) {
|
|
301
|
-
newSpread[key] = onPostWorkletCtx(newSpreadValue as Worklet);
|
|
302
|
-
} else if ((newSpreadValue as { __isGesture?: boolean }).__isGesture) {
|
|
303
|
-
processGestureBackground(newSpreadValue as GestureKind);
|
|
304
|
-
} else if (key == '__lynx_timing_flag' && oldSpread?.[key] != newSpreadValue && globalPipelineOptions) {
|
|
305
|
-
globalPipelineOptions.needTimestamps = true;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return { needUpdate, valueToCommit: newSpread };
|
|
310
|
-
}
|
|
311
|
-
if ('__ref' in newValueObj) {
|
|
312
|
-
queueRefAttrUpdate(oldValue as Ref, newValueObj as Ref, this.__id, index);
|
|
313
|
-
return { needUpdate: false, valueToCommit: 1 };
|
|
314
|
-
}
|
|
315
|
-
if ('_wkltId' in newValueObj) {
|
|
316
|
-
return { needUpdate: true, valueToCommit: onPostWorkletCtx(newValueObj as Worklet) };
|
|
317
|
-
}
|
|
318
|
-
if ('__isGesture' in newValueObj) {
|
|
319
|
-
processGestureBackground(newValueObj as unknown as GestureKind);
|
|
320
|
-
return { needUpdate: true, valueToCommit: newValue };
|
|
321
|
-
}
|
|
322
|
-
if ('__ltf' in newValueObj) {
|
|
323
|
-
// __lynx_timing_flag
|
|
324
|
-
if (globalPipelineOptions && (oldValue as { __ltf?: unknown } | undefined)?.__ltf != newValueObj['__ltf']) {
|
|
325
|
-
globalPipelineOptions.needTimestamps = true;
|
|
326
|
-
return { needUpdate: true, valueToCommit: newValue };
|
|
327
|
-
}
|
|
328
|
-
return { needUpdate: false, valueToCommit: newValue };
|
|
329
|
-
}
|
|
330
|
-
return { needUpdate: !isDirectOrDeepEqual(oldValue, newValue), valueToCommit: newValue };
|
|
331
|
-
}
|
|
332
|
-
if (newType === 'function') {
|
|
333
|
-
if ((newValue as { __ref?: unknown }).__ref) {
|
|
334
|
-
queueRefAttrUpdate(oldValue as Ref, newValue as Ref, this.__id, index);
|
|
335
|
-
return { needUpdate: false, valueToCommit: 1 };
|
|
336
|
-
}
|
|
337
|
-
/* event */
|
|
338
|
-
return { needUpdate: !oldValue, valueToCommit: 1 };
|
|
339
|
-
}
|
|
340
|
-
return { needUpdate: oldValue !== newValue, valueToCommit: newValue };
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export function hydrate(
|
|
345
|
-
before: SerializedSnapshotInstance,
|
|
346
|
-
after: BackgroundSnapshotInstance,
|
|
347
|
-
): SnapshotPatch {
|
|
348
|
-
initGlobalSnapshotPatch();
|
|
349
|
-
|
|
350
|
-
const helper2 = (afters: BackgroundSnapshotInstance[], parentId: number, targetId?: number) => {
|
|
351
|
-
for (const child of afters) {
|
|
352
|
-
const id = child.__id;
|
|
353
|
-
__globalSnapshotPatch!.push(SnapshotOperation.CreateElement, child.type, id);
|
|
354
|
-
const values = child.__values;
|
|
355
|
-
if (values) {
|
|
356
|
-
child.__values = undefined;
|
|
357
|
-
child.setAttribute('values', values);
|
|
358
|
-
}
|
|
359
|
-
const extraProps = child.__extraProps;
|
|
360
|
-
for (const key in extraProps) {
|
|
361
|
-
child.setAttribute(key, extraProps[key]);
|
|
362
|
-
}
|
|
363
|
-
helper2(child.childNodes, id);
|
|
364
|
-
__globalSnapshotPatch!.push(SnapshotOperation.InsertBefore, parentId, id, targetId);
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
const helper = (
|
|
369
|
-
before: SerializedSnapshotInstance,
|
|
370
|
-
after: BackgroundSnapshotInstance,
|
|
371
|
-
) => {
|
|
372
|
-
hydrationMap.set(after.__id, before.id);
|
|
373
|
-
backgroundSnapshotInstanceManager.updateId(after.__id, before.id);
|
|
374
|
-
after.__values?.forEach((value: unknown, index) => {
|
|
375
|
-
const old: unknown = before.values![index];
|
|
376
|
-
|
|
377
|
-
if (value) {
|
|
378
|
-
if (typeof value === 'object') {
|
|
379
|
-
if ('__spread' in value) {
|
|
380
|
-
// `value.__spread` my contain event ids using snapshot ids before hydration. Remove it.
|
|
381
|
-
delete value.__spread;
|
|
382
|
-
const __spread = transformSpread(after, index, value);
|
|
383
|
-
for (const key in __spread) {
|
|
384
|
-
const v = __spread[key];
|
|
385
|
-
if (v && typeof v === 'object') {
|
|
386
|
-
if ('_wkltId' in v) {
|
|
387
|
-
onPostWorkletCtx(v as Worklet);
|
|
388
|
-
} else if ('__isGesture' in v) {
|
|
389
|
-
processGestureBackground(v as GestureKind);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
(after.__values![index]! as Record<string, unknown>)['__spread'] = __spread;
|
|
394
|
-
value = __spread;
|
|
395
|
-
} else if ('__ref' in value) {
|
|
396
|
-
// skip patch
|
|
397
|
-
value = old;
|
|
398
|
-
} else if ('_wkltId' in value) {
|
|
399
|
-
onPostWorkletCtx(value as Worklet);
|
|
400
|
-
} else if ('__isGesture' in value) {
|
|
401
|
-
processGestureBackground(value as GestureKind);
|
|
402
|
-
}
|
|
403
|
-
} else if (typeof value === 'function') {
|
|
404
|
-
if ('__ref' in value) {
|
|
405
|
-
// skip patch
|
|
406
|
-
value = old;
|
|
407
|
-
} else {
|
|
408
|
-
value = `${after.__id}:${index}:`;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
if (!isDirectOrDeepEqual(value, old)) {
|
|
414
|
-
__globalSnapshotPatch!.push(
|
|
415
|
-
SnapshotOperation.SetAttribute,
|
|
416
|
-
after.__id,
|
|
417
|
-
index,
|
|
418
|
-
value,
|
|
419
|
-
);
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
if (after.__extraProps) {
|
|
424
|
-
for (const key in after.__extraProps) {
|
|
425
|
-
const value = after.__extraProps[key];
|
|
426
|
-
const old = before.extraProps?.[key];
|
|
427
|
-
if (!isDirectOrDeepEqual(value, old)) {
|
|
428
|
-
__globalSnapshotPatch!.push(
|
|
429
|
-
SnapshotOperation.SetAttribute,
|
|
430
|
-
after.__id,
|
|
431
|
-
key,
|
|
432
|
-
value,
|
|
433
|
-
);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
const { slot } = after.__snapshot_def;
|
|
439
|
-
|
|
440
|
-
const beforeChildNodes = before.children ?? [];
|
|
441
|
-
const afterChildNodes = after.childNodes;
|
|
442
|
-
|
|
443
|
-
if (!slot) {
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
slot.forEach(([type], index) => {
|
|
448
|
-
switch (type) {
|
|
449
|
-
case DynamicPartType.Slot:
|
|
450
|
-
case DynamicPartType.MultiChildren: {
|
|
451
|
-
// TODO: the following null assertions are not 100% safe
|
|
452
|
-
const v1 = beforeChildNodes[index]!;
|
|
453
|
-
const v2 = afterChildNodes[index]!;
|
|
454
|
-
helper(v1, v2);
|
|
455
|
-
break;
|
|
456
|
-
}
|
|
457
|
-
case DynamicPartType.Children:
|
|
458
|
-
case DynamicPartType.ListChildren: {
|
|
459
|
-
const diffResult = diffArrayLepus(
|
|
460
|
-
beforeChildNodes,
|
|
461
|
-
afterChildNodes,
|
|
462
|
-
(a, b) => a.type === b.type,
|
|
463
|
-
(a, b) => {
|
|
464
|
-
helper(a, b);
|
|
465
|
-
},
|
|
466
|
-
);
|
|
467
|
-
diffArrayAction(
|
|
468
|
-
beforeChildNodes,
|
|
469
|
-
diffResult,
|
|
470
|
-
(node, target) => {
|
|
471
|
-
helper2([node], before.id, target?.id);
|
|
472
|
-
return undefined as unknown as SerializedSnapshotInstance;
|
|
473
|
-
},
|
|
474
|
-
node => {
|
|
475
|
-
__globalSnapshotPatch!.push(
|
|
476
|
-
SnapshotOperation.RemoveChild,
|
|
477
|
-
before.id,
|
|
478
|
-
node.id,
|
|
479
|
-
);
|
|
480
|
-
},
|
|
481
|
-
(node, target) => {
|
|
482
|
-
// changedList.push([SnapshotOperation.RemoveChild, before.id, node.id]);
|
|
483
|
-
__globalSnapshotPatch!.push(
|
|
484
|
-
SnapshotOperation.InsertBefore,
|
|
485
|
-
before.id,
|
|
486
|
-
node.id,
|
|
487
|
-
target?.id,
|
|
488
|
-
);
|
|
489
|
-
},
|
|
490
|
-
);
|
|
491
|
-
break;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
};
|
|
496
|
-
|
|
497
|
-
helper(before, after);
|
|
498
|
-
// Hydration should not trigger ref updates. They were incorrectly triggered when using `setAttribute` to add values to the patch list.
|
|
499
|
-
clearQueuedRefs();
|
|
500
|
-
return takeGlobalSnapshotPatch()!;
|
|
501
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
|
|
5
|
-
import type { FC } from 'react';
|
|
6
|
-
|
|
7
|
-
// for better reuse if runtime is changed
|
|
8
|
-
export function factory(
|
|
9
|
-
{ createElement, useMemo, Suspense, lazy }: typeof import('react'),
|
|
10
|
-
loadLazyBundle: any,
|
|
11
|
-
): FC<{ is: string }> {
|
|
12
|
-
/**
|
|
13
|
-
* @internal a polyfill for <component is=? />
|
|
14
|
-
*/
|
|
15
|
-
const __ComponentIsPolyfill: FC<{ is: string }> = ({ is, ...props }) => {
|
|
16
|
-
if (typeof is !== 'string') {
|
|
17
|
-
lynx.reportError(
|
|
18
|
-
new Error(
|
|
19
|
-
'You must provide a string to props `is` when using syntax `<component is=? />`.',
|
|
20
|
-
),
|
|
21
|
-
);
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
const D = useMemo(() => lazy(() => loadLazyBundle(is)), [is]);
|
|
26
|
-
return createElement(Suspense, { key: is }, createElement(D, props));
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
return __ComponentIsPolyfill;
|
|
30
|
-
}
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
|
-
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
|
-
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import type { ComponentChildren, Consumer, Context, Provider } from 'preact';
|
|
5
|
-
import type { ComponentClass } from 'react';
|
|
6
|
-
|
|
7
|
-
import { useLynxGlobalEventListener } from '../hooks/useLynxGlobalEventListener.js';
|
|
8
|
-
import { globalFlushOptions } from '../lifecycle/patch/commit.js';
|
|
9
|
-
|
|
10
|
-
type Getter<T> = {
|
|
11
|
-
[key in keyof T]: () => T[key];
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// for better reuse if runtime is changed
|
|
15
|
-
export function factory<Data>(
|
|
16
|
-
{ createContext, useState, createElement, useLynxGlobalEventListener: useListener }: {
|
|
17
|
-
createContext: typeof import('preact').createContext;
|
|
18
|
-
useState: typeof import('preact/hooks').useState;
|
|
19
|
-
createElement: typeof import('preact').createElement;
|
|
20
|
-
useLynxGlobalEventListener: typeof useLynxGlobalEventListener;
|
|
21
|
-
},
|
|
22
|
-
prop: '__globalProps' | '__initData',
|
|
23
|
-
eventName: string,
|
|
24
|
-
): Getter<{
|
|
25
|
-
Context: Context<Data>;
|
|
26
|
-
Provider: Provider<Data>;
|
|
27
|
-
Consumer: Consumer<Data>;
|
|
28
|
-
use: () => Data;
|
|
29
|
-
useChanged: (callback: (data: Data) => void) => void;
|
|
30
|
-
}> {
|
|
31
|
-
const Context = createContext({} as Data);
|
|
32
|
-
|
|
33
|
-
const Provider = ({ children }: { children?: ComponentChildren }) => {
|
|
34
|
-
const [__, set] = useState<Data>(lynx[prop] as Data);
|
|
35
|
-
|
|
36
|
-
const handleChange = () => {
|
|
37
|
-
if (prop === '__initData') {
|
|
38
|
-
globalFlushOptions.triggerDataUpdated = true;
|
|
39
|
-
}
|
|
40
|
-
set(lynx[prop] as Data);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
useChanged(handleChange);
|
|
44
|
-
|
|
45
|
-
return createElement(
|
|
46
|
-
Context.Provider,
|
|
47
|
-
{
|
|
48
|
-
value: __,
|
|
49
|
-
},
|
|
50
|
-
children,
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const Consumer: Consumer<Data> = Context.Consumer;
|
|
55
|
-
|
|
56
|
-
const use = (): Data => {
|
|
57
|
-
const [__, set] = useState(lynx[prop]);
|
|
58
|
-
useChanged(() => {
|
|
59
|
-
if (prop === '__initData') {
|
|
60
|
-
globalFlushOptions.triggerDataUpdated = true;
|
|
61
|
-
}
|
|
62
|
-
set(lynx[prop]);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
return __ as Data;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const useChanged = (callback: (__: Data) => void) => {
|
|
69
|
-
if (!__LEPUS__) {
|
|
70
|
-
useListener(eventName, callback);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
/* v8 ignore next */
|
|
76
|
-
Context: () => Context,
|
|
77
|
-
Provider: () => Provider,
|
|
78
|
-
Consumer: () => Consumer,
|
|
79
|
-
use: () => use,
|
|
80
|
-
useChanged: () => useChanged,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Higher-Order Component (HOC) that injects `initData` into the state of the given class component.
|
|
86
|
-
*
|
|
87
|
-
* This HOC checks if the provided component is a class component. If it is, it wraps the component
|
|
88
|
-
* and injects the `initData` into its state. It also adds a listener
|
|
89
|
-
* to update the state when data changes, and removes the listener when the component unmounts.
|
|
90
|
-
*
|
|
91
|
-
* @typeParam P - The type of the props of the wrapped component.
|
|
92
|
-
* @typeParam S - The type of the state of the wrapped component.
|
|
93
|
-
*
|
|
94
|
-
* @param App - The class component to be wrapped by the HOC.
|
|
95
|
-
*
|
|
96
|
-
* @returns The original component if it is not a class component, otherwise a new class component
|
|
97
|
-
* with `initData` injection and state update functionality.
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* ```typescript
|
|
101
|
-
* class App extends React.Component<MyProps, MyState> {
|
|
102
|
-
* // component implementation
|
|
103
|
-
* }
|
|
104
|
-
*
|
|
105
|
-
* export default withInitDataInState(App);
|
|
106
|
-
* ```
|
|
107
|
-
* @public
|
|
108
|
-
*/
|
|
109
|
-
export function withInitDataInState<P, S>(App: ComponentClass<P, S>): ComponentClass<P, S> {
|
|
110
|
-
const isClassComponent = 'prototype' in App && 'render' in App.prototype;
|
|
111
|
-
/* v8 ignore next 4 */
|
|
112
|
-
if (!isClassComponent) {
|
|
113
|
-
// return as-is when not class component
|
|
114
|
-
return App;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
class C extends App {
|
|
118
|
-
h?: () => void;
|
|
119
|
-
|
|
120
|
-
constructor(props: P) {
|
|
121
|
-
super(props);
|
|
122
|
-
this.state = {
|
|
123
|
-
...this.state,
|
|
124
|
-
...lynx.__initData,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
if (!__LEPUS__) {
|
|
128
|
-
lynx.getJSModule('GlobalEventEmitter').addListener(
|
|
129
|
-
'onDataChanged',
|
|
130
|
-
this.h = () => {
|
|
131
|
-
globalFlushOptions.triggerDataUpdated = true;
|
|
132
|
-
this.setState(lynx.__initData as S);
|
|
133
|
-
},
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
override componentWillUnmount(): void {
|
|
139
|
-
super.componentWillUnmount?.();
|
|
140
|
-
if (!__LEPUS__) {
|
|
141
|
-
lynx.getJSModule('GlobalEventEmitter').removeListener(
|
|
142
|
-
'onDataChanged',
|
|
143
|
-
this.h!,
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return C;
|
|
150
|
-
}
|