@lynx-js/react 0.121.0 → 0.121.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 +8 -0
- package/package.json +2 -2
- package/runtime/lib/core/commit-context.d.ts +8 -0
- package/runtime/lib/core/commit-context.js +18 -0
- package/runtime/lib/core/commit-context.js.map +1 -0
- package/runtime/lib/core/forceRootRender.d.ts +7 -0
- package/runtime/lib/core/forceRootRender.js +40 -0
- package/runtime/lib/core/forceRootRender.js.map +1 -0
- package/runtime/lib/core/globalProps.d.ts +31 -0
- package/runtime/lib/core/globalProps.js +55 -0
- package/runtime/lib/core/globalProps.js.map +1 -0
- package/runtime/lib/core/hooks/useLynxGlobalEventListener.js +1 -1
- package/runtime/lib/core/hooks/useLynxGlobalEventListener.js.map +1 -1
- package/runtime/lib/{snapshot/compat → core}/initData.d.ts +1 -1
- package/runtime/lib/{snapshot/compat → core}/initData.js +4 -5
- package/runtime/lib/core/initData.js.map +1 -0
- package/runtime/lib/core/lynx-data-processors.d.ts +2 -0
- package/runtime/lib/core/lynx-data-processors.js +53 -0
- package/runtime/lib/core/lynx-data-processors.js.map +1 -0
- package/runtime/lib/core/lynx-page-data.d.ts +1 -0
- package/runtime/lib/core/lynx-page-data.js +14 -0
- package/runtime/lib/core/lynx-page-data.js.map +1 -0
- package/runtime/lib/core/lynx-update-data.d.ts +11 -0
- package/runtime/lib/core/lynx-update-data.js +21 -0
- package/runtime/lib/core/lynx-update-data.js.map +1 -0
- package/runtime/lib/core/ref.d.ts +37 -0
- package/runtime/lib/core/ref.js +108 -0
- package/runtime/lib/core/ref.js.map +1 -0
- package/runtime/lib/core/reload-version.d.ts +2 -0
- package/runtime/lib/{snapshot/lifecycle/pass.js → core/reload-version.js} +4 -5
- package/runtime/lib/core/reload-version.js.map +1 -0
- package/runtime/lib/element-template/background/attr-slots.d.ts +6 -1
- package/runtime/lib/element-template/background/attr-slots.js +35 -2
- package/runtime/lib/element-template/background/attr-slots.js.map +1 -1
- package/runtime/lib/element-template/background/commit-context.d.ts +3 -3
- package/runtime/lib/element-template/background/commit-context.js +15 -18
- package/runtime/lib/element-template/background/commit-context.js.map +1 -1
- package/runtime/lib/element-template/background/commit-hook.d.ts +1 -1
- package/runtime/lib/element-template/background/commit-hook.js +66 -41
- package/runtime/lib/element-template/background/commit-hook.js.map +1 -1
- package/runtime/lib/element-template/background/destroy.js +9 -6
- package/runtime/lib/element-template/background/destroy.js.map +1 -1
- package/runtime/lib/element-template/background/document.js +1 -7
- package/runtime/lib/element-template/background/document.js.map +1 -1
- package/runtime/lib/element-template/background/hydrate.d.ts +1 -1
- package/runtime/lib/element-template/background/hydrate.js +53 -36
- package/runtime/lib/element-template/background/hydrate.js.map +1 -1
- package/runtime/lib/element-template/background/hydration-listener.js +55 -9
- package/runtime/lib/element-template/background/hydration-listener.js.map +1 -1
- package/runtime/lib/element-template/background/instance.d.ts +12 -10
- package/runtime/lib/element-template/background/instance.js +113 -115
- package/runtime/lib/element-template/background/instance.js.map +1 -1
- package/runtime/lib/element-template/client/root.d.ts +7 -0
- package/runtime/lib/element-template/client/root.js +3 -6
- package/runtime/lib/element-template/client/root.js.map +1 -1
- package/runtime/lib/element-template/debug/alog.d.ts +7 -0
- package/runtime/lib/element-template/debug/alog.js +10 -0
- package/runtime/lib/element-template/debug/alog.js.map +1 -1
- package/runtime/lib/element-template/debug/elementPAPICall.js +4 -0
- package/runtime/lib/element-template/debug/elementPAPICall.js.map +1 -1
- package/runtime/lib/element-template/hydration-map.d.ts +5 -0
- package/runtime/lib/element-template/hydration-map.js +12 -0
- package/runtime/lib/element-template/hydration-map.js.map +1 -0
- package/runtime/lib/element-template/index.d.ts +22 -1
- package/runtime/lib/element-template/index.js +32 -2
- package/runtime/lib/element-template/index.js.map +1 -1
- package/runtime/lib/element-template/internal.d.ts +1 -1
- package/runtime/lib/element-template/internal.js +2 -3
- package/runtime/lib/element-template/internal.js.map +1 -1
- package/runtime/lib/element-template/lynx/env.js +5 -48
- package/runtime/lib/element-template/lynx/env.js.map +1 -1
- package/runtime/lib/element-template/native/index.d.ts +1 -1
- package/runtime/lib/element-template/native/index.js +28 -2
- package/runtime/lib/element-template/native/index.js.map +1 -1
- package/runtime/lib/element-template/native/main-thread-api.js +27 -5
- package/runtime/lib/element-template/native/main-thread-api.js.map +1 -1
- package/runtime/lib/element-template/native/patch-listener.js +5 -1
- package/runtime/lib/element-template/native/patch-listener.js.map +1 -1
- package/runtime/lib/element-template/native/reload.d.ts +2 -0
- package/runtime/lib/element-template/native/reload.js +64 -0
- package/runtime/lib/element-template/native/reload.js.map +1 -0
- package/runtime/lib/element-template/prop-adapters/event.d.ts +1 -0
- package/runtime/lib/element-template/prop-adapters/event.js +4 -1
- package/runtime/lib/element-template/prop-adapters/event.js.map +1 -1
- package/runtime/lib/element-template/prop-adapters/ref.d.ts +26 -0
- package/runtime/lib/element-template/prop-adapters/ref.js +107 -0
- package/runtime/lib/element-template/prop-adapters/ref.js.map +1 -0
- package/runtime/lib/element-template/prop-adapters/spread.js +8 -1
- package/runtime/lib/element-template/prop-adapters/spread.js.map +1 -1
- package/runtime/lib/element-template/protocol/opcodes.d.ts +1 -0
- package/runtime/lib/element-template/protocol/opcodes.js +1 -0
- package/runtime/lib/element-template/protocol/opcodes.js.map +1 -1
- package/runtime/lib/element-template/protocol/types.d.ts +50 -2
- package/runtime/lib/element-template/runtime/page/page.d.ts +5 -2
- package/runtime/lib/element-template/runtime/page/page.js +12 -0
- package/runtime/lib/element-template/runtime/page/page.js.map +1 -1
- package/runtime/lib/element-template/runtime/patch.js +70 -1
- package/runtime/lib/element-template/runtime/patch.js.map +1 -1
- package/runtime/lib/element-template/runtime/render/render-main-thread.d.ts +3 -1
- package/runtime/lib/element-template/runtime/render/render-main-thread.js +25 -7
- package/runtime/lib/element-template/runtime/render/render-main-thread.js.map +1 -1
- package/runtime/lib/element-template/runtime/render/render-to-opcodes.js +9 -3
- package/runtime/lib/element-template/runtime/render/render-to-opcodes.js.map +1 -1
- package/runtime/lib/element-template/runtime/template/attr-slot-plan.d.ts +1 -0
- package/runtime/lib/element-template/runtime/template/attr-slot-plan.js +4 -0
- package/runtime/lib/element-template/runtime/template/attr-slot-plan.js.map +1 -1
- package/runtime/lib/element-template/runtime/template/handle.js +0 -1
- package/runtime/lib/element-template/runtime/template/handle.js.map +1 -1
- package/runtime/lib/element-template/runtime/template/registry.js +1 -1
- package/runtime/lib/element-template/runtime/template/registry.js.map +1 -1
- package/runtime/lib/internal.d.ts +1 -1
- package/runtime/lib/internal.js +1 -1
- package/runtime/lib/internal.js.map +1 -1
- package/runtime/lib/lynx-api.d.ts +3 -8
- package/runtime/lib/lynx-api.js +8 -45
- package/runtime/lib/lynx-api.js.map +1 -1
- package/runtime/lib/snapshot/debug/vnodeSource.js +1 -1
- package/runtime/lib/snapshot/debug/vnodeSource.js.map +1 -1
- package/runtime/lib/snapshot/lifecycle/patch/commit.d.ts +0 -1
- package/runtime/lib/snapshot/lifecycle/patch/commit.js +3 -8
- package/runtime/lib/snapshot/lifecycle/patch/commit.js.map +1 -1
- package/runtime/lib/snapshot/lifecycle/patch/updateMainThread.js +1 -1
- package/runtime/lib/snapshot/lifecycle/patch/updateMainThread.js.map +1 -1
- package/runtime/lib/snapshot/lifecycle/ref/delay.d.ts +6 -13
- package/runtime/lib/snapshot/lifecycle/ref/delay.js +9 -30
- package/runtime/lib/snapshot/lifecycle/ref/delay.js.map +1 -1
- package/runtime/lib/snapshot/lifecycle/reload.js +2 -2
- package/runtime/lib/snapshot/lifecycle/reload.js.map +1 -1
- package/runtime/lib/snapshot/list/list.js +1 -1
- package/runtime/lib/snapshot/list/list.js.map +1 -1
- package/runtime/lib/snapshot/list/listUpdateInfo.js +3 -2
- package/runtime/lib/snapshot/list/listUpdateInfo.js.map +1 -1
- package/runtime/lib/snapshot/lynx/calledByNative.js +2 -8
- package/runtime/lib/snapshot/lynx/calledByNative.js.map +1 -1
- package/runtime/lib/snapshot/lynx/component.js +2 -2
- package/runtime/lib/snapshot/lynx/component.js.map +1 -1
- package/runtime/lib/snapshot/lynx/env.js +5 -51
- package/runtime/lib/snapshot/lynx/env.js.map +1 -1
- package/runtime/lib/snapshot/lynx/runWithForce.js +9 -39
- package/runtime/lib/snapshot/lynx/runWithForce.js.map +1 -1
- package/runtime/lib/snapshot/lynx/tt.js +9 -29
- package/runtime/lib/snapshot/lynx/tt.js.map +1 -1
- package/runtime/lib/snapshot/snapshot/backgroundSnapshot.js +3 -3
- package/runtime/lib/snapshot/snapshot/backgroundSnapshot.js.map +1 -1
- package/runtime/lib/snapshot/snapshot/list.js +1 -1
- package/runtime/lib/snapshot/snapshot/list.js.map +1 -1
- package/runtime/lib/snapshot/snapshot/ref.d.ts +3 -5
- package/runtime/lib/snapshot/snapshot/ref.js +16 -59
- package/runtime/lib/snapshot/snapshot/ref.js.map +1 -1
- package/runtime/lib/snapshot/snapshot/snapshotInstanceHydrationMap.js +1 -1
- package/runtime/lib/snapshot/snapshot/snapshotInstanceHydrationMap.js.map +1 -1
- package/runtime/lib/tsconfig.tsbuildinfo +1 -1
- package/runtime/lib/worklet-runtime/workletRuntime.js +1 -1
- package/runtime/lib/worklet-runtime/workletRuntime.js.map +1 -1
- package/runtime/worklet-runtime/dev.js +2 -2
- package/testing-library/dist/env/index.js +2 -8
- package/testing-library/dist/plugins/index.js +12 -1
- package/transform/dist/wasm.cjs +1 -1
- package/runtime/lib/element-template/hooks/react.d.ts +0 -14
- package/runtime/lib/element-template/hooks/react.js +0 -24
- package/runtime/lib/element-template/hooks/react.js.map +0 -1
- package/runtime/lib/element-template/runtime/components/slot.d.ts +0 -1
- package/runtime/lib/element-template/runtime/components/slot.js +0 -11
- package/runtime/lib/element-template/runtime/components/slot.js.map +0 -1
- package/runtime/lib/snapshot/compat/initData.js.map +0 -1
- package/runtime/lib/snapshot/lifecycle/pass.d.ts +0 -3
- package/runtime/lib/snapshot/lifecycle/pass.js.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Copyright 2026 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 {
|
|
4
|
+
import { getSpreadRefFromValue, queueRefAttrUpdate } from '../prop-adapters/ref.js';
|
|
5
|
+
import { __etAttrPlanMap, adaptRefAttrSlot, adaptSpreadAttrSlot } from '../runtime/template/attr-slot-plan.js';
|
|
5
6
|
function normalizeAttributeSlots(rawSlots) {
|
|
6
7
|
let normalizedSlots;
|
|
7
8
|
for (let slotIndex = 0; slotIndex < rawSlots.length; slotIndex += 1) {
|
|
@@ -14,7 +15,25 @@ function normalizeAttributeSlots(rawSlots) {
|
|
|
14
15
|
}
|
|
15
16
|
return normalizedSlots ?? rawSlots;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
+
function queuePlannedRefAttributeSlotUpdates(handleId, attrPlan, previousRawSlots, nextRawSlots) {
|
|
19
|
+
for (let planIndex = 0; planIndex < attrPlan.length; planIndex += 2) {
|
|
20
|
+
const attrSlotIndex = attrPlan[planIndex];
|
|
21
|
+
const adapter = attrPlan[planIndex + 1];
|
|
22
|
+
if (adapter === adaptRefAttrSlot) {
|
|
23
|
+
queueRefAttrUpdate(previousRawSlots?.[attrSlotIndex], nextRawSlots?.[attrSlotIndex], handleId, attrSlotIndex);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (adapter === adaptSpreadAttrSlot) {
|
|
27
|
+
const previousSpreadRef = getSpreadRefFromValue(previousRawSlots?.[attrSlotIndex]);
|
|
28
|
+
const nextSpreadRef = getSpreadRefFromValue(nextRawSlots?.[attrSlotIndex]);
|
|
29
|
+
if (previousSpreadRef === undefined && nextSpreadRef === undefined) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
queueRefAttrUpdate(previousSpreadRef, nextSpreadRef ?? null, handleId, attrSlotIndex);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function prepareAttributeSlots(templateKey, handleId, rawSlots, options) {
|
|
18
37
|
const attrPlan = __etAttrPlanMap[templateKey];
|
|
19
38
|
if (!attrPlan || attrPlan.length === 0) {
|
|
20
39
|
return normalizeAttributeSlots(rawSlots);
|
|
@@ -23,12 +42,26 @@ export function prepareAttributeSlots(templateKey, handleId, rawSlots) {
|
|
|
23
42
|
const preparedSlots = normalizedSlots === rawSlots
|
|
24
43
|
? rawSlots.slice()
|
|
25
44
|
: normalizedSlots;
|
|
45
|
+
const shouldQueueRefEffects = options?.queueRefEffects === true;
|
|
46
|
+
const previousRawSlots = options?.previousRawSlots;
|
|
26
47
|
for (let planIndex = 0; planIndex < attrPlan.length; planIndex += 2) {
|
|
27
48
|
const attrSlotIndex = attrPlan[planIndex];
|
|
28
49
|
const adapter = attrPlan[planIndex + 1];
|
|
29
50
|
const rawValue = rawSlots[attrSlotIndex];
|
|
30
51
|
preparedSlots[attrSlotIndex] = adapter(handleId, attrSlotIndex, rawValue);
|
|
31
52
|
}
|
|
53
|
+
if (shouldQueueRefEffects) {
|
|
54
|
+
// Ref effects compare raw user refs, not prepared marker strings or the
|
|
55
|
+
// spread wrapper object.
|
|
56
|
+
queuePlannedRefAttributeSlotUpdates(handleId, attrPlan, previousRawSlots, rawSlots);
|
|
57
|
+
}
|
|
32
58
|
return preparedSlots;
|
|
33
59
|
}
|
|
60
|
+
export function queueRefAttributeSlotUpdates(templateKey, handleId, previousRawSlots, nextRawSlots) {
|
|
61
|
+
const attrPlan = __etAttrPlanMap[templateKey];
|
|
62
|
+
if (!attrPlan || attrPlan.length === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
queuePlannedRefAttributeSlotUpdates(handleId, attrPlan, previousRawSlots, nextRawSlots);
|
|
66
|
+
}
|
|
34
67
|
//# sourceMappingURL=attr-slots.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attr-slots.js","sourceRoot":"","sources":["../../../src/element-template/background/attr-slots.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;
|
|
1
|
+
{"version":3,"file":"attr-slots.js","sourceRoot":"","sources":["../../../src/element-template/background/attr-slots.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { BackgroundElementTemplateInstance } from './instance.js';
|
|
2
2
|
import type { ElementTemplateUpdateCommitContext } from '../protocol/types.js';
|
|
3
3
|
interface ElementTemplateCommitNonPayloadState {
|
|
4
|
-
|
|
4
|
+
removedSubtreesAwaitingTeardown: BackgroundElementTemplateInstance[];
|
|
5
5
|
}
|
|
6
6
|
type ElementTemplateGlobalCommitContext = ElementTemplateUpdateCommitContext & {
|
|
7
7
|
nonPayload: ElementTemplateCommitNonPayloadState;
|
|
8
8
|
};
|
|
9
9
|
export declare const globalCommitContext: ElementTemplateGlobalCommitContext;
|
|
10
10
|
export declare function resetGlobalCommitContext(): void;
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function
|
|
11
|
+
export declare function markRemovedSubtreeForPostDispatchTeardown(root: BackgroundElementTemplateInstance): void;
|
|
12
|
+
export declare function takeRemovedSubtreesForPostDispatchTeardown(): BackgroundElementTemplateInstance[];
|
|
13
13
|
export {};
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
nonPayload: {
|
|
5
|
-
removedSubtrees: [],
|
|
6
|
-
},
|
|
1
|
+
import { globalCommitContext as coreGlobalCommitContext, resetGlobalCommitContext as resetCoreGlobalCommitContext, } from '../../core/commit-context.js';
|
|
2
|
+
const nonPayload = {
|
|
3
|
+
removedSubtreesAwaitingTeardown: [],
|
|
7
4
|
};
|
|
5
|
+
export const globalCommitContext = coreGlobalCommitContext;
|
|
6
|
+
globalCommitContext.nonPayload = nonPayload;
|
|
8
7
|
export function resetGlobalCommitContext() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
delete globalCommitContext.flowIds;
|
|
12
|
-
globalCommitContext.nonPayload.removedSubtrees = [];
|
|
8
|
+
resetCoreGlobalCommitContext();
|
|
9
|
+
nonPayload.removedSubtreesAwaitingTeardown = [];
|
|
13
10
|
}
|
|
14
|
-
export function
|
|
15
|
-
const {
|
|
16
|
-
if (!
|
|
17
|
-
|
|
11
|
+
export function markRemovedSubtreeForPostDispatchTeardown(root) {
|
|
12
|
+
const { removedSubtreesAwaitingTeardown } = globalCommitContext.nonPayload;
|
|
13
|
+
if (!removedSubtreesAwaitingTeardown.includes(root)) {
|
|
14
|
+
removedSubtreesAwaitingTeardown.push(root);
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
export function
|
|
21
|
-
const
|
|
22
|
-
globalCommitContext.nonPayload.
|
|
23
|
-
return
|
|
17
|
+
export function takeRemovedSubtreesForPostDispatchTeardown() {
|
|
18
|
+
const removedSubtreesAwaitingTeardown = globalCommitContext.nonPayload.removedSubtreesAwaitingTeardown;
|
|
19
|
+
globalCommitContext.nonPayload.removedSubtreesAwaitingTeardown = [];
|
|
20
|
+
return removedSubtreesAwaitingTeardown;
|
|
24
21
|
}
|
|
25
22
|
//# sourceMappingURL=commit-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-context.js","sourceRoot":"","sources":["../../../src/element-template/background/commit-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commit-context.js","sourceRoot":"","sources":["../../../src/element-template/background/commit-context.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,mBAAmB,IAAI,uBAAuB,EAC9C,wBAAwB,IAAI,4BAA4B,GACzD,MAAM,8BAA8B,CAAC;AActC,MAAM,UAAU,GAAyC;IACvD,+BAA+B,EAAE,EAAE;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAwE,CAAC;AAE5G,mBAAmB,CAAC,UAAU,GAAG,UAAU,CAAC;AAE5C,MAAM,UAAU,wBAAwB;IACtC,4BAA4B,EAAE,CAAC;IAC/B,UAAU,CAAC,+BAA+B,GAAG,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,yCAAyC,CACvD,IAAuC;IAEvC,MAAM,EAAE,+BAA+B,EAAE,GAAG,mBAAmB,CAAC,UAAU,CAAC;IAC3E,IAAI,CAAC,+BAA+B,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0CAA0C;IACxD,MAAM,+BAA+B,GAAG,mBAAmB,CAAC,UAAU,CAAC,+BAA+B,CAAC;IACvG,mBAAmB,CAAC,UAAU,CAAC,+BAA+B,GAAG,EAAE,CAAC;IACpE,OAAO,+BAA+B,CAAC;AACzC,CAAC"}
|
|
@@ -2,6 +2,6 @@ import type { BackgroundElementTemplateInstance } from './instance.js';
|
|
|
2
2
|
export declare function markElementTemplateHydrated(): void;
|
|
3
3
|
export declare function isElementTemplateHydrated(): boolean;
|
|
4
4
|
export declare function resetElementTemplateCommitState(): void;
|
|
5
|
-
export declare function scheduleElementTemplateRemovedSubtreeCleanup(
|
|
5
|
+
export declare function scheduleElementTemplateRemovedSubtreeCleanup(removedSubtreesAwaitingTeardown: BackgroundElementTemplateInstance[]): void;
|
|
6
6
|
export declare function cancelElementTemplateRemovedSubtreeCleanup(): void;
|
|
7
7
|
export declare function installElementTemplateCommitHook(): void;
|
|
@@ -2,16 +2,18 @@
|
|
|
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 { options } from 'preact';
|
|
5
|
-
import { globalCommitContext, resetGlobalCommitContext,
|
|
5
|
+
import { globalCommitContext, resetGlobalCommitContext, takeRemovedSubtreesForPostDispatchTeardown, } from './commit-context.js';
|
|
6
|
+
import { getReloadVersion } from '../../core/reload-version.js';
|
|
6
7
|
import { COMMIT } from '../../shared/render-constants.js';
|
|
7
|
-
import { hook } from '../../utils.js';
|
|
8
|
+
import { hook, isEmptyObject } from '../../utils.js';
|
|
8
9
|
import { formatElementTemplateUpdateCommands } from '../debug/alog.js';
|
|
9
10
|
import { profileEnd, profileStart } from '../debug/profile.js';
|
|
10
11
|
import { globalPipelineOptions, markTiming, markTimingLegacy, setPipeline } from '../lynx/performance.js';
|
|
12
|
+
import { clearPendingRefs, flushPendingRefs, hasPendingRefs } from '../prop-adapters/ref.js';
|
|
11
13
|
import { ElementTemplateLifecycleConstant } from '../protocol/lifecycle-constant.js';
|
|
12
14
|
let installed = false;
|
|
13
15
|
let hasHydrated = false;
|
|
14
|
-
const scheduledRemovedSubtreeCleanupTimers = new Set();
|
|
16
|
+
const scheduledRemovedSubtreeCleanupTimers = /*#__PURE__*/ new Set();
|
|
15
17
|
export function markElementTemplateHydrated() {
|
|
16
18
|
hasHydrated = true;
|
|
17
19
|
}
|
|
@@ -22,13 +24,13 @@ export function resetElementTemplateCommitState() {
|
|
|
22
24
|
hasHydrated = false;
|
|
23
25
|
resetGlobalCommitContext();
|
|
24
26
|
}
|
|
25
|
-
export function scheduleElementTemplateRemovedSubtreeCleanup(
|
|
26
|
-
if (
|
|
27
|
+
export function scheduleElementTemplateRemovedSubtreeCleanup(removedSubtreesAwaitingTeardown) {
|
|
28
|
+
if (removedSubtreesAwaitingTeardown.length === 0) {
|
|
27
29
|
return;
|
|
28
30
|
}
|
|
29
31
|
const timer = setTimeout(() => {
|
|
30
32
|
scheduledRemovedSubtreeCleanupTimers.delete(timer);
|
|
31
|
-
for (const root of
|
|
33
|
+
for (const root of removedSubtreesAwaitingTeardown) {
|
|
32
34
|
root.tearDown();
|
|
33
35
|
}
|
|
34
36
|
}, 10000);
|
|
@@ -46,48 +48,71 @@ export function installElementTemplateCommitHook() {
|
|
|
46
48
|
}
|
|
47
49
|
installed = true;
|
|
48
50
|
hook(options, COMMIT, (originalCommit, vnode, commitQueue) => {
|
|
49
|
-
if (__BACKGROUND__ && hasHydrated &&
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
if (__PROFILE__) {
|
|
64
|
-
profileEnd();
|
|
65
|
-
}
|
|
66
|
-
if (typeof __ALOG__ !== 'undefined' && __ALOG__) {
|
|
67
|
-
console.alog?.('[ReactLynxDebug] ElementTemplate BTS -> MTS update:\n'
|
|
68
|
-
+ JSON.stringify({
|
|
69
|
-
ops: formatElementTemplateUpdateCommands(globalCommitContext.ops),
|
|
70
|
-
flushOptions: globalCommitContext.flushOptions,
|
|
71
|
-
flowIds: globalCommitContext.flowIds,
|
|
72
|
-
}, null, 2));
|
|
73
|
-
}
|
|
74
|
-
const removedSubtrees = takeRemovedSubtreesForCurrentCommit();
|
|
51
|
+
if (__BACKGROUND__ && !hasHydrated && hasPendingRefs()) {
|
|
52
|
+
// User effects can run before ET hydrate arrives, so ordinary refs must be
|
|
53
|
+
// attached on the background commit even though native UI ops are delayed.
|
|
54
|
+
flushPendingRefs();
|
|
55
|
+
}
|
|
56
|
+
else if (__BACKGROUND__ && hasHydrated
|
|
57
|
+
&& (globalCommitContext.ops.length > 0
|
|
58
|
+
|| !isEmptyObject(globalCommitContext.flushOptions)
|
|
59
|
+
|| hasPendingRefs())) {
|
|
60
|
+
const hasNativeOps = globalCommitContext.ops.length > 0;
|
|
61
|
+
const hasUpdatePayload = hasNativeOps || !isEmptyObject(globalCommitContext.flushOptions);
|
|
62
|
+
const removedSubtreesAwaitingTeardown = hasNativeOps ? takeRemovedSubtreesForPostDispatchTeardown() : [];
|
|
63
|
+
let didFlushRefs = false;
|
|
75
64
|
try {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
65
|
+
if (hasUpdatePayload) {
|
|
66
|
+
markTimingLegacy('updateDiffVdomEnd');
|
|
67
|
+
markTiming('diffVdomEnd');
|
|
68
|
+
if (__PROFILE__) {
|
|
69
|
+
profileStart('ReactLynx::commitChanges');
|
|
70
|
+
}
|
|
71
|
+
markTiming('packChangesStart');
|
|
72
|
+
if (globalPipelineOptions) {
|
|
73
|
+
globalCommitContext.flushOptions.pipelineOptions = globalPipelineOptions;
|
|
74
|
+
}
|
|
75
|
+
markTiming('packChangesEnd');
|
|
76
|
+
if (globalPipelineOptions) {
|
|
77
|
+
setPipeline(undefined);
|
|
78
|
+
}
|
|
79
|
+
if (__PROFILE__) {
|
|
80
|
+
profileEnd();
|
|
81
|
+
}
|
|
82
|
+
if (typeof __ALOG__ !== 'undefined' && __ALOG__) {
|
|
83
|
+
console.alog?.('[ReactLynxDebug] ElementTemplate BTS -> MTS update:\n'
|
|
84
|
+
+ JSON.stringify({
|
|
85
|
+
ops: formatElementTemplateUpdateCommands(globalCommitContext.ops),
|
|
86
|
+
flushOptions: globalCommitContext.flushOptions,
|
|
87
|
+
flowIds: globalCommitContext.flowIds,
|
|
88
|
+
}, null, 2));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (hasUpdatePayload) {
|
|
92
|
+
lynx.getCoreContext().dispatchEvent({
|
|
93
|
+
type: ElementTemplateLifecycleConstant.update,
|
|
94
|
+
data: {
|
|
95
|
+
ops: globalCommitContext.ops,
|
|
96
|
+
flushOptions: globalCommitContext.flushOptions,
|
|
97
|
+
flowIds: globalCommitContext.flowIds,
|
|
98
|
+
reloadVersion: getReloadVersion(),
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// When native ops exist, patch first so a newly attached ref observes the
|
|
103
|
+
// committed native state. Ref-only commits still flush through this path.
|
|
104
|
+
flushPendingRefs();
|
|
105
|
+
didFlushRefs = true;
|
|
84
106
|
}
|
|
85
107
|
finally {
|
|
108
|
+
if (!didFlushRefs) {
|
|
109
|
+
clearPendingRefs();
|
|
110
|
+
}
|
|
86
111
|
resetGlobalCommitContext();
|
|
87
112
|
// Match Snapshot's cleanup boundary: start the delayed teardown only
|
|
88
113
|
// after the bridge dispatch attempt, so background JS objects are not
|
|
89
114
|
// torn down before main-thread detach observes the same commit.
|
|
90
|
-
scheduleElementTemplateRemovedSubtreeCleanup(
|
|
115
|
+
scheduleElementTemplateRemovedSubtreeCleanup(removedSubtreesAwaitingTeardown);
|
|
91
116
|
}
|
|
92
117
|
}
|
|
93
118
|
originalCommit?.(vnode, commitQueue);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit-hook.js","sourceRoot":"","sources":["../../../src/element-template/background/commit-hook.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,
|
|
1
|
+
{"version":3,"file":"commit-hook.js","sourceRoot":"","sources":["../../../src/element-template/background/commit-hook.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,0CAA0C,GAC3C,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,mCAAmC,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AAErF,IAAI,SAAS,GAAG,KAAK,CAAC;AACtB,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB,MAAM,oCAAoC,GAAG,aAAa,CAAC,IAAI,GAAG,EAAiC,CAAC;AAEpG,MAAM,UAAU,2BAA2B;IACzC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,+BAA+B;IAC7C,WAAW,GAAG,KAAK,CAAC;IACpB,wBAAwB,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,4CAA4C,CAC1D,+BAAoE;IAEpE,IAAI,+BAA+B,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,oCAAoC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnD,KAAK,MAAM,IAAI,IAAI,+BAA+B,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,EAAE,KAAK,CAAC,CAAC;IACV,oCAAoC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,0CAA0C;IACxD,KAAK,MAAM,KAAK,IAAI,oCAAoC,EAAE,CAAC;QACzD,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,oCAAoC,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,gCAAgC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IACD,SAAS,GAAG,IAAI,CAAC;IAEjB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;QAC3D,IAAI,cAAc,IAAI,CAAC,WAAW,IAAI,cAAc,EAAE,EAAE,CAAC;YACvD,2EAA2E;YAC3E,2EAA2E;YAC3E,gBAAgB,EAAE,CAAC;QACrB,CAAC;aAAM,IACL,cAAc,IAAI,WAAW;eAC1B,CACD,mBAAmB,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;mBAC/B,CAAC,aAAa,CAAC,mBAAmB,CAAC,YAAY,CAAC;mBAChD,cAAc,EAAE,CACpB,EACD,CAAC;YACD,MAAM,YAAY,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACxD,MAAM,gBAAgB,GAAG,YAAY,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;YAC1F,MAAM,+BAA+B,GAAG,YAAY,CAAC,CAAC,CAAC,0CAA0C,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzG,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,gBAAgB,EAAE,CAAC;oBACrB,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;oBACtC,UAAU,CAAC,aAAa,CAAC,CAAC;oBAE1B,IAAI,WAAW,EAAE,CAAC;wBAChB,YAAY,CAAC,0BAA0B,CAAC,CAAC;oBAC3C,CAAC;oBACD,UAAU,CAAC,kBAAkB,CAAC,CAAC;oBAC/B,IAAI,qBAAqB,EAAE,CAAC;wBAC1B,mBAAmB,CAAC,YAAY,CAAC,eAAe,GAAG,qBAAqB,CAAC;oBAC3E,CAAC;oBACD,UAAU,CAAC,gBAAgB,CAAC,CAAC;oBAC7B,IAAI,qBAAqB,EAAE,CAAC;wBAC1B,WAAW,CAAC,SAAS,CAAC,CAAC;oBACzB,CAAC;oBACD,IAAI,WAAW,EAAE,CAAC;wBAChB,UAAU,EAAE,CAAC;oBACf,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,EAAE,CAAC;wBAChD,OAAO,CAAC,IAAI,EAAE,CACZ,uDAAuD;8BACnD,IAAI,CAAC,SAAS,CACd;gCACE,GAAG,EAAE,mCAAmC,CAAC,mBAAmB,CAAC,GAAG,CAAC;gCACjE,YAAY,EAAE,mBAAmB,CAAC,YAAY;gCAC9C,OAAO,EAAE,mBAAmB,CAAC,OAAO;6BACrC,EACD,IAAI,EACJ,CAAC,CACF,CACJ,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,IAAI,gBAAgB,EAAE,CAAC;oBACrB,IAAI,CAAC,cAAc,EAAE,CAAC,aAAa,CAAC;wBAClC,IAAI,EAAE,gCAAgC,CAAC,MAAM;wBAC7C,IAAI,EAAE;4BACJ,GAAG,EAAE,mBAAmB,CAAC,GAAG;4BAC5B,YAAY,EAAE,mBAAmB,CAAC,YAAY;4BAC9C,OAAO,EAAE,mBAAmB,CAAC,OAAO;4BACpC,aAAa,EAAE,gBAAgB,EAAE;yBAClC;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,0EAA0E;gBAC1E,0EAA0E;gBAC1E,gBAAgB,EAAE,CAAC;gBACnB,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,gBAAgB,EAAE,CAAC;gBACrB,CAAC;gBACD,wBAAwB,EAAE,CAAC;gBAC3B,qEAAqE;gBACrE,sEAAsE;gBACtE,gEAAgE;gBAChE,4CAA4C,CAAC,+BAA+B,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;QAED,cAAc,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
|
|
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
|
+
import { render } from 'preact';
|
|
4
2
|
import { cancelElementTemplateRemovedSubtreeCleanup, resetElementTemplateCommitState } from './commit-hook.js';
|
|
5
3
|
import { resetElementTemplateHydrationListener } from './hydration-listener.js';
|
|
6
4
|
import { backgroundElementTemplateInstanceManager } from './manager.js';
|
|
7
5
|
import { clearEventState } from '../prop-adapters/event.js';
|
|
6
|
+
import { clearRefState, flushPendingRefs } from '../prop-adapters/ref.js';
|
|
7
|
+
import { __root } from '../runtime/page/root-instance.js';
|
|
8
8
|
export function destroyElementTemplateBackgroundRuntime() {
|
|
9
9
|
resetElementTemplateHydrationListener();
|
|
10
|
-
resetElementTemplateCommitState();
|
|
11
|
-
// Destroy is the only place that may discard delayed removed subtrees instead
|
|
12
|
-
// of letting the Snapshot-aligned timer tear them down later.
|
|
13
10
|
cancelElementTemplateRemovedSubtreeCleanup();
|
|
11
|
+
render(null, __root);
|
|
12
|
+
// Run user cleanup before dropping the backend side tables; after clearRefState
|
|
13
|
+
// the raw ref ownership needed to detach callbacks is gone.
|
|
14
|
+
flushPendingRefs();
|
|
15
|
+
resetElementTemplateCommitState();
|
|
14
16
|
clearEventState();
|
|
17
|
+
clearRefState();
|
|
15
18
|
backgroundElementTemplateInstanceManager.clear();
|
|
16
19
|
}
|
|
17
20
|
//# sourceMappingURL=destroy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/element-template/background/destroy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"destroy.js","sourceRoot":"","sources":["../../../src/element-template/background/destroy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,0CAA0C,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAC;AAC/G,OAAO,EAAE,qCAAqC,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,wCAAwC,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAE1D,MAAM,UAAU,uCAAuC;IACrD,qCAAqC,EAAE,CAAC;IACxC,0CAA0C,EAAE,CAAC;IAE7C,MAAM,CAAC,IAAI,EAAE,MAAkC,CAAC,CAAC;IACjD,gFAAgF;IAChF,4DAA4D;IAC5D,gBAAgB,EAAE,CAAC;IAEnB,+BAA+B,EAAE,CAAC;IAClC,eAAe,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC;IAChB,wCAAwC,CAAC,KAAK,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -2,19 +2,13 @@
|
|
|
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 { options } from 'preact';
|
|
5
|
-
import { BUILTIN_RAW_TEXT_TEMPLATE_KEY, BackgroundElementTemplateInstance
|
|
5
|
+
import { BUILTIN_RAW_TEXT_TEMPLATE_KEY, BackgroundElementTemplateInstance } from './instance.js';
|
|
6
6
|
export function setupBackgroundElementTemplateDocument() {
|
|
7
7
|
const doc = {
|
|
8
8
|
createElement(type) {
|
|
9
|
-
if (type === 'slot') {
|
|
10
|
-
return new BackgroundElementTemplateSlot();
|
|
11
|
-
}
|
|
12
9
|
return new BackgroundElementTemplateInstance(type);
|
|
13
10
|
},
|
|
14
11
|
createElementNS(_ns, type) {
|
|
15
|
-
if (type === 'slot') {
|
|
16
|
-
return new BackgroundElementTemplateSlot();
|
|
17
|
-
}
|
|
18
12
|
return new BackgroundElementTemplateInstance(type);
|
|
19
13
|
},
|
|
20
14
|
createTextNode(text) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../../src/element-template/background/document.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,OAAO,
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../../src/element-template/background/document.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,yEAAyE;AACzE,0DAA0D;AAE1D,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,OAAO,EAAE,6BAA6B,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAQjG,MAAM,UAAU,sCAAsC;IACpD,MAAM,GAAG,GAAG;QACV,aAAa,CAAC,IAAY;YACxB,OAAO,IAAI,iCAAiC,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,eAAe,CAAC,GAAW,EAAE,IAAY;YACvC,OAAO,IAAI,iCAAiC,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,cAAc,CAAC,IAAY;YACzB,OAAO,IAAI,iCAAiC,CAAC,6BAA6B,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACtF,CAAC;KACF,CAAC;IAEF,OAAO,CAAC,QAAQ,GAAG,GAA0B,CAAC;IAE9C,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { BackgroundElementTemplateInstance } from './instance.js';
|
|
2
2
|
import type { ElementTemplateUpdateCommandStream, SerializedElementTemplate } from '../protocol/types.js';
|
|
3
3
|
export declare function hydrate(serialized: SerializedElementTemplate, instance: BackgroundElementTemplateInstance): ElementTemplateUpdateCommandStream;
|
|
4
|
-
export declare function hydrateIntoContext(serialized: SerializedElementTemplate, instance: BackgroundElementTemplateInstance):
|
|
4
|
+
export declare function hydrateIntoContext(serialized: SerializedElementTemplate, instance: BackgroundElementTemplateInstance): boolean;
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
// Copyright 2025 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 { globalCommitContext,
|
|
4
|
+
import { globalCommitContext, markRemovedSubtreeForPostDispatchTeardown, resetGlobalCommitContext, } from './commit-context.js';
|
|
5
5
|
import { BUILTIN_RAW_TEXT_TEMPLATE_KEY } from './instance.js';
|
|
6
6
|
import { backgroundElementTemplateInstanceManager } from './manager.js';
|
|
7
7
|
import { isDirectOrDeepEqual } from '../../utils.js';
|
|
8
|
+
import { hydrationMap } from '../hydration-map.js';
|
|
8
9
|
import { ElementTemplateUpdateOps } from '../protocol/opcodes.js';
|
|
9
10
|
export function hydrate(serialized, instance) {
|
|
10
11
|
resetGlobalCommitContext();
|
|
11
|
-
hydrateIntoContext(serialized, instance)
|
|
12
|
+
if (!hydrateIntoContext(serialized, instance)) {
|
|
13
|
+
// Hydration protocol errors are not transactional: earlier matched nodes
|
|
14
|
+
// may already be rebound while discovering a later mismatch. Discard the
|
|
15
|
+
// native output for this failed pass and let the listener keep refs/events gated.
|
|
16
|
+
resetGlobalCommitContext();
|
|
17
|
+
}
|
|
12
18
|
return globalCommitContext.ops;
|
|
13
19
|
}
|
|
14
20
|
export function hydrateIntoContext(serialized, instance) {
|
|
15
|
-
hydrateInstance(serialized, instance);
|
|
21
|
+
return hydrateInstance(serialized, instance);
|
|
16
22
|
}
|
|
17
23
|
function hydrateMatchingChildrenAndDiffSlot(serializedChildren, backgroundChildren) {
|
|
18
24
|
let lastPlacedIndex = 0;
|
|
@@ -37,7 +43,9 @@ function hydrateMatchingChildrenAndDiffSlot(serializedChildren, backgroundChildr
|
|
|
37
43
|
if (matchedSerialized) {
|
|
38
44
|
serializedCursorByTemplateKey[backgroundChild.type] = candidateCursor + 1;
|
|
39
45
|
const oldIndex = matchedSerialized[1];
|
|
40
|
-
hydrateInstance(matchedSerialized[0], backgroundChild)
|
|
46
|
+
if (!hydrateInstance(matchedSerialized[0], backgroundChild)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
41
49
|
if (oldIndex < lastPlacedIndex) {
|
|
42
50
|
result.moves[oldIndex] = { toIndex: i, instance: backgroundChild };
|
|
43
51
|
result.hasChanges = true;
|
|
@@ -67,48 +75,54 @@ function hydrateInstance(serialized, instance) {
|
|
|
67
75
|
if (__DEV__) {
|
|
68
76
|
lynx.reportError(new Error(`ElementTemplate hydrate key mismatch: main='${serialized.templateKey}' background='${instance.type}'.`));
|
|
69
77
|
}
|
|
70
|
-
return;
|
|
78
|
+
return false;
|
|
71
79
|
}
|
|
72
80
|
const handleId = serialized.uid;
|
|
73
81
|
if (!bindHydrationHandleId(instance, handleId, serialized.templateKey)) {
|
|
74
|
-
return;
|
|
82
|
+
return false;
|
|
75
83
|
}
|
|
76
|
-
instance.
|
|
84
|
+
instance.prepareAttributeSlotsForHydration();
|
|
77
85
|
hydrateAttributeSlots(handleId, serialized.attributeSlots ?? [], instance.attributeSlots);
|
|
78
86
|
if (serialized.templateKey === BUILTIN_RAW_TEXT_TEMPLATE_KEY) {
|
|
79
|
-
return;
|
|
87
|
+
return true;
|
|
80
88
|
}
|
|
81
89
|
const serializedElementSlots = serialized.elementSlots ?? [];
|
|
90
|
+
const backgroundElementSlots = instance.elementSlots;
|
|
82
91
|
// Snapshot hydrates dynamic children through slot-filtered lists. Keeping ET
|
|
83
92
|
// scoped the same way means a cross-slot candidate is a source remove plus a
|
|
84
93
|
// target create/insert, while same-slot reorder can still stay move-like.
|
|
85
|
-
const slotCount = Math.max(serializedElementSlots.length,
|
|
94
|
+
const slotCount = Math.max(serializedElementSlots.length, backgroundElementSlots.length);
|
|
86
95
|
for (let slotId = 0; slotId < slotCount; slotId += 1) {
|
|
87
96
|
const serializedSlot = serializedElementSlots[slotId];
|
|
88
|
-
const backgroundSlot =
|
|
97
|
+
const backgroundSlot = backgroundElementSlots[slotId];
|
|
89
98
|
if (!serializedSlot && !backgroundSlot) {
|
|
90
99
|
continue;
|
|
91
100
|
}
|
|
92
|
-
hydrateElementSlot(instance, slotId, serializedSlot ?? [])
|
|
101
|
+
if (!hydrateElementSlot(instance, slotId, serializedSlot ?? [], backgroundSlot ?? [])) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
93
104
|
}
|
|
105
|
+
return true;
|
|
94
106
|
}
|
|
95
|
-
function hydrateElementSlot(parent, slotId, serializedChildren) {
|
|
96
|
-
const backgroundChildren = parent.elementSlots[slotId] ?? [];
|
|
107
|
+
function hydrateElementSlot(parent, slotId, serializedChildren, backgroundChildren) {
|
|
97
108
|
if (backgroundChildren.length === 0) {
|
|
98
109
|
for (const serialized of serializedChildren) {
|
|
99
110
|
emitSerializedSubtreeRemove(parent, slotId, serialized);
|
|
100
111
|
}
|
|
101
|
-
return;
|
|
112
|
+
return true;
|
|
102
113
|
}
|
|
103
114
|
const listDiff = hydrateMatchingChildrenAndDiffSlot(serializedChildren, backgroundChildren);
|
|
115
|
+
if (listDiff === null) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
104
118
|
if (!listDiff.hasChanges) {
|
|
105
|
-
return;
|
|
119
|
+
return true;
|
|
106
120
|
}
|
|
107
121
|
// Hydrate emits patches directly here. Replaying against serialized order
|
|
108
122
|
// keeps insert targets in the main-thread slot without reshaping background.
|
|
109
123
|
const removalIndexes = new Set(listDiff.removals);
|
|
110
124
|
const { insertions, moves } = listDiff;
|
|
111
|
-
const
|
|
125
|
+
const movesWaitingForInsertionPoint = new Map();
|
|
112
126
|
let serializedCursor = 0;
|
|
113
127
|
let currentSerializedChild = serializedChildren[serializedCursor];
|
|
114
128
|
let newIndex = 0;
|
|
@@ -116,31 +130,31 @@ function hydrateElementSlot(parent, slotId, serializedChildren) {
|
|
|
116
130
|
// Insertions are known before replay starts. Moves are counted only when their
|
|
117
131
|
// old serialized position is reached, so the cursor can keep emitting patches
|
|
118
132
|
// even after all serialized children have been consumed.
|
|
119
|
-
let
|
|
120
|
-
while (currentSerializedChild ||
|
|
133
|
+
let insertOrMovePatchesWaitingForInsertionPoint = listDiff.insertionCount;
|
|
134
|
+
while (currentSerializedChild || insertOrMovePatchesWaitingForInsertionPoint > 0) {
|
|
121
135
|
let keepCurrentSerializedChild = false;
|
|
122
136
|
if (currentSerializedChild && removalIndexes.has(oldIndex)) {
|
|
123
137
|
emitSerializedSubtreeRemove(parent, slotId, currentSerializedChild);
|
|
124
138
|
}
|
|
125
139
|
else if (currentSerializedChild && moves[oldIndex] !== undefined) {
|
|
126
140
|
const move = moves[oldIndex];
|
|
127
|
-
|
|
128
|
-
|
|
141
|
+
movesWaitingForInsertionPoint.set(move.toIndex, move.instance);
|
|
142
|
+
insertOrMovePatchesWaitingForInsertionPoint += 1;
|
|
129
143
|
}
|
|
130
144
|
else {
|
|
131
145
|
const beforeChildId = currentSerializedChild ? currentSerializedChild.uid : 0;
|
|
132
|
-
const movedChild =
|
|
146
|
+
const movedChild = movesWaitingForInsertionPoint.get(newIndex);
|
|
133
147
|
if (movedChild) {
|
|
134
148
|
keepCurrentSerializedChild = true;
|
|
135
149
|
globalCommitContext.ops.push(ElementTemplateUpdateOps.insertNode, parent.instanceId, slotId, movedChild.instanceId, beforeChildId);
|
|
136
|
-
|
|
150
|
+
insertOrMovePatchesWaitingForInsertionPoint -= 1;
|
|
137
151
|
}
|
|
138
152
|
else if (insertions[newIndex] !== undefined) {
|
|
139
153
|
const insertedChild = insertions[newIndex];
|
|
140
154
|
keepCurrentSerializedChild = true;
|
|
141
155
|
emitCreateSubtree(insertedChild);
|
|
142
156
|
globalCommitContext.ops.push(ElementTemplateUpdateOps.insertNode, parent.instanceId, slotId, insertedChild.instanceId, beforeChildId);
|
|
143
|
-
|
|
157
|
+
insertOrMovePatchesWaitingForInsertionPoint -= 1;
|
|
144
158
|
}
|
|
145
159
|
newIndex += 1;
|
|
146
160
|
}
|
|
@@ -149,6 +163,7 @@ function hydrateElementSlot(parent, slotId, serializedChildren) {
|
|
|
149
163
|
oldIndex += 1;
|
|
150
164
|
}
|
|
151
165
|
}
|
|
166
|
+
return true;
|
|
152
167
|
}
|
|
153
168
|
function emitSerializedSubtreeRemove(parent, slotId, serialized) {
|
|
154
169
|
const childId = serialized.uid;
|
|
@@ -159,7 +174,7 @@ function emitSerializedSubtreeRemove(parent, slotId, serialized) {
|
|
|
159
174
|
collectSerializedSubtreeHandleIdsInto(serialized, removedSubtreeHandleIds);
|
|
160
175
|
globalCommitContext.ops.push(ElementTemplateUpdateOps.removeNode, parent.instanceId, slotId, childId, removedSubtreeHandleIds);
|
|
161
176
|
if (existing && !existing.parent) {
|
|
162
|
-
|
|
177
|
+
markRemovedSubtreeForPostDispatchTeardown(existing);
|
|
163
178
|
}
|
|
164
179
|
}
|
|
165
180
|
function collectSerializedSubtreeHandleIdsInto(serialized, handles) {
|
|
@@ -174,23 +189,25 @@ function collectSerializedSubtreeHandleIdsInto(serialized, handles) {
|
|
|
174
189
|
}
|
|
175
190
|
}
|
|
176
191
|
function emitCreateSubtree(node) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
node.prepareAttributeSlotsForNative();
|
|
192
|
+
// Linked-list walk: slot grouping would be discarded since we recurse into
|
|
193
|
+
// every child regardless of slot. `emitCreate` does its own single-walk
|
|
194
|
+
// serialization of `instanceId`s grouped by slot.
|
|
195
|
+
let child = node.firstChild;
|
|
196
|
+
while (child) {
|
|
197
|
+
emitCreateSubtree(child);
|
|
198
|
+
child = child.nextSibling;
|
|
199
|
+
}
|
|
200
|
+
node.prepareAttributeSlotsForHydration();
|
|
188
201
|
node.emitCreate();
|
|
189
202
|
}
|
|
190
203
|
function bindHydrationHandleId(instance, handleId, templateKey) {
|
|
204
|
+
const oldHandleId = instance.instanceId;
|
|
191
205
|
try {
|
|
192
206
|
backgroundElementTemplateInstanceManager.updateId(instance.instanceId, handleId);
|
|
193
|
-
|
|
207
|
+
// Ref proxies created before hydrate keep the old background id; resolve it
|
|
208
|
+
// lazily so user-held proxies continue selecting the hydrated native node.
|
|
209
|
+
hydrationMap.set(oldHandleId, handleId);
|
|
210
|
+
instance.markMaterializedByHydration();
|
|
194
211
|
return true;
|
|
195
212
|
}
|
|
196
213
|
catch (error) {
|