@lynx-js/react 0.105.2 → 0.106.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 +28 -0
- package/package.json +2 -2
- package/refresh/.turbo/turbo-build.log +1 -1
- package/runtime/lib/lifecycle/destroy.js +2 -2
- package/runtime/lib/lifecycle/destroy.js.map +1 -1
- package/runtime/lib/lifecycle/patch/commit.d.ts +7 -3
- package/runtime/lib/lifecycle/patch/commit.js +60 -27
- package/runtime/lib/lifecycle/patch/commit.js.map +1 -1
- package/runtime/lib/lifecycle/patch/updateMainThread.js +14 -13
- package/runtime/lib/lifecycle/patch/updateMainThread.js.map +1 -1
- package/runtime/lib/lifecycle/reload.js +2 -3
- 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 +10 -2
- 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/tt.js +4 -4
- package/runtime/lib/lynx/tt.js.map +1 -1
- package/runtime/lib/lynx-api.js +2 -2
- package/runtime/lib/lynx-api.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/src/lifecycle/destroy.ts +2 -3
- package/runtime/src/lifecycle/patch/commit.ts +79 -31
- package/runtime/src/lifecycle/patch/updateMainThread.ts +18 -16
- package/runtime/src/lifecycle/reload.ts +2 -4
- package/runtime/src/lifecycle/render.ts +11 -2
- package/runtime/src/list.ts +11 -2
- package/runtime/src/lynx/calledByNative.ts +47 -4
- package/runtime/src/lynx/tt.ts +4 -4
- package/runtime/src/lynx-api.ts +2 -2
- package/runtime/src/opcodes.ts +90 -0
- package/runtime/src/root.ts +1 -1
- package/types/react.docs.d.ts +1 -1
|
@@ -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
|
|
package/runtime/src/lynx/tt.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
4
|
+
import { options } from 'preact';
|
|
5
5
|
import type { VNode } from 'preact';
|
|
6
6
|
|
|
7
7
|
import { LifecycleConstant, NativeUpdateDataType } from '../lifecycleConstant.js';
|
|
@@ -10,6 +10,7 @@ import { BackgroundSnapshotInstance, hydrate } from '../backgroundSnapshot.js';
|
|
|
10
10
|
import { destroyBackground } from '../lifecycle/destroy.js';
|
|
11
11
|
import { commitPatchUpdate, genCommitTaskId, globalCommitTaskMap } from '../lifecycle/patch/commit.js';
|
|
12
12
|
import { reloadBackground } from '../lifecycle/reload.js';
|
|
13
|
+
import { renderBackground } from '../lifecycle/render.js';
|
|
13
14
|
import { CHILDREN, COMPONENT, DIFF, DIFFED, FORCE } from '../renderToOpcodes/constants.js';
|
|
14
15
|
import { __root } from '../root.js';
|
|
15
16
|
import { globalRefsToSet, updateBackgroundRefs } from '../snapshot/ref.js';
|
|
@@ -143,14 +144,13 @@ async function OnLifecycleEvent([type, data]: [string, any]) {
|
|
|
143
144
|
if (__PROFILE__) {
|
|
144
145
|
console.profileEnd();
|
|
145
146
|
}
|
|
146
|
-
markTiming(PerformanceTimingKeys.pack_changes_start);
|
|
147
147
|
// console.debug("********** After hydration:");
|
|
148
148
|
// printSnapshotInstance(__root as BackgroundSnapshotInstance);
|
|
149
149
|
if (__PROFILE__) {
|
|
150
150
|
console.profile('commitChanges');
|
|
151
151
|
}
|
|
152
152
|
const commitTaskId = genCommitTaskId();
|
|
153
|
-
await commitPatchUpdate({ snapshotPatch }, {
|
|
153
|
+
await commitPatchUpdate({ patchList: [{ snapshotPatch, id: commitTaskId }] }, { isHydration: true });
|
|
154
154
|
updateBackgroundRefs(commitTaskId);
|
|
155
155
|
globalCommitTaskMap.forEach((commitTask, id) => {
|
|
156
156
|
if (id > commitTaskId) {
|
|
@@ -232,7 +232,7 @@ function updateGlobalProps(newData: Record<string, any>): void {
|
|
|
232
232
|
// This is already done because updateFromRoot will consume all dirty flags marked by
|
|
233
233
|
// the setState, and setState's flush will be a noop. No extra diffs will be needed.
|
|
234
234
|
Promise.resolve().then(() => {
|
|
235
|
-
runWithForce(() =>
|
|
235
|
+
runWithForce(() => renderBackground(__root.__jsx, __root as any));
|
|
236
236
|
});
|
|
237
237
|
lynxCoreInject.tt.GlobalEventEmitter.emit('onGlobalPropsChanged');
|
|
238
238
|
}
|
package/runtime/src/lynx-api.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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
4
|
import { createContext, createElement } from 'preact/compat';
|
|
6
5
|
import { useState } from 'preact/hooks';
|
|
7
6
|
import type { Consumer, FC, ReactNode } from 'react';
|
|
8
7
|
|
|
9
8
|
import { factory, withInitDataInState } from './compat/initData.js';
|
|
10
9
|
import { useLynxGlobalEventListener } from './hooks/useLynxGlobalEventListener.js';
|
|
10
|
+
import { renderBackground } from './lifecycle/render.js';
|
|
11
11
|
import { LifecycleConstant } from './lifecycleConstant.js';
|
|
12
12
|
import { flushDelayedLifecycleEvents } from './lynx/tt.js';
|
|
13
13
|
import { __root } from './root.js';
|
|
@@ -86,7 +86,7 @@ export const root: Root = {
|
|
|
86
86
|
__root.__jsx = jsx;
|
|
87
87
|
} else {
|
|
88
88
|
__root.__jsx = jsx;
|
|
89
|
-
|
|
89
|
+
renderBackground(jsx, __root as any);
|
|
90
90
|
if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') {}
|
|
91
91
|
else {
|
|
92
92
|
lynx.getNativeApp().callLepusMethod(LifecycleConstant.jsReady, {});
|
package/runtime/src/opcodes.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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 { componentAtIndexFactory, enqueueComponentFactory, gRecycleMap, gSignMap } from './list.js';
|
|
4
5
|
import { CHILDREN } from './renderToOpcodes/constants.js';
|
|
5
6
|
import { SnapshotInstance } from './snapshot.js';
|
|
6
7
|
|
|
@@ -11,6 +12,90 @@ const enum Opcode {
|
|
|
11
12
|
Text,
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
interface SSRFiberElement {
|
|
16
|
+
ssrID: string;
|
|
17
|
+
}
|
|
18
|
+
export type SSRSnapshotInstance = [string, number, SSRFiberElement[]];
|
|
19
|
+
|
|
20
|
+
export function ssrHydrateByOpcodes(
|
|
21
|
+
opcodes: any[],
|
|
22
|
+
into: SnapshotInstance,
|
|
23
|
+
refMap?: Record<string, FiberElement>,
|
|
24
|
+
): void {
|
|
25
|
+
let top: SnapshotInstance & { __pendingElements?: SSRFiberElement[] } = into;
|
|
26
|
+
const stack: SnapshotInstance[] = [into];
|
|
27
|
+
for (let i = 0; i < opcodes.length;) {
|
|
28
|
+
const opcode = opcodes[i];
|
|
29
|
+
switch (opcode) {
|
|
30
|
+
case Opcode.Begin: {
|
|
31
|
+
const p = top;
|
|
32
|
+
const [type, __id, elements] = opcodes[i + 1] as SSRSnapshotInstance;
|
|
33
|
+
top = new SnapshotInstance(type, __id);
|
|
34
|
+
top.__pendingElements = elements;
|
|
35
|
+
p.insertBefore(top);
|
|
36
|
+
stack.push(top);
|
|
37
|
+
|
|
38
|
+
i += 2;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case Opcode.End: {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
top[CHILDREN] = undefined;
|
|
44
|
+
|
|
45
|
+
top.__elements = top.__pendingElements!.map(({ ssrID }) => refMap![ssrID]!);
|
|
46
|
+
top.__element_root = top.__elements[0];
|
|
47
|
+
delete top.__pendingElements;
|
|
48
|
+
|
|
49
|
+
if (top.__snapshot_def.isListHolder) {
|
|
50
|
+
const listElement = top.__element_root!;
|
|
51
|
+
const listElementUniqueID = __GetElementUniqueID(listElement);
|
|
52
|
+
const signMap = gSignMap[listElementUniqueID] = new Map();
|
|
53
|
+
gRecycleMap[listElementUniqueID] = new Map();
|
|
54
|
+
const enqueueFunc = enqueueComponentFactory();
|
|
55
|
+
const componentAtIndex = componentAtIndexFactory(top.childNodes);
|
|
56
|
+
for (const child of top.childNodes) {
|
|
57
|
+
if (child.__element_root) {
|
|
58
|
+
const childElementUniqueID = __GetElementUniqueID(child.__element_root);
|
|
59
|
+
signMap.set(childElementUniqueID, child);
|
|
60
|
+
enqueueFunc(
|
|
61
|
+
listElement,
|
|
62
|
+
listElementUniqueID,
|
|
63
|
+
childElementUniqueID,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
__UpdateListCallbacks(listElement, componentAtIndex, enqueueFunc);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
stack.pop();
|
|
71
|
+
const p = stack[stack.length - 1];
|
|
72
|
+
top = p!;
|
|
73
|
+
|
|
74
|
+
i += 1;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case Opcode.Attr: {
|
|
78
|
+
const key = opcodes[i + 1];
|
|
79
|
+
const value = opcodes[i + 2];
|
|
80
|
+
top.setAttribute(key, value);
|
|
81
|
+
|
|
82
|
+
i += 3;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case Opcode.Text: {
|
|
86
|
+
const [[type, __id, elements], text] = opcodes[i + 1] as [SSRSnapshotInstance, string];
|
|
87
|
+
const s = new SnapshotInstance(type, __id);
|
|
88
|
+
s.setAttribute(0, text);
|
|
89
|
+
top.insertBefore(s);
|
|
90
|
+
s.__elements = elements.map(({ ssrID }) => refMap![ssrID]!);
|
|
91
|
+
s.__element_root = s.__elements[0];
|
|
92
|
+
i += 2;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
14
99
|
export function renderOpcodesInto(opcodes: any[], into: SnapshotInstance): void {
|
|
15
100
|
let top: SnapshotInstance = into;
|
|
16
101
|
const stack: SnapshotInstance[] = [into];
|
|
@@ -24,6 +109,7 @@ export function renderOpcodesInto(opcodes: any[], into: SnapshotInstance): void
|
|
|
24
109
|
if (top.__parent) {
|
|
25
110
|
// already inserted
|
|
26
111
|
top = new SnapshotInstance(top.type);
|
|
112
|
+
opcodes[i + 1] = top;
|
|
27
113
|
}
|
|
28
114
|
p.insertBefore(top);
|
|
29
115
|
stack.push(top);
|
|
@@ -53,6 +139,10 @@ export function renderOpcodesInto(opcodes: any[], into: SnapshotInstance): void
|
|
|
53
139
|
case Opcode.Text: {
|
|
54
140
|
const text = opcodes[i + 1];
|
|
55
141
|
const s = new SnapshotInstance(null as unknown as string);
|
|
142
|
+
if (__ENABLE_SSR__) {
|
|
143
|
+
// We need store the just created SnapshotInstance, or it will be lost when we leave the function
|
|
144
|
+
opcodes[i + 1] = [s, text];
|
|
145
|
+
}
|
|
56
146
|
s.setAttribute(0, text);
|
|
57
147
|
top.insertBefore(s);
|
|
58
148
|
|
package/runtime/src/root.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { BackgroundSnapshotInstance } from './backgroundSnapshot.js';
|
|
5
5
|
import { SnapshotInstance } from './snapshot.js';
|
|
6
6
|
|
|
7
|
-
let __root: (SnapshotInstance | BackgroundSnapshotInstance) & { __jsx?: React.ReactNode };
|
|
7
|
+
let __root: (SnapshotInstance | BackgroundSnapshotInstance) & { __jsx?: React.ReactNode; __opcodes?: any[] };
|
|
8
8
|
|
|
9
9
|
function setRoot(root: typeof __root): void {
|
|
10
10
|
__root = root;
|
package/types/react.docs.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export {
|
|
|
48
48
|
useSyncExternalStore,
|
|
49
49
|
} from 'react';
|
|
50
50
|
|
|
51
|
-
export { useEffect, useLayoutEffect } from '../runtime/lib/hooks/react.js';
|
|
51
|
+
export { useEffect, useLayoutEffect, useErrorBoundary } from '../runtime/lib/hooks/react.js';
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Built-in React APIs
|