diff --git a/.changeset/rude-seas-design.md b/.changeset/rude-seas-design.md new file mode 100644 index 0000000000..853d812bb3 --- /dev/null +++ b/.changeset/rude-seas-design.md @@ -0,0 +1,3 @@ +--- + +--- diff --git a/packages/react/runtime/__test__/preact.test.jsx b/packages/react/runtime/__test__/preact.test.jsx index b66248966a..157c7252b3 100644 --- a/packages/react/runtime/__test__/preact.test.jsx +++ b/packages/react/runtime/__test__/preact.test.jsx @@ -404,7 +404,6 @@ describe('document - background', () => { expect(globalBackgroundSnapshotInstancesToRemove).toMatchInlineSnapshot(` [ 2, - 3, ] `); }); diff --git a/packages/react/runtime/src/backgroundSnapshot.ts b/packages/react/runtime/src/backgroundSnapshot.ts index 1b1bcb0cad..0ad248d330 100644 --- a/packages/react/runtime/src/backgroundSnapshot.ts +++ b/packages/react/runtime/src/backgroundSnapshot.ts @@ -23,7 +23,7 @@ import { } from './lifecycle/patch/snapshotPatch.js'; import { globalPipelineOptions } from './lynx/performance.js'; import { DynamicPartType } from './snapshot/dynamicPartType.js'; -import { clearQueuedRefs, queueRefAttrUpdate } from './snapshot/ref.js'; +import { applyRef, clearQueuedRefs, queueRefAttrUpdate } from './snapshot/ref.js'; import type { Ref } from './snapshot/ref.js'; import { transformSpread } from './snapshot/spread.js'; import type { SerializedSnapshotInstance, Snapshot } from './snapshot.js'; @@ -158,23 +158,37 @@ export class BackgroundSnapshotInstance { node.__previousSibling = null; node.__nextSibling = null; - traverseSnapshotInstance(node, v => { + queueRefAttrUpdate( + () => { + traverseSnapshotInstance(node, v => { + if (v.__values) { + v.__snapshot_def.refAndSpreadIndexes?.forEach((i) => { + const value = v.__values![i] as unknown; + if (value && (typeof value === 'object' || typeof value === 'function')) { + if ('__spread' in value && 'ref' in value) { + applyRef(value.ref as Ref, null); + } else if ('__ref' in value) { + applyRef(value as Ref, null); + } + } + }); + } + }); + }, + null, + 0, + 0, + ); + + globalBackgroundSnapshotInstancesToRemove.push(node.__id); + } + + tearDown(): void { + traverseSnapshotInstance(this, v => { v.__parent = null; v.__previousSibling = null; v.__nextSibling = null; - if (v.__values) { - v.__snapshot_def.refAndSpreadIndexes?.forEach((i) => { - const value = v.__values![i] as unknown; - if (value && (typeof value === 'object' || typeof value === 'function')) { - if ('__spread' in value && 'ref' in value) { - queueRefAttrUpdate(value.ref as Ref, null, v.__id, i); - } else if ('__ref' in value) { - queueRefAttrUpdate(value as Ref, null, v.__id, i); - } - } - }); - } - globalBackgroundSnapshotInstancesToRemove.push(v.__id); + backgroundSnapshotInstanceManager.values.delete(v.__id); }); } diff --git a/packages/react/runtime/src/lifecycle/patch/commit.ts b/packages/react/runtime/src/lifecycle/patch/commit.ts index dda7d7dd05..1d50aefc94 100644 --- a/packages/react/runtime/src/lifecycle/patch/commit.ts +++ b/packages/react/runtime/src/lifecycle/patch/commit.ts @@ -95,7 +95,7 @@ function replaceCommitHook(): void { if (backgroundSnapshotInstancesToRemove.length) { setTimeout(() => { backgroundSnapshotInstancesToRemove.forEach(id => { - backgroundSnapshotInstanceManager.values.delete(id); + backgroundSnapshotInstanceManager.values.get(id)?.tearDown(); }); }, 10000); } diff --git a/packages/react/runtime/src/snapshot/ref.ts b/packages/react/runtime/src/snapshot/ref.ts index dd1cee7979..4e3fc14520 100644 --- a/packages/react/runtime/src/snapshot/ref.ts +++ b/packages/react/runtime/src/snapshot/ref.ts @@ -10,8 +10,8 @@ import { RefProxy } from '../lifecycle/ref/delay.js'; const refsToClear: Ref[] = []; const refsToApply: (Ref | [snapshotInstanceId: number, expIndex: number])[] = []; -type Ref = (((ref: RefProxy) => () => void) | { current: RefProxy | null }) & { - _unmount?: () => void; +type Ref = (((ref: RefProxy) => (() => void) | void) | { current: RefProxy | null }) & { + _unmount?: (() => void) | void; __ref?: { value: number }; };