@lynx-js/react 0.109.2 → 0.110.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/CHANGELOG.md +33 -0
- package/components/lib/Page.js.map +1 -1
- package/components/src/Page.ts +1 -1
- package/package.json +1 -1
- package/refresh/.turbo/turbo-build.log +1 -1
- package/runtime/lib/backgroundSnapshot.d.ts +2 -1
- package/runtime/lib/backgroundSnapshot.js +66 -42
- package/runtime/lib/backgroundSnapshot.js.map +1 -1
- package/runtime/lib/compat/initData.d.ts +7 -5
- package/runtime/lib/compat/initData.js +1 -2
- package/runtime/lib/compat/initData.js.map +1 -1
- package/runtime/lib/compat/lynxComponent.js +10 -12
- package/runtime/lib/compat/lynxComponent.js.map +1 -1
- package/runtime/lib/debug/profile.js +1 -0
- package/runtime/lib/debug/profile.js.map +1 -1
- package/runtime/lib/gesture/processGestureBagkround.d.ts +1 -1
- package/runtime/lib/gesture/processGestureBagkround.js +4 -1
- package/runtime/lib/gesture/processGestureBagkround.js.map +1 -1
- package/runtime/lib/gesture/types.js.map +1 -1
- package/runtime/lib/hooks/react.js +3 -3
- package/runtime/lib/hooks/react.js.map +1 -1
- package/runtime/lib/hooks/useLynxGlobalEventListener.d.ts +1 -1
- package/runtime/lib/hydrate.d.ts +1 -1
- package/runtime/lib/hydrate.js +5 -4
- package/runtime/lib/hydrate.js.map +1 -1
- package/runtime/lib/internal.d.ts +3 -2
- package/runtime/lib/internal.js +3 -2
- package/runtime/lib/internal.js.map +1 -1
- package/runtime/lib/legacy-react-runtime/index.js +1 -1
- package/runtime/lib/legacy-react-runtime/index.js.map +1 -1
- package/runtime/lib/lifecycle/destroy.js +1 -0
- package/runtime/lib/lifecycle/destroy.js.map +1 -1
- package/runtime/lib/lifecycle/event/delayEvents.js +3 -0
- package/runtime/lib/lifecycle/event/delayEvents.js.map +1 -1
- package/runtime/lib/lifecycle/event/delayLifecycleEvents.d.ts +3 -2
- package/runtime/lib/lifecycle/event/delayLifecycleEvents.js +1 -12
- package/runtime/lib/lifecycle/event/delayLifecycleEvents.js.map +1 -1
- package/runtime/lib/lifecycle/event/jsReady.d.ts +1 -1
- package/runtime/lib/lifecycle/event/jsReady.js +3 -2
- package/runtime/lib/lifecycle/event/jsReady.js.map +1 -1
- package/runtime/lib/lifecycle/patch/commit.d.ts +0 -2
- package/runtime/lib/lifecycle/patch/commit.js +8 -36
- package/runtime/lib/lifecycle/patch/commit.js.map +1 -1
- package/runtime/lib/lifecycle/patch/error.d.ts +8 -0
- package/runtime/lib/lifecycle/patch/error.js +47 -0
- package/runtime/lib/lifecycle/patch/error.js.map +1 -0
- package/runtime/lib/lifecycle/patch/isMainThreadHydrationFinished.js +3 -0
- package/runtime/lib/lifecycle/patch/isMainThreadHydrationFinished.js.map +1 -1
- package/runtime/lib/lifecycle/patch/snapshotPatch.d.ts +2 -2
- package/runtime/lib/lifecycle/patch/snapshotPatch.js.map +1 -1
- package/runtime/lib/lifecycle/patch/snapshotPatchApply.js +10 -10
- package/runtime/lib/lifecycle/patch/snapshotPatchApply.js.map +1 -1
- package/runtime/lib/lifecycle/patch/updateMainThread.d.ts +0 -1
- package/runtime/lib/lifecycle/patch/updateMainThread.js +7 -14
- package/runtime/lib/lifecycle/patch/updateMainThread.js.map +1 -1
- package/runtime/lib/lifecycle/ref/delay.d.ts +31 -0
- package/runtime/lib/lifecycle/ref/delay.js +80 -0
- package/runtime/lib/lifecycle/ref/delay.js.map +1 -0
- package/runtime/lib/lifecycle/reload.d.ts +1 -1
- package/runtime/lib/lifecycle/reload.js +8 -5
- package/runtime/lib/lifecycle/reload.js.map +1 -1
- package/runtime/lib/lifecycle/render.js +3 -2
- package/runtime/lib/lifecycle/render.js.map +1 -1
- package/runtime/lib/lifecycleConstant.d.ts +10 -7
- package/runtime/lib/lifecycleConstant.js +8 -8
- package/runtime/lib/lifecycleConstant.js.map +1 -1
- package/runtime/lib/list.d.ts +1 -45
- package/runtime/lib/list.js +31 -206
- package/runtime/lib/list.js.map +1 -1
- package/runtime/lib/listUpdateInfo.d.ts +38 -0
- package/runtime/lib/listUpdateInfo.js +152 -0
- package/runtime/lib/listUpdateInfo.js.map +1 -0
- package/runtime/lib/lynx/calledByNative.js +9 -6
- package/runtime/lib/lynx/calledByNative.js.map +1 -1
- package/runtime/lib/lynx/component.js +7 -0
- package/runtime/lib/lynx/component.js.map +1 -1
- package/runtime/lib/lynx/dynamic-js.d.ts +5 -1
- package/runtime/lib/lynx/dynamic-js.js +1 -0
- package/runtime/lib/lynx/dynamic-js.js.map +1 -1
- package/runtime/lib/lynx/env.d.ts +1 -1
- package/runtime/lib/lynx/env.js +13 -13
- package/runtime/lib/lynx/env.js.map +1 -1
- package/runtime/lib/lynx/lazy-bundle.js +7 -5
- package/runtime/lib/lynx/lazy-bundle.js.map +1 -1
- package/runtime/lib/lynx/performance.js +1 -1
- package/runtime/lib/lynx/performance.js.map +1 -1
- package/runtime/lib/lynx/runWithForce.js +3 -0
- package/runtime/lib/lynx/runWithForce.js.map +1 -1
- package/runtime/lib/lynx/tt.js +12 -33
- package/runtime/lib/lynx/tt.js.map +1 -1
- package/runtime/lib/lynx-api.d.ts +1 -1
- package/runtime/lib/lynx-api.js +3 -0
- package/runtime/lib/lynx-api.js.map +1 -1
- package/runtime/lib/lynx.js +6 -6
- package/runtime/lib/lynx.js.map +1 -1
- package/runtime/lib/opcodes.js +2 -1
- package/runtime/lib/opcodes.js.map +1 -1
- package/runtime/lib/pendingListUpdates.d.ts +6 -0
- package/runtime/lib/pendingListUpdates.js +16 -0
- package/runtime/lib/pendingListUpdates.js.map +1 -0
- package/runtime/lib/renderToOpcodes/index.js +7 -7
- package/runtime/lib/renderToOpcodes/index.js.map +1 -1
- package/runtime/lib/snapshot/dynamicPartType.d.ts +12 -0
- package/runtime/lib/snapshot/dynamicPartType.js +17 -0
- package/runtime/lib/snapshot/dynamicPartType.js.map +1 -0
- package/runtime/lib/snapshot/gesture.js +3 -0
- package/runtime/lib/snapshot/gesture.js.map +1 -1
- package/runtime/lib/snapshot/list.d.ts +3 -0
- package/runtime/lib/snapshot/list.js +23 -0
- package/runtime/lib/snapshot/list.js.map +1 -0
- package/runtime/lib/snapshot/platformInfo.d.ts +10 -0
- package/runtime/lib/snapshot/platformInfo.js +6 -3
- package/runtime/lib/snapshot/platformInfo.js.map +1 -1
- package/runtime/lib/snapshot/ref.d.ts +17 -9
- package/runtime/lib/snapshot/ref.js +64 -73
- package/runtime/lib/snapshot/ref.js.map +1 -1
- package/runtime/lib/snapshot/spread.d.ts +2 -2
- package/runtime/lib/snapshot/spread.js +12 -12
- package/runtime/lib/snapshot/spread.js.map +1 -1
- package/runtime/lib/snapshot/workletEvent.js +1 -1
- package/runtime/lib/snapshot/workletEvent.js.map +1 -1
- package/runtime/lib/snapshot/workletRef.d.ts +3 -3
- package/runtime/lib/snapshot/workletRef.js +27 -8
- package/runtime/lib/snapshot/workletRef.js.map +1 -1
- package/runtime/lib/snapshot.d.ts +9 -18
- package/runtime/lib/snapshot.js +46 -40
- package/runtime/lib/snapshot.js.map +1 -1
- package/runtime/lib/snapshotInstanceHydrationMap.d.ts +9 -0
- package/runtime/lib/snapshotInstanceHydrationMap.js +16 -0
- package/runtime/lib/snapshotInstanceHydrationMap.js.map +1 -0
- package/runtime/lib/utils.js +1 -1
- package/runtime/lib/utils.js.map +1 -1
- package/runtime/lib/worklet/workletRef.js +1 -2
- package/runtime/lib/worklet/workletRef.js.map +1 -1
- package/runtime/src/backgroundSnapshot.ts +75 -52
- package/runtime/src/compat/initData.ts +10 -9
- package/runtime/src/compat/lynxComponent.ts +12 -13
- package/runtime/src/debug/profile.ts +1 -0
- package/runtime/src/gesture/processGestureBagkround.ts +5 -1
- package/runtime/src/gesture/types.ts +3 -0
- package/runtime/src/hooks/react.ts +3 -3
- package/runtime/src/hooks/useLynxGlobalEventListener.ts +1 -1
- package/runtime/src/hydrate.ts +6 -4
- package/runtime/src/internal.ts +3 -2
- package/runtime/src/legacy-react-runtime/index.ts +1 -1
- package/runtime/src/lifecycle/destroy.ts +1 -0
- package/runtime/src/lifecycle/event/delayEvents.ts +3 -0
- package/runtime/src/lifecycle/event/delayLifecycleEvents.ts +7 -13
- package/runtime/src/lifecycle/event/jsReady.ts +4 -3
- package/runtime/src/lifecycle/patch/commit.ts +10 -41
- package/runtime/src/lifecycle/patch/error.ts +61 -0
- package/runtime/src/lifecycle/patch/isMainThreadHydrationFinished.ts +3 -0
- package/runtime/src/lifecycle/patch/snapshotPatch.ts +2 -2
- package/runtime/src/lifecycle/patch/snapshotPatchApply.ts +28 -28
- package/runtime/src/lifecycle/patch/updateMainThread.ts +7 -16
- package/runtime/src/lifecycle/ref/delay.ts +99 -0
- package/runtime/src/lifecycle/reload.ts +10 -7
- package/runtime/src/lifecycle/render.ts +3 -2
- package/runtime/src/lifecycleConstant.ts +11 -7
- package/runtime/src/list.ts +33 -269
- package/runtime/src/listUpdateInfo.ts +221 -0
- package/runtime/src/lynx/calledByNative.ts +15 -10
- package/runtime/src/lynx/component.ts +9 -0
- package/runtime/src/lynx/dynamic-js.ts +5 -1
- package/runtime/src/lynx/env.ts +17 -17
- package/runtime/src/lynx/lazy-bundle.ts +22 -14
- package/runtime/src/lynx/performance.ts +1 -1
- package/runtime/src/lynx/runWithForce.ts +9 -5
- package/runtime/src/lynx/tt.ts +19 -37
- package/runtime/src/lynx-api.ts +5 -2
- package/runtime/src/lynx.ts +7 -6
- package/runtime/src/opcodes.ts +2 -1
- package/runtime/src/pendingListUpdates.ts +18 -0
- package/runtime/src/renderToOpcodes/index.ts +7 -7
- package/runtime/src/snapshot/dynamicPartType.ts +16 -0
- package/runtime/src/snapshot/gesture.ts +3 -0
- package/runtime/src/snapshot/list.ts +36 -0
- package/runtime/src/snapshot/platformInfo.ts +19 -5
- package/runtime/src/snapshot/ref.ts +78 -87
- package/runtime/src/snapshot/spread.ts +47 -22
- package/runtime/src/snapshot/workletEvent.ts +1 -1
- package/runtime/src/snapshot/workletRef.ts +36 -10
- package/runtime/src/snapshot.ts +62 -51
- package/runtime/src/snapshotInstanceHydrationMap.ts +17 -0
- package/runtime/src/utils.ts +3 -3
- package/runtime/src/worklet/workletRef.ts +1 -2
- package/testing-library/dist/env/vitest.js +8 -6
- package/testing-library/dist/pure.js +4 -3
- package/testing-library/dist/vitest.config.js +7 -7
- package/transform/cjs/main.cjs +4 -0
- package/transform/dist/wasm.cjs +1 -1
- package/worklet-runtime/dist/dev.js +1 -4
- package/worklet-runtime/dist/main.js +0 -3
- package/worklet-runtime/lib/bindings/observers.d.ts +14 -1
- package/worklet-runtime/lib/bindings/observers.js +7 -7
- package/worklet-runtime/lib/bindings/observers.js.map +1 -1
- package/worklet-runtime/lib/hydrate.js +0 -5
- package/worklet-runtime/lib/hydrate.js.map +1 -1
- package/runtime/lib/lifecycle/delayUnmount.d.ts +0 -8
- package/runtime/lib/lifecycle/delayUnmount.js +0 -65
- package/runtime/lib/lifecycle/delayUnmount.js.map +0 -1
- package/runtime/src/lifecycle/delayUnmount.ts +0 -77
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// Copyright 2025 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 { hydrate } from './hydrate.js';
|
|
6
|
+
import { componentAtIndexFactory, enqueueComponentFactory } from './list.js';
|
|
7
|
+
import type { SnapshotInstance } from './snapshot.js';
|
|
8
|
+
|
|
9
|
+
export interface ListUpdateInfo {
|
|
10
|
+
flush(): void;
|
|
11
|
+
onInsertBefore(
|
|
12
|
+
newNode: SnapshotInstance,
|
|
13
|
+
existingNode?: SnapshotInstance,
|
|
14
|
+
): void;
|
|
15
|
+
onRemoveChild(child: SnapshotInstance): void;
|
|
16
|
+
onSetAttribute(child: SnapshotInstance, attr: any, oldAttr: any): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// class ListUpdateInfoDiffing implements ListUpdateInfo {
|
|
20
|
+
// private oldChildNodes: SnapshotInstance[];
|
|
21
|
+
// constructor(private list: SnapshotInstance) {
|
|
22
|
+
// this.oldChildNodes = list.childNodes;
|
|
23
|
+
// }
|
|
24
|
+
// flush(): void {
|
|
25
|
+
// Object.defineProperty(SnapshotInstance.prototype, "key", {
|
|
26
|
+
// get: function () {
|
|
27
|
+
// return this.values[0]["item-key"];
|
|
28
|
+
// },
|
|
29
|
+
// });
|
|
30
|
+
|
|
31
|
+
// }
|
|
32
|
+
// onInsertBefore(newNode: SnapshotInstance, existingNode?: SnapshotInstance | undefined): void {}
|
|
33
|
+
// onRemoveChild(child: SnapshotInstance): void {}
|
|
34
|
+
// onSetAttribute(child: SnapshotInstance, attr: any): void {
|
|
35
|
+
// throw new Error("Method not implemented.");
|
|
36
|
+
// }
|
|
37
|
+
// }
|
|
38
|
+
|
|
39
|
+
interface InsertAction {
|
|
40
|
+
position: number;
|
|
41
|
+
type: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface UpdateAction {
|
|
45
|
+
from: number;
|
|
46
|
+
to: number;
|
|
47
|
+
type: string;
|
|
48
|
+
flush: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface ListOperations {
|
|
52
|
+
insertAction: InsertAction[];
|
|
53
|
+
removeAction: number[];
|
|
54
|
+
updateAction: UpdateAction[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class ListUpdateInfoRecording implements ListUpdateInfo {
|
|
58
|
+
constructor(private list: SnapshotInstance) {
|
|
59
|
+
this.oldChildNodes = list.childNodes;
|
|
60
|
+
// this.oldChildNodesSet = new Set(this.oldChildNodes);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// private __commitAndReset() {
|
|
64
|
+
// (this.__pendingAttributes ??= []).push(this.__toAttribute());
|
|
65
|
+
// this.oldChildNodes = this.list.childNodes;
|
|
66
|
+
// this.oldChildNodesSet = new Set(this.oldChildNodes);
|
|
67
|
+
// this.removeChild1.clear();
|
|
68
|
+
// this.removeChild2.clear();
|
|
69
|
+
// this.insertBefore.clear();
|
|
70
|
+
// this.appendChild.length = 0;
|
|
71
|
+
// this.platformInfoUpdate.clear();
|
|
72
|
+
// }
|
|
73
|
+
|
|
74
|
+
flush(): void {
|
|
75
|
+
const elementIndex = this.list.__snapshot_def.slot[0]![1];
|
|
76
|
+
const listElement = this.list.__elements![elementIndex]!;
|
|
77
|
+
// this.__pendingAttributes?.forEach(pendingAttribute => {
|
|
78
|
+
// __SetAttribute(listElement, "update-list-info", pendingAttribute);
|
|
79
|
+
// __FlushElementTree(listElement);
|
|
80
|
+
// });
|
|
81
|
+
__SetAttribute(listElement, 'update-list-info', this.__toAttribute());
|
|
82
|
+
const [componentAtIndex, componentAtIndexes] = componentAtIndexFactory(this.list.childNodes, hydrate);
|
|
83
|
+
__UpdateListCallbacks(
|
|
84
|
+
listElement,
|
|
85
|
+
componentAtIndex,
|
|
86
|
+
enqueueComponentFactory(),
|
|
87
|
+
componentAtIndexes,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private oldChildNodes: SnapshotInstance[];
|
|
92
|
+
// private oldChildNodesSet: Set<SnapshotInstance>;
|
|
93
|
+
private removeChild = new Set<SnapshotInstance>();
|
|
94
|
+
private insertBefore = new Map<SnapshotInstance, SnapshotInstance[]>(); // insert V before K
|
|
95
|
+
private appendChild = [] as SnapshotInstance[];
|
|
96
|
+
private platformInfoUpdate = new Map<SnapshotInstance, any>();
|
|
97
|
+
|
|
98
|
+
onInsertBefore(newNode: SnapshotInstance, existingNode?: SnapshotInstance): void {
|
|
99
|
+
if (newNode.parentNode) {
|
|
100
|
+
// if (!this.oldChildNodesSet.has(newNode)) {
|
|
101
|
+
// this.__commitAndReset();
|
|
102
|
+
// }
|
|
103
|
+
this.removeChild.add(newNode);
|
|
104
|
+
}
|
|
105
|
+
if (existingNode) {
|
|
106
|
+
// if (!this.oldChildNodesSet.has(existingNode)) {
|
|
107
|
+
// this.__commitAndReset();
|
|
108
|
+
// }
|
|
109
|
+
const newChildren = this.insertBefore.get(existingNode) ?? [];
|
|
110
|
+
newChildren.push(newNode);
|
|
111
|
+
this.insertBefore.set(existingNode, newChildren);
|
|
112
|
+
} else {
|
|
113
|
+
this.appendChild.push(newNode);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
onRemoveChild(child: SnapshotInstance): void {
|
|
118
|
+
// if (!this.oldChildNodesSet.has(child)) {
|
|
119
|
+
// this.__commitAndReset();
|
|
120
|
+
// }
|
|
121
|
+
this.removeChild.add(child);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
onSetAttribute(child: SnapshotInstance, attr: any, _oldAttr: any): void {
|
|
125
|
+
this.platformInfoUpdate.set(child, attr);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private __toAttribute(): ListOperations {
|
|
129
|
+
const { removeChild, insertBefore, appendChild, platformInfoUpdate } = this;
|
|
130
|
+
|
|
131
|
+
const removals: number[] = [];
|
|
132
|
+
const insertions: InsertAction[] = [];
|
|
133
|
+
const updates: UpdateAction[] = [];
|
|
134
|
+
|
|
135
|
+
let j = 0;
|
|
136
|
+
for (let i = 0; i < this.oldChildNodes.length; i++, j++) {
|
|
137
|
+
const child = this.oldChildNodes[i]!;
|
|
138
|
+
if (platformInfoUpdate.has(child)) {
|
|
139
|
+
updates.push({
|
|
140
|
+
...platformInfoUpdate.get(child),
|
|
141
|
+
from: +j,
|
|
142
|
+
to: +j,
|
|
143
|
+
// no flush
|
|
144
|
+
flush: false,
|
|
145
|
+
type: child.type,
|
|
146
|
+
} as UpdateAction);
|
|
147
|
+
}
|
|
148
|
+
if (insertBefore.has(child)) {
|
|
149
|
+
const children = insertBefore.get(child)!;
|
|
150
|
+
children.forEach(c => {
|
|
151
|
+
insertions.push({
|
|
152
|
+
position: j,
|
|
153
|
+
type: c.type,
|
|
154
|
+
...c.__listItemPlatformInfo,
|
|
155
|
+
} as InsertAction);
|
|
156
|
+
j++;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (removeChild.has(child)) {
|
|
160
|
+
removals.push(i);
|
|
161
|
+
removeChild.delete(child);
|
|
162
|
+
j--;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (let i = 0; i < appendChild.length; i++) {
|
|
166
|
+
const child = appendChild[i]!;
|
|
167
|
+
insertions.push({
|
|
168
|
+
position: j + i,
|
|
169
|
+
type: child.type,
|
|
170
|
+
...child.__listItemPlatformInfo,
|
|
171
|
+
} as InsertAction);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
insertions.sort((a, b) => a.position - b.position);
|
|
175
|
+
removals.sort((a, b) => a - b);
|
|
176
|
+
|
|
177
|
+
if (
|
|
178
|
+
SystemInfo.lynxSdkVersion === '2.14'
|
|
179
|
+
|| SystemInfo.lynxSdkVersion === '2.15'
|
|
180
|
+
|| SystemInfo.lynxSdkVersion === '2.16'
|
|
181
|
+
|| SystemInfo.lynxSdkVersion === '2.17'
|
|
182
|
+
|| SystemInfo.lynxSdkVersion === '2.18'
|
|
183
|
+
) {
|
|
184
|
+
const elementIndex = this.list.__snapshot_def.slot[0]![1];
|
|
185
|
+
const listElement = this.list.__elements![elementIndex]!;
|
|
186
|
+
|
|
187
|
+
// `__GetAttributeByName` is available since Lynx 2.14
|
|
188
|
+
if (__GetAttributeByName(listElement, 'custom-list-name') === 'list-container') {
|
|
189
|
+
// `updateAction` must be full (not incremental) when Lynx version <= 2.18 and
|
|
190
|
+
// when `custom-list-name` is `list-container` (available when Lynx version >= 2.14) is true,
|
|
191
|
+
updates.length = 0;
|
|
192
|
+
this.list.childNodes.forEach((child, index) => {
|
|
193
|
+
updates.push({
|
|
194
|
+
...child.__listItemPlatformInfo,
|
|
195
|
+
from: index,
|
|
196
|
+
to: index,
|
|
197
|
+
// no flush
|
|
198
|
+
flush: false,
|
|
199
|
+
type: child.type,
|
|
200
|
+
} as UpdateAction);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
insertAction: insertions,
|
|
207
|
+
removeAction: removals,
|
|
208
|
+
updateAction: updates,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
toJSON(): [ListOperations] {
|
|
213
|
+
// if (this.__pendingAttributes) {
|
|
214
|
+
// return [...this.__pendingAttributes, this.__toAttribute()];
|
|
215
|
+
// } else {
|
|
216
|
+
// return [this.__toAttribute()];
|
|
217
|
+
// }
|
|
218
|
+
|
|
219
|
+
return [this.__toAttribute()] as const;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -6,10 +6,10 @@ import { isJSReady, jsReady, jsReadyEventIdSwap, resetJSReady } from '../lifecyc
|
|
|
6
6
|
import { reloadMainThread } from '../lifecycle/reload.js';
|
|
7
7
|
import { renderMainThread } from '../lifecycle/render.js';
|
|
8
8
|
import { LifecycleConstant } from '../lifecycleConstant.js';
|
|
9
|
-
import { __pendingListUpdates } from '../list.js';
|
|
10
9
|
import { ssrHydrateByOpcodes } from '../opcodes.js';
|
|
10
|
+
import { __pendingListUpdates } from '../pendingListUpdates.js';
|
|
11
11
|
import { __root, setRoot } from '../root.js';
|
|
12
|
-
import {
|
|
12
|
+
import { applyRefQueue } from '../snapshot/workletRef.js';
|
|
13
13
|
import { SnapshotInstance, __page, setupPage } from '../snapshot.js';
|
|
14
14
|
import { isEmptyObject } from '../utils.js';
|
|
15
15
|
import { PerformanceTimingKeys, markTiming, setPipeline } from './performance.js';
|
|
@@ -18,6 +18,7 @@ function ssrEncode() {
|
|
|
18
18
|
const { __opcodes } = __root;
|
|
19
19
|
delete __root.__opcodes;
|
|
20
20
|
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
21
22
|
const oldToJSON = SnapshotInstance.prototype.toJSON;
|
|
22
23
|
SnapshotInstance.prototype.toJSON = function(this: SnapshotInstance): any {
|
|
23
24
|
return [
|
|
@@ -44,8 +45,13 @@ function ssrHydrate(info: string) {
|
|
|
44
45
|
setupPage(nativePage);
|
|
45
46
|
const refsMap = __GetTemplateParts(nativePage);
|
|
46
47
|
|
|
47
|
-
const { __opcodes, __root_values } = JSON.parse(info)
|
|
48
|
-
|
|
48
|
+
const { __opcodes, __root_values } = JSON.parse(info) as {
|
|
49
|
+
__opcodes: unknown[];
|
|
50
|
+
__root_values: unknown[] | undefined;
|
|
51
|
+
};
|
|
52
|
+
if (__root_values) {
|
|
53
|
+
__root.setAttribute('values', __root_values);
|
|
54
|
+
}
|
|
49
55
|
ssrHydrateByOpcodes(__opcodes, __root as SnapshotInstance, refsMap);
|
|
50
56
|
|
|
51
57
|
(__root as SnapshotInstance).__elements = [nativePage];
|
|
@@ -74,11 +80,11 @@ function injectCalledByNative(): void {
|
|
|
74
80
|
});
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
function renderPage(data:
|
|
83
|
+
function renderPage(data: Record<string, unknown> | undefined): void {
|
|
78
84
|
// reset `jsReady` state
|
|
79
85
|
resetJSReady();
|
|
80
86
|
|
|
81
|
-
lynx.__initData = data
|
|
87
|
+
lynx.__initData = data ?? {};
|
|
82
88
|
|
|
83
89
|
setupPage(__CreatePage('0', 0));
|
|
84
90
|
(__root as SnapshotInstance).ensureElements();
|
|
@@ -88,13 +94,14 @@ function renderPage(data: any): void {
|
|
|
88
94
|
// always call this before `__FlushElementTree`
|
|
89
95
|
// (There is an implicit `__FlushElementTree` in `renderPage`)
|
|
90
96
|
__pendingListUpdates.flush();
|
|
97
|
+
applyRefQueue();
|
|
91
98
|
|
|
92
99
|
if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {
|
|
93
100
|
jsReady();
|
|
94
101
|
}
|
|
95
102
|
}
|
|
96
103
|
|
|
97
|
-
function updatePage(data:
|
|
104
|
+
function updatePage(data: Record<string, unknown> | undefined, options?: UpdatePageOption): void {
|
|
98
105
|
if (options?.reloadTemplate) {
|
|
99
106
|
reloadMainThread(data, options);
|
|
100
107
|
return;
|
|
@@ -118,9 +125,6 @@ function updatePage(data: any, options?: UpdatePageOption): void {
|
|
|
118
125
|
markTiming(PerformanceTimingKeys.updateDiffVdomStart);
|
|
119
126
|
{
|
|
120
127
|
__pendingListUpdates.clear();
|
|
121
|
-
|
|
122
|
-
// ignore ref & unref before jsReady
|
|
123
|
-
takeGlobalRefPatchMap();
|
|
124
128
|
renderMainThread();
|
|
125
129
|
// As said by codename `jsReadyEventIdSwap`, this swap will only be used for event remap,
|
|
126
130
|
// because ref & unref cause by previous render will be ignored
|
|
@@ -132,6 +136,7 @@ function updatePage(data: any, options?: UpdatePageOption): void {
|
|
|
132
136
|
|
|
133
137
|
// always call this before `__FlushElementTree`
|
|
134
138
|
__pendingListUpdates.flush();
|
|
139
|
+
applyRefQueue();
|
|
135
140
|
}
|
|
136
141
|
markTiming(PerformanceTimingKeys.updateDiffVdomEnd);
|
|
137
142
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
|
+
|
|
5
|
+
/* eslint-disable */
|
|
6
|
+
|
|
4
7
|
import { Component } from 'preact';
|
|
5
8
|
|
|
6
9
|
import { PerfSpecificKey, PerformanceTimingKeys, markTimingLegacy } from './performance.js';
|
|
@@ -20,11 +23,14 @@ if (__JS__) {
|
|
|
20
23
|
),
|
|
21
24
|
);
|
|
22
25
|
}
|
|
26
|
+
// @ts-expect-error hack lynx-kernel
|
|
23
27
|
return lynxCoreInject.tt._reactLynx.ReactComponent.prototype.getNodeRef
|
|
24
28
|
.call(
|
|
25
29
|
{
|
|
26
30
|
_type: '',
|
|
31
|
+
// @ts-expect-error hack lynx-kernel
|
|
27
32
|
_nativeApp: lynxCoreInject.tt._nativeApp,
|
|
33
|
+
// @ts-expect-error hack lynx-kernel
|
|
28
34
|
_uiModule: lynxCoreInject.tt._nativeApp.nativeModuleProxy.LynxUIMethodModule,
|
|
29
35
|
_reactAppInstance: lynxCoreInject.tt,
|
|
30
36
|
},
|
|
@@ -41,11 +47,14 @@ if (__JS__) {
|
|
|
41
47
|
),
|
|
42
48
|
);
|
|
43
49
|
}
|
|
50
|
+
// @ts-expect-error hack lynx-kernel
|
|
44
51
|
return lynxCoreInject.tt._reactLynx.ReactComponent.prototype
|
|
45
52
|
.getNodeRefFromRoot.call(
|
|
46
53
|
{
|
|
47
54
|
_type: '',
|
|
55
|
+
// @ts-expect-error hack lynx-kernel
|
|
48
56
|
_nativeApp: lynxCoreInject.tt._nativeApp,
|
|
57
|
+
// @ts-expect-error hack lynx-kernel
|
|
49
58
|
_uiModule: lynxCoreInject.tt._nativeApp.nativeModuleProxy.LynxUIMethodModule,
|
|
50
59
|
_reactAppInstance: lynxCoreInject.tt,
|
|
51
60
|
},
|
|
@@ -9,6 +9,7 @@ export function loadDynamicJS<T>(url: string): Promise<T> {
|
|
|
9
9
|
new Error(`A dynamic import (to "${url}") is leaked to Lepus bundle.`),
|
|
10
10
|
{ errorCode: 202 },
|
|
11
11
|
);
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
12
13
|
return Promise.reject();
|
|
13
14
|
}
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
@@ -22,7 +23,10 @@ export function loadDynamicJS<T>(url: string): Promise<T> {
|
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export function __dynamicImport<T>(
|
|
26
|
+
export function __dynamicImport<T>(
|
|
27
|
+
url: string,
|
|
28
|
+
options?: { with?: { type?: 'component' | 'tsx' | 'jsx' } },
|
|
29
|
+
): Promise<T> {
|
|
26
30
|
const t = options?.with?.type;
|
|
27
31
|
if (t === 'component' || t === 'tsx' || t === 'jsx') {
|
|
28
32
|
return loadLazyBundle<any>(url);
|
package/runtime/src/lynx/env.ts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
// Copyright 2024 The Lynx Authors. All rights reserved.
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import type { DataProcessorDefinition } from '../lynx-api.js';
|
|
4
|
+
import type { DataProcessorDefinition, InitData, InitDataRaw } from '../lynx-api.js';
|
|
5
5
|
|
|
6
|
-
export function
|
|
6
|
+
export function setupLynxEnv(): void {
|
|
7
7
|
if (!__LEPUS__) {
|
|
8
8
|
const { initData, updateData } = lynxCoreInject.tt._params;
|
|
9
|
-
// @ts-ignore
|
|
10
9
|
lynx.__initData = { ...initData, ...updateData };
|
|
11
10
|
lynx.registerDataProcessors = function() {};
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
if (__LEPUS__) {
|
|
15
|
-
// @ts-ignore
|
|
16
14
|
lynx.__initData = {
|
|
17
15
|
/* available only in renderPage */
|
|
18
16
|
};
|
|
19
|
-
// @ts-
|
|
20
|
-
|
|
17
|
+
// @ts-expect-error no type for lynx.SystemInfo
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
19
|
+
globalThis.SystemInfo = lynx.SystemInfo ?? {};
|
|
21
20
|
|
|
22
|
-
lynx.reportError = function(e:
|
|
21
|
+
lynx.reportError = function(e: Error) {
|
|
23
22
|
_ReportError(e, {
|
|
24
23
|
errorCode: 1101, // ErrCode::LYNX_ERROR_CODE_LEPUS in Lynx/base/debug/error_code.h
|
|
25
24
|
});
|
|
@@ -33,13 +32,14 @@ export function setupLynxTestingEnv(): void {
|
|
|
33
32
|
};
|
|
34
33
|
|
|
35
34
|
{
|
|
35
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
36
36
|
function __name(empty: string) {
|
|
37
37
|
return `Native${empty}Modules`;
|
|
38
38
|
}
|
|
39
39
|
// TODO(hongzhiyuan.hzy): make sure this is run before any other code (especially code access `NativeModules`)
|
|
40
|
-
// @ts-
|
|
40
|
+
// @ts-expect-error hack
|
|
41
41
|
if (typeof globalThis[__name('')] === 'undefined') {
|
|
42
|
-
// @ts-
|
|
42
|
+
// @ts-expect-error hack
|
|
43
43
|
globalThis[__name('')] = undefined;
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -48,13 +48,12 @@ export function setupLynxTestingEnv(): void {
|
|
|
48
48
|
dataProcessorDefinition?: DataProcessorDefinition,
|
|
49
49
|
) {
|
|
50
50
|
let hasDefaultDataProcessorExecuted = false;
|
|
51
|
-
// @ts-ignore
|
|
52
51
|
globalThis.processData = (data, processorName) => {
|
|
53
52
|
if (__PROFILE__) {
|
|
54
53
|
console.profile('processData');
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
let r;
|
|
56
|
+
let r: InitData | InitDataRaw;
|
|
58
57
|
try {
|
|
59
58
|
if (processorName) {
|
|
60
59
|
r = dataProcessorDefinition?.dataProcessors?.[processorName]?.(data)
|
|
@@ -63,7 +62,7 @@ export function setupLynxTestingEnv(): void {
|
|
|
63
62
|
r = dataProcessorDefinition?.defaultDataProcessor?.(data) ?? data;
|
|
64
63
|
}
|
|
65
64
|
} catch (e: any) {
|
|
66
|
-
lynx.reportError(e);
|
|
65
|
+
lynx.reportError(e as Error);
|
|
67
66
|
// when there is an error
|
|
68
67
|
// we should perform like dataProcessor returns nothing
|
|
69
68
|
// so use `{}` rather than `data`
|
|
@@ -75,20 +74,22 @@ export function setupLynxTestingEnv(): void {
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
if (hasDefaultDataProcessorExecuted === false) {
|
|
78
|
-
// @ts-
|
|
77
|
+
// @ts-expect-error todo: add types to i18n logic
|
|
79
78
|
if (globalThis.__I18N_RESOURCE_TRANSLATION__) {
|
|
80
79
|
r = {
|
|
81
80
|
...r,
|
|
82
|
-
// @ts-
|
|
81
|
+
// @ts-expect-error todo: add types to i18n logic
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
83
83
|
__I18N_RESOURCE_TRANSLATION__: globalThis.__I18N_RESOURCE_TRANSLATION__,
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
// @ts-
|
|
87
|
+
// @ts-expect-error todo: add types to __EXTRACT_STR__
|
|
88
88
|
if (__EXTRACT_STR__) {
|
|
89
89
|
r = {
|
|
90
90
|
...r,
|
|
91
|
-
// @ts-
|
|
91
|
+
// @ts-expect-error todo: add types to __EXTRACT_STR__
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
92
93
|
_EXTRACT_STR: __EXTRACT_STR_IDENT_FLAG__,
|
|
93
94
|
};
|
|
94
95
|
}
|
|
@@ -100,7 +101,6 @@ export function setupLynxTestingEnv(): void {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
return r;
|
|
103
|
-
// TODO
|
|
104
104
|
};
|
|
105
105
|
};
|
|
106
106
|
|
|
@@ -9,18 +9,24 @@ import { Fragment, lazy as backgroundLazy, createElement } from 'preact/compat';
|
|
|
9
9
|
* const App2 = lazy(() => import("./x").then(({App2}) => ({default: App2})))
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
|
-
export const makeSyncThen = function<T>(result: T) {
|
|
13
|
-
return function
|
|
12
|
+
export const makeSyncThen = function<T>(result: T): Promise<T>['then'] {
|
|
13
|
+
return function<TR1 = T, TR2 = never>(
|
|
14
|
+
this: Promise<T>,
|
|
15
|
+
onF?: ((value: T) => TR1 | PromiseLike<TR1>) | null,
|
|
16
|
+
_onR?: ((reason: any) => TR2 | PromiseLike<TR2>) | null,
|
|
17
|
+
): Promise<TR1 | TR2> {
|
|
14
18
|
if (onF) {
|
|
15
|
-
let ret
|
|
19
|
+
let ret: TR1 | PromiseLike<TR1>;
|
|
16
20
|
try {
|
|
17
21
|
ret = onF(result);
|
|
18
22
|
} catch (e) {
|
|
19
|
-
|
|
23
|
+
// if (onR) {
|
|
24
|
+
// return Promise.resolve(onR(e));
|
|
25
|
+
// }
|
|
26
|
+
return Promise.reject(e as Error);
|
|
20
27
|
}
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
if (ret && typeof ret.then === 'function' /* `thenable` object */) {
|
|
29
|
+
if (ret && typeof (ret as PromiseLike<TR1>).then === 'function' /* `thenable` object */) {
|
|
24
30
|
// lazy(() =>
|
|
25
31
|
// import("./x").then(() => new Promise(...))
|
|
26
32
|
// )
|
|
@@ -39,12 +45,14 @@ export const makeSyncThen = function<T>(result: T) {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
const p = Promise.resolve(ret);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
|
|
49
|
+
const then = makeSyncThen(ret as TR1);
|
|
50
|
+
p.then = then as Promise<Awaited<TR1>>['then'];
|
|
51
|
+
|
|
52
|
+
return p as Promise<TR1 | TR2>;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
|
-
return this
|
|
55
|
+
return this as Promise<TR1 | TR2>;
|
|
48
56
|
};
|
|
49
57
|
};
|
|
50
58
|
|
|
@@ -66,7 +74,7 @@ export const loadLazyBundle: <
|
|
|
66
74
|
const query = __QueryComponent(source);
|
|
67
75
|
let result: T;
|
|
68
76
|
try {
|
|
69
|
-
result = query.evalResult;
|
|
77
|
+
result = query.evalResult as T;
|
|
70
78
|
} catch (e) {
|
|
71
79
|
// Here we cannot return a rejected promise
|
|
72
80
|
// (which will eventually be an unhandled rejection and cause unnecessary redbox)
|
|
@@ -79,12 +87,11 @@ export const loadLazyBundle: <
|
|
|
79
87
|
// Why we should modify the implementation of `then`?
|
|
80
88
|
// We should make it `sync` so lepus first-screen render can use result above instantly
|
|
81
89
|
// We also should keep promise shape
|
|
82
|
-
// @ts-ignore
|
|
83
90
|
r.then = makeSyncThen(result);
|
|
84
91
|
return r;
|
|
85
92
|
} else if (__JS__) {
|
|
86
93
|
return new Promise((resolve, reject) => {
|
|
87
|
-
const callback: (result:
|
|
94
|
+
const callback: (result: { code: number; detail: { schema: string } }) => void = result => {
|
|
88
95
|
const { code, detail } = result;
|
|
89
96
|
if (code === 0) {
|
|
90
97
|
const { schema } = detail;
|
|
@@ -92,7 +99,7 @@ export const loadLazyBundle: <
|
|
|
92
99
|
// `code === 0` means that the lazy bundle has been successfully parsed. However,
|
|
93
100
|
// its javascript files may still fail to run, which would prevent the retrieval of the exports object.
|
|
94
101
|
if (exports) {
|
|
95
|
-
resolve(exports);
|
|
102
|
+
resolve(exports as T);
|
|
96
103
|
return;
|
|
97
104
|
}
|
|
98
105
|
}
|
|
@@ -121,6 +128,7 @@ export function mainThreadLazy<T>(loader: () => Promise<{ default: T } | T>) {
|
|
|
121
128
|
function _Lazy(props: any) {
|
|
122
129
|
try {
|
|
123
130
|
// @ts-expect-error `Lazy` returned from `backgroundLazy` should be a FC
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
124
132
|
return Lazy(props);
|
|
125
133
|
} catch (e) {
|
|
126
134
|
// We should never throw at mainThread
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { options } from 'preact';
|
|
5
5
|
import type { VNode } from 'preact';
|
|
6
6
|
|
|
7
|
-
import { DIFF } from '../renderToOpcodes/constants.js';
|
|
8
7
|
import { __globalSnapshotPatch } from '../lifecycle/patch/snapshotPatch.js';
|
|
8
|
+
import { DIFF } from '../renderToOpcodes/constants.js';
|
|
9
9
|
import { isSdkVersionGt } from '../utils.js';
|
|
10
10
|
|
|
11
11
|
enum PerformanceTimingKeys {
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
// Copyright 2025 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.
|
|
1
4
|
import { options } from 'preact';
|
|
2
|
-
import type { VNode } from 'preact';
|
|
5
|
+
import type { Component, VNode } from 'preact';
|
|
6
|
+
|
|
3
7
|
import { COMPONENT, DIFF, DIFFED, FORCE } from '../renderToOpcodes/constants.js';
|
|
4
8
|
|
|
5
9
|
const sForcedVNode = Symbol('FORCE');
|
|
@@ -8,7 +12,7 @@ type PatchedVNode = VNode & { [sForcedVNode]?: true };
|
|
|
8
12
|
|
|
9
13
|
export function runWithForce(cb: () => void): void {
|
|
10
14
|
// save vnode and its `_component` in WeakMap
|
|
11
|
-
const m = new WeakMap<VNode,
|
|
15
|
+
const m = new WeakMap<VNode, Component>();
|
|
12
16
|
|
|
13
17
|
const oldDiff = options[DIFF];
|
|
14
18
|
|
|
@@ -22,13 +26,13 @@ export function runWithForce(cb: () => void): void {
|
|
|
22
26
|
// but it will be set later
|
|
23
27
|
Object.defineProperty(vnode, COMPONENT, {
|
|
24
28
|
configurable: true,
|
|
25
|
-
set(c) {
|
|
29
|
+
set(c: Component) {
|
|
26
30
|
m.set(vnode, c);
|
|
27
31
|
if (c) {
|
|
28
32
|
c[FORCE] = true;
|
|
29
33
|
}
|
|
30
34
|
},
|
|
31
|
-
get() {
|
|
35
|
+
get(): Component | undefined {
|
|
32
36
|
return m.get(vnode);
|
|
33
37
|
},
|
|
34
38
|
});
|
|
@@ -50,7 +54,7 @@ export function runWithForce(cb: () => void): void {
|
|
|
50
54
|
delete vnode[COMPONENT];
|
|
51
55
|
delete vnode[sForcedVNode];
|
|
52
56
|
// restore
|
|
53
|
-
vnode[COMPONENT] = m.get(vnode)
|
|
57
|
+
vnode[COMPONENT] = m.get(vnode)!;
|
|
54
58
|
}
|
|
55
59
|
};
|
|
56
60
|
|