@lynx-js/react 0.105.1 → 0.106.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/CHANGELOG.md +40 -0
- package/package.json +2 -2
- package/refresh/.turbo/turbo-build.log +1 -1
- package/refresh/package.json +1 -1
- package/runtime/lib/backgroundSnapshot.d.ts +1 -1
- package/runtime/lib/backgroundSnapshot.js +2 -2
- package/runtime/lib/backgroundSnapshot.js.map +1 -1
- package/runtime/lib/compat/initData.js +0 -2
- package/runtime/lib/compat/initData.js.map +1 -1
- package/runtime/lib/gesture/processGesture.js +3 -0
- package/runtime/lib/gesture/processGesture.js.map +1 -1
- package/runtime/lib/gesture/types.d.ts +2 -0
- package/runtime/lib/internal.d.ts +2 -1
- package/runtime/lib/internal.js +3 -2
- package/runtime/lib/internal.js.map +1 -1
- package/runtime/lib/lifecycle/destroy.js +3 -3
- package/runtime/lib/lifecycle/destroy.js.map +1 -1
- package/runtime/lib/lifecycle/{patchUpdate.d.ts → patch/commit.d.ts} +8 -6
- package/runtime/lib/lifecycle/patch/commit.js +167 -0
- package/runtime/lib/lifecycle/patch/commit.js.map +1 -0
- package/runtime/lib/lifecycle/patch/snapshotPatch.js.map +1 -0
- package/runtime/lib/{snapshotPatchApply.js → lifecycle/patch/snapshotPatchApply.js} +1 -4
- package/runtime/lib/lifecycle/patch/snapshotPatchApply.js.map +1 -0
- package/runtime/lib/lifecycle/patch/updateMainThread.d.ts +3 -0
- package/runtime/lib/lifecycle/patch/updateMainThread.js +56 -0
- package/runtime/lib/lifecycle/patch/updateMainThread.js.map +1 -0
- package/runtime/lib/lifecycle/reload.js +3 -4
- package/runtime/lib/lifecycle/reload.js.map +1 -1
- package/runtime/lib/lifecycle/render.d.ts +3 -1
- package/runtime/lib/lifecycle/render.js +9 -2
- package/runtime/lib/lifecycle/render.js.map +1 -1
- package/runtime/lib/list.d.ts +3 -0
- package/runtime/lib/list.js +11 -3
- package/runtime/lib/list.js.map +1 -1
- package/runtime/lib/lynx/calledByNative.js +40 -5
- package/runtime/lib/lynx/calledByNative.js.map +1 -1
- package/runtime/lib/lynx/component.js +3 -3
- package/runtime/lib/lynx/component.js.map +1 -1
- package/runtime/lib/lynx/dynamic-js.js +0 -1
- package/runtime/lib/lynx/dynamic-js.js.map +1 -1
- package/runtime/lib/lynx/env.js +1 -2
- package/runtime/lib/lynx/env.js.map +1 -1
- 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/tt.d.ts +1 -0
- package/runtime/lib/lynx/tt.js +48 -7
- package/runtime/lib/lynx/tt.js.map +1 -1
- package/runtime/lib/lynx-api.d.ts +1 -1
- package/runtime/lib/lynx-api.js +2 -2
- package/runtime/lib/lynx-api.js.map +1 -1
- package/runtime/lib/lynx.d.ts +0 -1
- package/runtime/lib/lynx.js +4 -46
- package/runtime/lib/lynx.js.map +1 -1
- package/runtime/lib/opcodes.d.ts +6 -0
- package/runtime/lib/opcodes.js +70 -0
- package/runtime/lib/opcodes.js.map +1 -1
- package/runtime/lib/root.d.ts +1 -0
- package/runtime/lib/root.js.map +1 -1
- package/runtime/lib/snapshot/ref.d.ts +2 -2
- package/runtime/lib/snapshot/ref.js +6 -7
- package/runtime/lib/snapshot/ref.js.map +1 -1
- package/runtime/lib/snapshot.js +1 -1
- package/runtime/lib/snapshot.js.map +1 -1
- package/runtime/lib/worklet/functionCall.js.map +1 -1
- package/runtime/lib/worklet/hmr.js +1 -1
- package/runtime/lib/worklet/hmr.js.map +1 -1
- package/runtime/lib/worklet/runOnBackground.js.map +1 -1
- package/runtime/lib/worklet/workletRef.js +1 -1
- package/runtime/lib/worklet/workletRef.js.map +1 -1
- package/runtime/src/backgroundSnapshot.ts +3 -3
- package/runtime/src/compat/initData.ts +5 -6
- package/runtime/src/gesture/processGesture.ts +4 -0
- package/runtime/src/gesture/types.ts +2 -0
- package/runtime/src/internal.ts +4 -2
- package/runtime/src/lifecycle/destroy.ts +3 -4
- package/runtime/src/lifecycle/{patchUpdate.ts → patch/commit.ts} +94 -100
- package/runtime/src/{snapshotPatchApply.ts → lifecycle/patch/snapshotPatchApply.ts} +2 -2
- package/runtime/src/lifecycle/patch/updateMainThread.ts +71 -0
- package/runtime/src/lifecycle/reload.ts +3 -5
- package/runtime/src/lifecycle/render.ts +12 -3
- package/runtime/src/list.ts +12 -3
- package/runtime/src/lynx/calledByNative.ts +47 -4
- package/runtime/src/lynx/component.ts +3 -3
- package/runtime/src/lynx/dynamic-js.ts +2 -3
- package/runtime/src/lynx/env.ts +2 -2
- package/runtime/src/lynx/lazy-bundle.ts +1 -1
- package/runtime/src/lynx/performance.ts +3 -2
- package/runtime/src/lynx/tt.ts +58 -9
- package/runtime/src/lynx-api.ts +3 -3
- package/runtime/src/lynx.ts +5 -55
- package/runtime/src/opcodes.ts +90 -0
- package/runtime/src/root.ts +1 -1
- package/runtime/src/snapshot/ref.ts +6 -9
- package/runtime/src/snapshot.ts +1 -1
- package/runtime/src/worklet/functionCall.ts +1 -1
- package/runtime/src/worklet/hmr.ts +1 -1
- package/runtime/src/worklet/runOnBackground.ts +4 -4
- package/runtime/src/worklet/workletRef.ts +1 -1
- package/transform/dist/wasm.cjs +1 -1
- package/types/react.docs.d.ts +1 -1
- package/runtime/lib/lifecycle/patchUpdate.js +0 -179
- package/runtime/lib/lifecycle/patchUpdate.js.map +0 -1
- package/runtime/lib/snapshotPatch.js.map +0 -1
- package/runtime/lib/snapshotPatchApply.js.map +0 -1
- /package/runtime/lib/{snapshotPatch.d.ts → lifecycle/patch/snapshotPatch.d.ts} +0 -0
- /package/runtime/lib/{snapshotPatch.js → lifecycle/patch/snapshotPatch.js} +0 -0
- /package/runtime/lib/{snapshotPatchApply.d.ts → lifecycle/patch/snapshotPatchApply.d.ts} +0 -0
- /package/runtime/src/{snapshotPatch.ts → lifecycle/patch/snapshotPatch.ts} +0 -0
|
@@ -1,31 +1,27 @@
|
|
|
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 { options } from 'preact';
|
|
5
4
|
import type { VNode } from 'preact';
|
|
5
|
+
import { options } from 'preact';
|
|
6
6
|
import type { Component } from 'preact/compat';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import { LifecycleConstant } from '
|
|
11
|
-
import { __pendingListUpdates } from '../list.js';
|
|
12
|
-
import { runDelayedUnmounts, takeDelayedUnmounts } from './delayUnmount.js';
|
|
13
|
-
import { getReloadVersion } from './pass.js';
|
|
8
|
+
import type { SnapshotPatch } from './snapshotPatch.js';
|
|
9
|
+
import { takeGlobalSnapshotPatch } from './snapshotPatch.js';
|
|
10
|
+
import { LifecycleConstant } from '../../lifecycleConstant.js';
|
|
14
11
|
import {
|
|
15
12
|
PerformanceTimingKeys,
|
|
16
13
|
globalPipelineOptions,
|
|
17
14
|
markTiming,
|
|
18
15
|
markTimingLegacy,
|
|
19
16
|
setPipeline,
|
|
20
|
-
} from '
|
|
21
|
-
import { CATCH_ERROR, COMMIT, RENDER_CALLBACKS, VNODE } from '
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { takeWorkletRefInitValuePatch } from '../worklet/workletRefPool.js';
|
|
17
|
+
} from '../../lynx/performance.js';
|
|
18
|
+
import { CATCH_ERROR, COMMIT, RENDER_CALLBACKS, VNODE } from '../../renderToOpcodes/constants.js';
|
|
19
|
+
import { updateBackgroundRefs } from '../../snapshot/ref.js';
|
|
20
|
+
import { backgroundSnapshotInstanceManager } from '../../snapshot.js';
|
|
21
|
+
import { isEmptyObject } from '../../utils.js';
|
|
22
|
+
import { takeWorkletRefInitValuePatch } from '../../worklet/workletRefPool.js';
|
|
23
|
+
import { runDelayedUnmounts, takeDelayedUnmounts } from '../delayUnmount.js';
|
|
24
|
+
import { getReloadVersion } from '../pass.js';
|
|
29
25
|
|
|
30
26
|
let globalFlushOptions: FlushOptions = {};
|
|
31
27
|
|
|
@@ -34,77 +30,56 @@ let nextCommitTaskId = 1;
|
|
|
34
30
|
|
|
35
31
|
let globalBackgroundSnapshotInstancesToRemove: number[] = [];
|
|
36
32
|
|
|
33
|
+
let patchesToCommit: Patch[] = [];
|
|
34
|
+
|
|
37
35
|
interface Patch {
|
|
36
|
+
id: number;
|
|
38
37
|
snapshotPatch?: SnapshotPatch;
|
|
39
38
|
workletRefInitValuePatch?: [id: number, value: unknown][];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface PatchList {
|
|
42
|
+
patchList: Patch[];
|
|
40
43
|
flushOptions?: FlushOptions;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
interface PatchOptions {
|
|
44
|
-
commitTaskId: number;
|
|
45
47
|
pipelineOptions?: PipelineOptions;
|
|
46
|
-
reloadVersion
|
|
48
|
+
reloadVersion: number;
|
|
47
49
|
isHydration?: boolean;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
function replaceCommitHook(): void {
|
|
53
|
+
// use our own `options.debounceRendering` to insert a timing flag before render
|
|
54
|
+
type DebounceRendering = (f: () => void) => void;
|
|
55
|
+
const injectDebounceRendering = (debounceRendering: DebounceRendering): DebounceRendering => {
|
|
56
|
+
return (f: () => void) => {
|
|
57
|
+
debounceRendering(() => {
|
|
58
|
+
f();
|
|
59
|
+
void commitToMainThread();
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const defaultDebounceRendering = options.debounceRendering?.bind(options)
|
|
64
|
+
?? (Promise.prototype.then.bind(Promise.resolve()) as DebounceRendering);
|
|
65
|
+
let _debounceRendering = injectDebounceRendering(defaultDebounceRendering);
|
|
66
|
+
Object.defineProperty(options, 'debounceRendering', {
|
|
67
|
+
get() {
|
|
68
|
+
return _debounceRendering;
|
|
55
69
|
},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
setPipeline(patchOptions.pipelineOptions);
|
|
62
|
-
markTiming(PerformanceTimingKeys.parse_changes_start);
|
|
63
|
-
let { snapshotPatch, workletRefInitValuePatch, flushOptions } = JSON.parse(data) as Patch;
|
|
64
|
-
markTiming(PerformanceTimingKeys.parse_changes_end);
|
|
65
|
-
|
|
66
|
-
markTiming(PerformanceTimingKeys.patch_changes_start);
|
|
67
|
-
updateWorkletRefInitValueChanges(workletRefInitValuePatch);
|
|
68
|
-
__pendingListUpdates.clear();
|
|
69
|
-
if (snapshotPatch) {
|
|
70
|
-
snapshotPatchApply(snapshotPatch);
|
|
71
|
-
}
|
|
72
|
-
__pendingListUpdates.flush();
|
|
73
|
-
// console.debug('********** Lepus updatePatch:');
|
|
74
|
-
// printSnapshotInstance(snapshotInstanceManager.values.get(-1)!);
|
|
75
|
-
|
|
76
|
-
commitMainThreadPatchUpdate(patchOptions.commitTaskId);
|
|
77
|
-
if (patchOptions.isHydration) {
|
|
78
|
-
clearDelayedWorklets();
|
|
79
|
-
}
|
|
80
|
-
markTiming(PerformanceTimingKeys.patch_changes_end);
|
|
81
|
-
flushOptions ||= {};
|
|
82
|
-
if (patchOptions.pipelineOptions) {
|
|
83
|
-
flushOptions.pipelineOptions = patchOptions.pipelineOptions;
|
|
84
|
-
}
|
|
85
|
-
// TODO: triggerDataUpdated?
|
|
86
|
-
__FlushElementTree(__page, flushOptions);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
Object.assign(globalThis, { [LifecycleConstant.patchUpdate]: updatePatch });
|
|
90
|
-
}
|
|
70
|
+
set(debounceRendering: DebounceRendering) {
|
|
71
|
+
_debounceRendering = injectDebounceRendering(debounceRendering);
|
|
72
|
+
},
|
|
73
|
+
});
|
|
91
74
|
|
|
92
|
-
function replaceCommitHook(): void {
|
|
93
75
|
const oldCommit = options[COMMIT];
|
|
94
|
-
|
|
76
|
+
const commit = async (vnode: VNode, commitQueue: any[]) => {
|
|
95
77
|
if (__LEPUS__) {
|
|
96
78
|
// for testing only
|
|
97
79
|
commitQueue.length = 0;
|
|
98
80
|
return;
|
|
99
81
|
}
|
|
100
|
-
|
|
101
|
-
markTimingLegacy(PerformanceTimingKeys.update_diff_vdom_end);
|
|
102
|
-
markTiming(PerformanceTimingKeys.diff_vdom_end);
|
|
103
|
-
markTiming(PerformanceTimingKeys.pack_changes_start);
|
|
104
|
-
if (__PROFILE__) {
|
|
105
|
-
console.profile('commitChanges');
|
|
106
|
-
}
|
|
107
|
-
const renderCallbacks = commitQueue.map(component => {
|
|
82
|
+
const renderCallbacks = commitQueue.map((component: Component<any>) => {
|
|
108
83
|
const ret = {
|
|
109
84
|
component,
|
|
110
85
|
[RENDER_CALLBACKS]: component[RENDER_CALLBACKS],
|
|
@@ -130,7 +105,7 @@ function replaceCommitHook(): void {
|
|
|
130
105
|
cb.call(wrapper.component);
|
|
131
106
|
});
|
|
132
107
|
} catch (e) {
|
|
133
|
-
options[CATCH_ERROR](e, wrapper[VNODE]);
|
|
108
|
+
options[CATCH_ERROR](e, wrapper[VNODE]!);
|
|
134
109
|
}
|
|
135
110
|
});
|
|
136
111
|
if (backgroundSnapshotInstancesToRemove.length) {
|
|
@@ -143,50 +118,75 @@ function replaceCommitHook(): void {
|
|
|
143
118
|
});
|
|
144
119
|
|
|
145
120
|
const snapshotPatch = takeGlobalSnapshotPatch();
|
|
146
|
-
const flushOptions = globalFlushOptions;
|
|
147
121
|
const workletRefInitValuePatch = takeWorkletRefInitValuePatch();
|
|
148
|
-
globalFlushOptions = {};
|
|
149
122
|
if (!snapshotPatch && workletRefInitValuePatch.length === 0) {
|
|
150
123
|
// before hydration, skip patch
|
|
151
|
-
if (__PROFILE__) {
|
|
152
|
-
console.profileEnd();
|
|
153
|
-
}
|
|
154
124
|
return;
|
|
155
125
|
}
|
|
156
126
|
|
|
157
|
-
const patch: Patch = {
|
|
127
|
+
const patch: Patch = {
|
|
128
|
+
id: commitTaskId,
|
|
129
|
+
};
|
|
158
130
|
// TODO: check all fields in `flushOptions` from runtime3
|
|
159
131
|
if (snapshotPatch?.length) {
|
|
160
132
|
patch.snapshotPatch = snapshotPatch;
|
|
161
133
|
}
|
|
162
|
-
if (!isEmptyObject(flushOptions)) {
|
|
163
|
-
patch.flushOptions = flushOptions;
|
|
164
|
-
}
|
|
165
134
|
if (workletRefInitValuePatch.length) {
|
|
166
135
|
patch.workletRefInitValuePatch = workletRefInitValuePatch;
|
|
167
136
|
}
|
|
168
|
-
await commitPatchUpdate(patch, { commitTaskId });
|
|
169
137
|
|
|
170
|
-
|
|
138
|
+
patchesToCommit.push(patch);
|
|
139
|
+
};
|
|
140
|
+
options[COMMIT] = commit as ((...args: Parameters<typeof commit>) => void);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async function commitToMainThread(): Promise<void> {
|
|
144
|
+
if (patchesToCommit.length === 0) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
markTimingLegacy(PerformanceTimingKeys.update_diff_vdom_end);
|
|
149
|
+
markTiming(PerformanceTimingKeys.diff_vdom_end);
|
|
150
|
+
|
|
151
|
+
const flushOptions = globalFlushOptions;
|
|
152
|
+
globalFlushOptions = {};
|
|
153
|
+
|
|
154
|
+
const patchList: PatchList = {
|
|
155
|
+
patchList: patchesToCommit,
|
|
156
|
+
};
|
|
157
|
+
patchesToCommit = [];
|
|
158
|
+
|
|
159
|
+
if (!isEmptyObject(flushOptions)) {
|
|
160
|
+
patchList.flushOptions = flushOptions;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
await commitPatchUpdate(patchList, {});
|
|
164
|
+
|
|
165
|
+
for (const patch of patchList.patchList) {
|
|
166
|
+
const commitTask = globalCommitTaskMap.get(patch.id);
|
|
171
167
|
if (commitTask) {
|
|
172
168
|
commitTask();
|
|
173
|
-
globalCommitTaskMap.delete(
|
|
169
|
+
globalCommitTaskMap.delete(patch.id);
|
|
174
170
|
}
|
|
175
|
-
}
|
|
171
|
+
}
|
|
176
172
|
}
|
|
177
173
|
|
|
178
|
-
function commitPatchUpdate(
|
|
174
|
+
function commitPatchUpdate(patchList: PatchList, patchOptions: Omit<PatchOptions, 'reloadVersion'>): Promise<void> {
|
|
179
175
|
return new Promise(resolve => {
|
|
180
176
|
// console.debug('********** JS update:');
|
|
181
177
|
// printSnapshotInstance(
|
|
182
178
|
// (backgroundSnapshotInstanceManager.values.get(1) || backgroundSnapshotInstanceManager.values.get(-1))!,
|
|
183
179
|
// );
|
|
184
|
-
// console.debug('commitPatchUpdate: ', JSON.stringify(
|
|
180
|
+
// console.debug('commitPatchUpdate: ', JSON.stringify(patchList));
|
|
181
|
+
if (__PROFILE__) {
|
|
182
|
+
console.profile('commitChanges');
|
|
183
|
+
}
|
|
184
|
+
markTiming(PerformanceTimingKeys.pack_changes_start);
|
|
185
185
|
const obj: {
|
|
186
186
|
data: string;
|
|
187
187
|
patchOptions: PatchOptions;
|
|
188
188
|
} = {
|
|
189
|
-
data: JSON.stringify(
|
|
189
|
+
data: JSON.stringify(patchList),
|
|
190
190
|
patchOptions: {
|
|
191
191
|
...patchOptions,
|
|
192
192
|
reloadVersion: getReloadVersion(),
|
|
@@ -197,20 +197,13 @@ function commitPatchUpdate(data: Patch, patchOptions: PatchOptions): Promise<voi
|
|
|
197
197
|
obj.patchOptions.pipelineOptions = globalPipelineOptions;
|
|
198
198
|
setPipeline(undefined);
|
|
199
199
|
}
|
|
200
|
+
lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, resolve);
|
|
200
201
|
if (__PROFILE__) {
|
|
201
202
|
console.profileEnd();
|
|
202
203
|
}
|
|
203
|
-
lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, resolve);
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
function commitMainThreadPatchUpdate(commitTaskId?: number): void {
|
|
208
|
-
const refPatch = takeGlobalRefPatchMap();
|
|
209
|
-
if (!isEmptyObject(refPatch)) {
|
|
210
|
-
__OnLifecycleEvent([LifecycleConstant.ref, { commitTaskId, refPatch: JSON.stringify(refPatch) }]);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
207
|
function genCommitTaskId(): number {
|
|
215
208
|
return nextCommitTaskId++;
|
|
216
209
|
}
|
|
@@ -219,7 +212,7 @@ function replaceRequestAnimationFrame(): void {
|
|
|
219
212
|
// to make afterPaintEffects run faster
|
|
220
213
|
const resolvedPromise = Promise.resolve();
|
|
221
214
|
options.requestAnimationFrame = (cb: () => void) => {
|
|
222
|
-
resolvedPromise.then(cb);
|
|
215
|
+
void resolvedPromise.then(cb);
|
|
223
216
|
};
|
|
224
217
|
}
|
|
225
218
|
|
|
@@ -227,14 +220,15 @@ function replaceRequestAnimationFrame(): void {
|
|
|
227
220
|
* @internal
|
|
228
221
|
*/
|
|
229
222
|
export {
|
|
230
|
-
injectUpdatePatch,
|
|
231
223
|
commitPatchUpdate,
|
|
232
|
-
|
|
224
|
+
commitToMainThread,
|
|
233
225
|
genCommitTaskId,
|
|
234
|
-
commitMainThreadPatchUpdate,
|
|
235
|
-
replaceRequestAnimationFrame,
|
|
236
|
-
globalFlushOptions,
|
|
237
|
-
globalCommitTaskMap,
|
|
238
226
|
globalBackgroundSnapshotInstancesToRemove,
|
|
227
|
+
globalCommitTaskMap,
|
|
228
|
+
globalFlushOptions,
|
|
239
229
|
nextCommitTaskId,
|
|
230
|
+
replaceCommitHook,
|
|
231
|
+
replaceRequestAnimationFrame,
|
|
232
|
+
type PatchOptions,
|
|
233
|
+
type PatchList,
|
|
240
234
|
};
|
|
@@ -1,9 +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
|
-
import { createSnapshot, SnapshotInstance, snapshotInstanceManager, snapshotManager } from './snapshot.js';
|
|
5
4
|
import type { SnapshotPatch } from './snapshotPatch.js';
|
|
6
5
|
import { SnapshotOperation } from './snapshotPatch.js';
|
|
6
|
+
import { SnapshotInstance, createSnapshot, snapshotInstanceManager, snapshotManager } from '../../snapshot.js';
|
|
7
7
|
|
|
8
8
|
function reportCtxNotFound(): void {
|
|
9
9
|
lynx.reportError(new Error(`snapshotPatchApply failed: ctx not found`));
|
|
@@ -25,7 +25,7 @@ export function snapshotPatchApply(snapshotPatch: SnapshotPatch): void {
|
|
|
25
25
|
const beforeId = snapshotPatch[++i];
|
|
26
26
|
const parent = snapshotInstanceManager.values.get(parentId);
|
|
27
27
|
const child = snapshotInstanceManager.values.get(childId);
|
|
28
|
-
const existingNode = snapshotInstanceManager.values.get(beforeId
|
|
28
|
+
const existingNode = snapshotInstanceManager.values.get(beforeId);
|
|
29
29
|
if (!parent || !child) {
|
|
30
30
|
reportCtxNotFound();
|
|
31
31
|
} else {
|
|
@@ -0,0 +1,71 @@
|
|
|
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 { clearDelayedWorklets, updateWorkletRefInitValueChanges } from '@lynx-js/react/worklet-runtime/bindings';
|
|
6
|
+
|
|
7
|
+
import type { PatchList, PatchOptions } from './commit.js';
|
|
8
|
+
import { snapshotPatchApply } from './snapshotPatchApply.js';
|
|
9
|
+
import { LifecycleConstant } from '../../lifecycleConstant.js';
|
|
10
|
+
import { __pendingListUpdates } from '../../list.js';
|
|
11
|
+
import { PerformanceTimingKeys, markTiming, setPipeline } from '../../lynx/performance.js';
|
|
12
|
+
import { takeGlobalRefPatchMap } from '../../snapshot/ref.js';
|
|
13
|
+
import { __page } from '../../snapshot.js';
|
|
14
|
+
import { isEmptyObject } from '../../utils.js';
|
|
15
|
+
import { getReloadVersion } from '../pass.js';
|
|
16
|
+
|
|
17
|
+
function updateMainThread(
|
|
18
|
+
{ data, patchOptions }: {
|
|
19
|
+
data: string;
|
|
20
|
+
patchOptions: PatchOptions;
|
|
21
|
+
},
|
|
22
|
+
): void {
|
|
23
|
+
if ((patchOptions.reloadVersion) < getReloadVersion()) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setPipeline(patchOptions.pipelineOptions);
|
|
28
|
+
markTiming(PerformanceTimingKeys.parse_changes_start);
|
|
29
|
+
const { patchList, flushOptions = {} } = JSON.parse(data) as PatchList;
|
|
30
|
+
|
|
31
|
+
markTiming(PerformanceTimingKeys.parse_changes_end);
|
|
32
|
+
markTiming(PerformanceTimingKeys.patch_changes_start);
|
|
33
|
+
|
|
34
|
+
for (const { snapshotPatch, workletRefInitValuePatch, id } of patchList) {
|
|
35
|
+
updateWorkletRefInitValueChanges(workletRefInitValuePatch);
|
|
36
|
+
__pendingListUpdates.clear();
|
|
37
|
+
if (snapshotPatch) {
|
|
38
|
+
snapshotPatchApply(snapshotPatch);
|
|
39
|
+
}
|
|
40
|
+
__pendingListUpdates.flush();
|
|
41
|
+
// console.debug('********** Lepus updatePatch:');
|
|
42
|
+
// printSnapshotInstance(snapshotInstanceManager.values.get(-1)!);
|
|
43
|
+
|
|
44
|
+
commitMainThreadPatchUpdate(id);
|
|
45
|
+
}
|
|
46
|
+
markTiming(PerformanceTimingKeys.patch_changes_end);
|
|
47
|
+
if (patchOptions.isHydration) {
|
|
48
|
+
clearDelayedWorklets();
|
|
49
|
+
}
|
|
50
|
+
if (patchOptions.pipelineOptions) {
|
|
51
|
+
flushOptions.pipelineOptions = patchOptions.pipelineOptions;
|
|
52
|
+
}
|
|
53
|
+
// TODO: triggerDataUpdated?
|
|
54
|
+
__FlushElementTree(__page, flushOptions);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function injectUpdateMainThread(): void {
|
|
58
|
+
Object.assign(globalThis, { [LifecycleConstant.patchUpdate]: updateMainThread });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function commitMainThreadPatchUpdate(commitTaskId?: number): void {
|
|
62
|
+
const refPatch = takeGlobalRefPatchMap();
|
|
63
|
+
if (!isEmptyObject(refPatch)) {
|
|
64
|
+
__OnLifecycleEvent([LifecycleConstant.ref, { commitTaskId, refPatch: JSON.stringify(refPatch) }]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export { commitMainThreadPatchUpdate, injectUpdateMainThread };
|
|
@@ -1,19 +1,17 @@
|
|
|
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 { render } from 'preact';
|
|
5
|
-
|
|
6
4
|
import { __root, setRoot } from '../root.js';
|
|
7
5
|
import { SnapshotInstance, __page, snapshotInstanceManager } from '../snapshot.js';
|
|
8
6
|
import { isEmptyObject } from '../utils.js';
|
|
9
7
|
import { destroyBackground } from './destroy.js';
|
|
10
8
|
import { increaseReloadVersion } from './pass.js';
|
|
11
|
-
import { renderMainThread } from './render.js';
|
|
9
|
+
import { renderBackground, renderMainThread } from './render.js';
|
|
12
10
|
import { hydrate } from '../hydrate.js';
|
|
13
11
|
import { LifecycleConstant } from '../lifecycleConstant.js';
|
|
14
12
|
import { __pendingListUpdates } from '../list.js';
|
|
15
13
|
import { takeGlobalRefPatchMap } from '../snapshot/ref.js';
|
|
16
|
-
import { deinitGlobalSnapshotPatch } from '
|
|
14
|
+
import { deinitGlobalSnapshotPatch } from './patch/snapshotPatch.js';
|
|
17
15
|
import { destroyWorklet } from '../worklet/destroy.js';
|
|
18
16
|
|
|
19
17
|
function reloadMainThread(data: any, options: UpdatePageOption): void {
|
|
@@ -71,7 +69,7 @@ function reloadBackground(updateData: Record<string, any>): void {
|
|
|
71
69
|
// COW when modify `lynx.__initData` to make sure Provider & Consumer works
|
|
72
70
|
lynx.__initData = Object.assign({}, lynx.__initData, updateData);
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
renderBackground(__root.__jsx, __root as any);
|
|
75
73
|
|
|
76
74
|
if (__PROFILE__) {
|
|
77
75
|
console.profileEnd();
|
|
@@ -2,11 +2,12 @@
|
|
|
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
4
|
import { render } from 'preact';
|
|
5
|
+
import type { ComponentChild, ContainerNode } from 'preact';
|
|
5
6
|
|
|
6
7
|
import { renderOpcodesInto } from '../opcodes.js';
|
|
7
8
|
import { render as renderToString } from '../renderToOpcodes/index.js';
|
|
8
9
|
import { __root } from '../root.js';
|
|
9
|
-
|
|
10
|
+
import { commitToMainThread } from './patch/commit.js';
|
|
10
11
|
|
|
11
12
|
function renderMainThread(): void {
|
|
12
13
|
/* v8 ignore start */
|
|
@@ -24,7 +25,7 @@ function renderMainThread(): void {
|
|
|
24
25
|
// @ts-ignore
|
|
25
26
|
opcodes = renderToString(__root.__jsx);
|
|
26
27
|
} catch (e) {
|
|
27
|
-
lynx.reportError(e);
|
|
28
|
+
lynx.reportError(e as Error);
|
|
28
29
|
opcodes = [];
|
|
29
30
|
} finally {
|
|
30
31
|
if (__PROFILE__) {
|
|
@@ -36,6 +37,9 @@ function renderMainThread(): void {
|
|
|
36
37
|
console.profile('renderOpcodesInto');
|
|
37
38
|
}
|
|
38
39
|
renderOpcodesInto(opcodes, __root as any);
|
|
40
|
+
if (__ENABLE_SSR__) {
|
|
41
|
+
__root.__opcodes = opcodes;
|
|
42
|
+
}
|
|
39
43
|
if (__PROFILE__) {
|
|
40
44
|
console.profileEnd();
|
|
41
45
|
}
|
|
@@ -43,4 +47,9 @@ function renderMainThread(): void {
|
|
|
43
47
|
/* v8 ignore stop */
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
|
|
50
|
+
function renderBackground(vnode: ComponentChild, parent: ContainerNode): void {
|
|
51
|
+
render(vnode, parent);
|
|
52
|
+
void commitToMainThread();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { renderMainThread, renderBackground };
|
package/runtime/src/list.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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
4
|
import { hydrate } from './hydrate.js';
|
|
5
|
-
import { commitMainThreadPatchUpdate } from './lifecycle/
|
|
5
|
+
import { commitMainThreadPatchUpdate } from './lifecycle/patch/updateMainThread.js';
|
|
6
6
|
import type { SnapshotInstance } from './snapshot.js';
|
|
7
7
|
|
|
8
8
|
export interface ListUpdateInfo {
|
|
@@ -223,8 +223,17 @@ export const __pendingListUpdates = {
|
|
|
223
223
|
},
|
|
224
224
|
};
|
|
225
225
|
|
|
226
|
-
const gSignMap: Record<number, Map<number, SnapshotInstance>> = {};
|
|
227
|
-
const gRecycleMap: Record<number, Map<string, Map<number, SnapshotInstance>>> = {};
|
|
226
|
+
export const gSignMap: Record<number, Map<number, SnapshotInstance>> = {};
|
|
227
|
+
export const gRecycleMap: Record<number, Map<string, Map<number, SnapshotInstance>>> = {};
|
|
228
|
+
|
|
229
|
+
export function clearListGlobal(): void {
|
|
230
|
+
for (const key in gSignMap) {
|
|
231
|
+
delete gSignMap[key];
|
|
232
|
+
}
|
|
233
|
+
for (const key in gRecycleMap) {
|
|
234
|
+
delete gRecycleMap[key];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
228
237
|
|
|
229
238
|
export function componentAtIndexFactory(ctx: SnapshotInstance[]): ComponentAtIndexCallback {
|
|
230
239
|
const componentAtIndex = (
|
|
@@ -13,8 +13,51 @@ import { renderMainThread } from '../lifecycle/render.js';
|
|
|
13
13
|
import { hydrate } from '../hydrate.js';
|
|
14
14
|
import { markTiming, PerformanceTimingKeys, setPipeline } from './performance.js';
|
|
15
15
|
import { __pendingListUpdates } from '../list.js';
|
|
16
|
+
import { ssrHydrateByOpcodes } from '../opcodes.js';
|
|
17
|
+
|
|
18
|
+
function ssrEncode() {
|
|
19
|
+
const { __opcodes } = __root;
|
|
20
|
+
delete __root.__opcodes;
|
|
21
|
+
|
|
22
|
+
const oldToJSON = SnapshotInstance.prototype.toJSON;
|
|
23
|
+
SnapshotInstance.prototype.toJSON = function(this: SnapshotInstance): any {
|
|
24
|
+
return [
|
|
25
|
+
this.type,
|
|
26
|
+
this.__id,
|
|
27
|
+
this.__elements,
|
|
28
|
+
];
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
return JSON.stringify({ __opcodes, __root_values: __root.__values });
|
|
33
|
+
} finally {
|
|
34
|
+
SnapshotInstance.prototype.toJSON = oldToJSON;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function ssrHydrate(info: string) {
|
|
39
|
+
const nativePage = __GetPageElement();
|
|
40
|
+
if (!nativePage) {
|
|
41
|
+
throw new Error('SSR Hydration Failed! Please check if the SSR content loaded successfully!');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const refsMap = __GetTemplateParts(nativePage);
|
|
45
|
+
|
|
46
|
+
const { __opcodes, __root_values } = JSON.parse(info);
|
|
47
|
+
__root_values && __root.setAttribute('values', __root_values);
|
|
48
|
+
ssrHydrateByOpcodes(__opcodes, __root as SnapshotInstance, refsMap);
|
|
49
|
+
|
|
50
|
+
(__root as SnapshotInstance).__elements = [nativePage];
|
|
51
|
+
(__root as SnapshotInstance).__element_root = nativePage;
|
|
52
|
+
}
|
|
16
53
|
|
|
17
54
|
function injectCalledByNative(): void {
|
|
55
|
+
if (process.env['NODE_ENV'] !== 'test') {
|
|
56
|
+
if (__FIRST_SCREEN_SYNC_TIMING__ !== 'jsReady' && __ENABLE_SSR__) {
|
|
57
|
+
throw new Error('`firstScreenSyncTiming` must be `jsReady` when SSR is enabled');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
18
61
|
const calledByNative: LynxCallByNative = {
|
|
19
62
|
renderPage,
|
|
20
63
|
updatePage,
|
|
@@ -23,9 +66,13 @@ function injectCalledByNative(): void {
|
|
|
23
66
|
return null;
|
|
24
67
|
},
|
|
25
68
|
removeComponents: function(): void {},
|
|
69
|
+
...(__ENABLE_SSR__ ? { ssrEncode, ssrHydrate } : {}),
|
|
26
70
|
};
|
|
27
71
|
|
|
28
72
|
Object.assign(globalThis, calledByNative);
|
|
73
|
+
Object.assign(globalThis, {
|
|
74
|
+
[LifecycleConstant.jsReady]: jsReady,
|
|
75
|
+
});
|
|
29
76
|
}
|
|
30
77
|
|
|
31
78
|
function renderPage(data: any): void {
|
|
@@ -46,10 +93,6 @@ function renderPage(data: any): void {
|
|
|
46
93
|
|
|
47
94
|
if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {
|
|
48
95
|
jsReady();
|
|
49
|
-
} else {
|
|
50
|
-
Object.assign(globalThis, {
|
|
51
|
-
[LifecycleConstant.jsReady]: jsReady,
|
|
52
|
-
});
|
|
53
96
|
}
|
|
54
97
|
}
|
|
55
98
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Component } from 'preact';
|
|
5
5
|
|
|
6
6
|
import { PerfSpecificKey, PerformanceTimingKeys, markTimingLegacy } from './performance.js';
|
|
7
|
-
import { globalFlushOptions } from '../lifecycle/
|
|
7
|
+
import { globalFlushOptions } from '../lifecycle/patch/commit.js';
|
|
8
8
|
import { NEXT_STATE } from '../renderToOpcodes/constants.js';
|
|
9
9
|
|
|
10
10
|
if (__JS__) {
|
|
@@ -91,7 +91,7 @@ if (__JS__) {
|
|
|
91
91
|
|
|
92
92
|
__Component.prototype.GlobalEventEmitter = lynxCoreInject.tt.GlobalEventEmitter;
|
|
93
93
|
|
|
94
|
-
__Component.prototype.createSelectorQuery = function(
|
|
94
|
+
__Component.prototype.createSelectorQuery = function() {
|
|
95
95
|
if (!__DISABLE_CREATE_SELECTOR_QUERY_INCOMPATIBLE_WARNING__) {
|
|
96
96
|
lynx.reportError(
|
|
97
97
|
new Error(
|
|
@@ -99,7 +99,7 @@ if (__JS__) {
|
|
|
99
99
|
),
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
|
-
return lynx.createSelectorQuery(
|
|
102
|
+
return lynx.createSelectorQuery();
|
|
103
103
|
};
|
|
104
104
|
|
|
105
105
|
const oldSetState = __Component.prototype.setState;
|
|
@@ -12,12 +12,11 @@ export function loadDynamicJS<T>(url: string): Promise<T> {
|
|
|
12
12
|
return Promise.reject();
|
|
13
13
|
}
|
|
14
14
|
return new Promise((resolve, reject) => {
|
|
15
|
-
|
|
16
|
-
lynx.requireModuleAsync(url, (err, data) => {
|
|
15
|
+
lynx.requireModuleAsync<T>(url, (err, data) => {
|
|
17
16
|
if (err) {
|
|
18
17
|
reject(err);
|
|
19
18
|
} else {
|
|
20
|
-
resolve(data);
|
|
19
|
+
resolve(data as T);
|
|
21
20
|
}
|
|
22
21
|
});
|
|
23
22
|
});
|
package/runtime/src/lynx/env.ts
CHANGED
|
@@ -96,7 +96,7 @@ export function loadLazyBundle<
|
|
|
96
96
|
if (typeof lynx.QueryComponent === 'function') {
|
|
97
97
|
lynx.QueryComponent(source, callback);
|
|
98
98
|
} else {
|
|
99
|
-
lynx.getNativeLynx().QueryComponent(source, callback);
|
|
99
|
+
lynx.getNativeLynx().QueryComponent!(source, callback);
|
|
100
100
|
}
|
|
101
101
|
});
|
|
102
102
|
}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
4
|
import { options } from 'preact';
|
|
5
5
|
import type { VNode } from 'preact';
|
|
6
|
+
|
|
6
7
|
import { DIFF } from '../renderToOpcodes/constants.js';
|
|
7
|
-
import { __globalSnapshotPatch } from '../snapshotPatch.js';
|
|
8
|
+
import { __globalSnapshotPatch } from '../lifecycle/patch/snapshotPatch.js';
|
|
8
9
|
|
|
9
10
|
enum PerformanceTimingKeys {
|
|
10
11
|
update_set_state_trigger,
|
|
@@ -61,7 +62,7 @@ function markTimingLegacy(key: PerformanceTimingKeys, timingFlag_?: string): voi
|
|
|
61
62
|
break;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
|
-
lynx.getNativeApp().markTiming?.(timingFlag
|
|
65
|
+
lynx.getNativeApp().markTiming?.(timingFlag!, PerformanceTimingKeys[key]);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
function beginPipeline(needTimestamps: boolean, timingFlag?: string): void {
|