diff --git a/.changeset/silly-rocks-guess.md b/.changeset/silly-rocks-guess.md new file mode 100644 index 0000000000..d1845455b0 --- /dev/null +++ b/.changeset/silly-rocks-guess.md @@ -0,0 +1,7 @@ +--- +"@lynx-js/react": minor +--- + +Reverts #239: "batch multiple patches for main thread communication" + +This reverts the change that batched updates sent to the main thread in a single render pass. diff --git a/.changeset/strong-rockets-itch.md b/.changeset/strong-rockets-itch.md new file mode 100644 index 0000000000..7d675e7aba --- /dev/null +++ b/.changeset/strong-rockets-itch.md @@ -0,0 +1,6 @@ +--- +"@lynx-js/react-rsbuild-plugin": patch +"@lynx-js/react-webpack-plugin": patch +--- + +Support `@lynx-js/react` v0.108.0. diff --git a/packages/react/runtime/__test__/lifecycle.test.jsx b/packages/react/runtime/__test__/lifecycle.test.jsx index 95087ac645..bfb64ad1e5 100644 --- a/packages/react/runtime/__test__/lifecycle.test.jsx +++ b/packages/react/runtime/__test__/lifecycle.test.jsx @@ -1,20 +1,18 @@ -import { Component, options } from 'preact'; +import { Component, options, render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { useEffect, useLayoutEffect, useState } from '../src/index'; import { globalEnvManager } from './utils/envManager'; +import { waitSchedule } from './utils/nativeMethod'; import { initDelayUnmount } from '../src/lifecycle/delayUnmount'; import { globalCommitTaskMap, replaceCommitHook, replaceRequestAnimationFrame } from '../src/lifecycle/patch/commit'; import { deinitGlobalSnapshotPatch, initGlobalSnapshotPatch } from '../src/lifecycle/patch/snapshotPatch'; -import { renderBackground as render } from '../src/lifecycle/render'; import { LifecycleConstant } from '../src/lifecycleConstant'; import { CATCH_ERROR } from '../src/renderToOpcodes/constants'; import { __root } from '../src/root'; import { backgroundSnapshotInstanceManager, setupPage } from '../src/snapshot'; -import { elementTree, waitSchedule } from './utils/nativeMethod'; beforeAll(() => { - options.debounceRendering = Promise.prototype.then.bind(Promise.resolve()); setupPage(__CreatePage('0', 0)); replaceCommitHook(); initDelayUnmount(); @@ -30,7 +28,6 @@ afterEach(() => { globalEnvManager.resetEnv(); deinitGlobalSnapshotPatch(); vi.restoreAllMocks(); - elementTree.clear(); }); describe('useEffect', () => { @@ -804,118 +801,4 @@ describe('useState', () => { ); } }); - - it('should batch multiple updates', async function() { - let _setCount; - let _setCount2; - - const Child1 = () => { - const [count, setCount] = useState(0); - _setCount = setCount; - return ( - - - - ); - }; - - const Child2 = () => { - const [count, setCount] = useState(0); - _setCount2 = setCount; - return ( - - - - ); - }; - - const Comp = () => { - return ( - - - - - ); - }; - - // main thread render - { - __root.__jsx = ; - renderPage(); - } - - // background render - { - globalEnvManager.switchToBackground(); - render(, __root); - } - - // hydrate - { - // LifecycleConstant.firstScreen - lynxCoreInject.tt.OnLifecycleEvent(...globalThis.__OnLifecycleEvent.mock.calls[0]); - - // rLynxChange - globalEnvManager.switchToMainThread(); - globalThis.__OnLifecycleEvent.mockClear(); - const rLynxChange = lynx.getNativeApp().callLepusMethod.mock.calls[0]; - globalThis[rLynxChange[0]](rLynxChange[1]); - expect(globalThis.__OnLifecycleEvent).not.toBeCalled(); - } - - // insert node - { - globalEnvManager.switchToBackground(); - lynx.getNativeApp().callLepusMethod.mockClear(); - _setCount(1); - _setCount2(2); - await waitSchedule(); - - expect(lynx.getNativeApp().callLepusMethod).toHaveBeenCalledTimes(1); - expect(lynx.getNativeApp().callLepusMethod.mock.calls).toMatchInlineSnapshot( - ` - [ - [ - "rLynxChange", - { - "data": "{"patchList":[{"id":42,"snapshotPatch":[3,-3,0,1]},{"id":43,"snapshotPatch":[3,-4,0,2]}]}", - "patchOptions": { - "reloadVersion": 0, - }, - }, - [Function], - ], - ] - `, - ); - } - - { - globalEnvManager.switchToMainThread(); - globalThis.__OnLifecycleEvent.mockClear(); - const rLynxChange = lynx.getNativeApp().callLepusMethod.mock.calls[0]; - globalThis[rLynxChange[0]](rLynxChange[1]); - rLynxChange[2]; - lynx.getNativeApp().callLepusMethod.mockClear(); - await waitSchedule(); - expect(__root.__element_root).toMatchInlineSnapshot(` - - - - - - - - - - - `); - } - }); }); diff --git a/packages/react/runtime/__test__/lynx/timing.test.jsx b/packages/react/runtime/__test__/lynx/timing.test.jsx index 04601e217a..d4a575c0b7 100644 --- a/packages/react/runtime/__test__/lynx/timing.test.jsx +++ b/packages/react/runtime/__test__/lynx/timing.test.jsx @@ -3,12 +3,11 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. */ -import { Component, options } from 'preact'; +import { Component, options, render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import '../../src/lynx/component'; import { initTimingAPI } from '../../src/lynx/performance'; import { __root } from '../../src/root'; diff --git a/packages/react/runtime/__test__/snapshot/gesture.test.jsx b/packages/react/runtime/__test__/snapshot/gesture.test.jsx index a90dee9e38..9de53ab92e 100644 --- a/packages/react/runtime/__test__/snapshot/gesture.test.jsx +++ b/packages/react/runtime/__test__/snapshot/gesture.test.jsx @@ -1,8 +1,8 @@ +import { render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import { __root } from '../../src/root'; import { setupPage } from '../../src/snapshot'; import { globalEnvManager } from '../utils/envManager'; diff --git a/packages/react/runtime/__test__/snapshot/ref.test.jsx b/packages/react/runtime/__test__/snapshot/ref.test.jsx index c0421f3848..66e1251f8c 100644 --- a/packages/react/runtime/__test__/snapshot/ref.test.jsx +++ b/packages/react/runtime/__test__/snapshot/ref.test.jsx @@ -3,13 +3,13 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. */ +import { render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { Component, createRef, root, useState } from '../../src/index'; import { delayedLifecycleEvents } from '../../src/lifecycle/event/delayLifecycleEvents'; import { clearCommitTaskId, replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import { __pendingListUpdates } from '../../src/list'; import { __root } from '../../src/root'; import { setupPage } from '../../src/snapshot'; diff --git a/packages/react/runtime/__test__/snapshot/workletEvent.test.jsx b/packages/react/runtime/__test__/snapshot/workletEvent.test.jsx index fb2202bbab..54712065ff 100644 --- a/packages/react/runtime/__test__/snapshot/workletEvent.test.jsx +++ b/packages/react/runtime/__test__/snapshot/workletEvent.test.jsx @@ -3,12 +3,12 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. */ +import { render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { Component, useState } from '../../src/index'; import { replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import { __root } from '../../src/root'; import { setupPage } from '../../src/snapshot'; import { globalEnvManager } from '../utils/envManager'; diff --git a/packages/react/runtime/__test__/snapshot/workletRef.test.jsx b/packages/react/runtime/__test__/snapshot/workletRef.test.jsx index b7655c49a6..a4e78f0f2a 100644 --- a/packages/react/runtime/__test__/snapshot/workletRef.test.jsx +++ b/packages/react/runtime/__test__/snapshot/workletRef.test.jsx @@ -3,13 +3,13 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. */ +import { render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { createCompBG1, createCompBGList, createCompBGSpread } from './workletRefBG'; import { createCompMT1, createCompMTList, createCompMTSpread } from './workletRefMT'; import { replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import { __root } from '../../src/root'; import { setupPage } from '../../src/snapshot'; import { globalEnvManager } from '../utils/envManager'; diff --git a/packages/react/runtime/__test__/worklet/workletRef.test.jsx b/packages/react/runtime/__test__/worklet/workletRef.test.jsx index 9eb2079f3e..97b6fcc7d7 100644 --- a/packages/react/runtime/__test__/worklet/workletRef.test.jsx +++ b/packages/react/runtime/__test__/worklet/workletRef.test.jsx @@ -3,11 +3,11 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. */ +import { render } from 'preact'; import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { replaceCommitHook } from '../../src/lifecycle/patch/commit'; import { injectUpdateMainThread } from '../../src/lifecycle/patch/updateMainThread'; -import { renderBackground as render } from '../../src/lifecycle/render'; import { __root } from '../../src/root'; import { setupPage } from '../../src/snapshot'; import { destroyWorklet } from '../../src/worklet/destroy'; diff --git a/packages/react/runtime/src/lifecycle/destroy.ts b/packages/react/runtime/src/lifecycle/destroy.ts index bdbf4fa6c9..c37368685e 100644 --- a/packages/react/runtime/src/lifecycle/destroy.ts +++ b/packages/react/runtime/src/lifecycle/destroy.ts @@ -1,18 +1,19 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +import { render } from 'preact'; + import { __root } from '../root.js'; import { delayedEvents } from './event/delayEvents.js'; import { delayedLifecycleEvents } from './event/delayLifecycleEvents.js'; import { globalCommitTaskMap } from './patch/commit.js'; -import { renderBackground } from './render.js'; function destroyBackground(): void { if (__PROFILE__) { console.profile('destroyBackground'); } - renderBackground(null, __root as any); + render(null, __root as any); globalCommitTaskMap.forEach(task => { task(); diff --git a/packages/react/runtime/src/lifecycle/patch/commit.ts b/packages/react/runtime/src/lifecycle/patch/commit.ts index 296bd00ae0..2a50f4a768 100644 --- a/packages/react/runtime/src/lifecycle/patch/commit.ts +++ b/packages/react/runtime/src/lifecycle/patch/commit.ts @@ -30,11 +30,6 @@ let nextCommitTaskId = 1; let globalBackgroundSnapshotInstancesToRemove: number[] = []; -let patchesToCommit: Patch[] = []; -function clearPatchesToCommit(): void { - patchesToCommit = []; -} - interface Patch { id: number; snapshotPatch?: SnapshotPatch; @@ -53,28 +48,6 @@ interface PatchOptions { } function replaceCommitHook(): void { - // use our own `options.debounceRendering` to insert a timing flag before render - type DebounceRendering = (f: () => void) => void; - const injectDebounceRendering = (debounceRendering: DebounceRendering): DebounceRendering => { - return (f: () => void) => { - debounceRendering(() => { - f(); - void commitToMainThread(); - }); - }; - }; - const defaultDebounceRendering = options.debounceRendering?.bind(options) - ?? (Promise.prototype.then.bind(Promise.resolve()) as DebounceRendering); - let _debounceRendering = injectDebounceRendering(defaultDebounceRendering); - Object.defineProperty(options, 'debounceRendering', { - get() { - return _debounceRendering; - }, - set(debounceRendering: DebounceRendering) { - _debounceRendering = injectDebounceRendering(debounceRendering); - }, - }); - const oldCommit = options[COMMIT]; const commit = async (vnode: VNode, commitQueue: any[]) => { if (__LEPUS__) { @@ -82,6 +55,9 @@ function replaceCommitHook(): void { commitQueue.length = 0; return; } + + markTimingLegacy(PerformanceTimingKeys.updateDiffVdomEnd); + markTiming(PerformanceTimingKeys.diffVdomEnd); const renderCallbacks = commitQueue.map((component: Component) => { const ret = { component, @@ -121,7 +97,9 @@ function replaceCommitHook(): void { }); const snapshotPatch = takeGlobalSnapshotPatch(); + const flushOptions = globalFlushOptions; const workletRefInitValuePatch = takeWorkletRefInitValuePatch(); + globalFlushOptions = {}; if (!snapshotPatch && workletRefInitValuePatch.length === 0) { // before hydration, skip patch return; @@ -137,44 +115,23 @@ function replaceCommitHook(): void { if (workletRefInitValuePatch.length) { patch.workletRefInitValuePatch = workletRefInitValuePatch; } + const patchList: PatchList = { + patchList: [patch], + }; + if (!isEmptyObject(flushOptions)) { + patchList.flushOptions = flushOptions; + } + const obj = commitPatchUpdate(patchList, {}); - patchesToCommit.push(patch); - }; - options[COMMIT] = commit as ((...args: Parameters) => void); -} - -async function commitToMainThread(): Promise { - if (patchesToCommit.length === 0) { - return; - } - - markTimingLegacy(PerformanceTimingKeys.updateDiffVdomEnd); - markTiming(PerformanceTimingKeys.diffVdomEnd); - - const flushOptions = globalFlushOptions; - globalFlushOptions = {}; - - const patchList: PatchList = { - patchList: patchesToCommit, - }; - patchesToCommit = []; - - if (!isEmptyObject(flushOptions)) { - patchList.flushOptions = flushOptions; - } - - const obj = commitPatchUpdate(patchList, {}); - - lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, () => { - for (let i = 0; i < patchList.patchList.length; i++) { - const patch = patchList.patchList[i]!; - const commitTask = globalCommitTaskMap.get(patch.id); + lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, () => { + const commitTask = globalCommitTaskMap.get(commitTaskId); if (commitTask) { commitTask(); - globalCommitTaskMap.delete(patch.id); + globalCommitTaskMap.delete(commitTaskId); } - } - }); + }); + }; + options[COMMIT] = commit as ((...args: Parameters) => void); } function commitPatchUpdate(patchList: PatchList, patchOptions: Omit): { @@ -232,15 +189,12 @@ function replaceRequestAnimationFrame(): void { */ export { commitPatchUpdate, - commitToMainThread, genCommitTaskId, clearCommitTaskId, globalBackgroundSnapshotInstancesToRemove, globalCommitTaskMap, globalFlushOptions, nextCommitTaskId, - patchesToCommit, - clearPatchesToCommit, replaceCommitHook, replaceRequestAnimationFrame, type PatchOptions, diff --git a/packages/react/runtime/src/lifecycle/reload.ts b/packages/react/runtime/src/lifecycle/reload.ts index 9f7afb7ee2..b8d1bf9f03 100644 --- a/packages/react/runtime/src/lifecycle/reload.ts +++ b/packages/react/runtime/src/lifecycle/reload.ts @@ -1,6 +1,8 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +import { render } from 'preact'; + import { hydrate } from '../hydrate.js'; import { LifecycleConstant } from '../lifecycleConstant.js'; import { __pendingListUpdates } from '../list.js'; @@ -13,7 +15,7 @@ import { destroyWorklet } from '../worklet/destroy.js'; import { clearJSReadyEventIdSwap, isJSReady } from './event/jsReady.js'; import { increaseReloadVersion } from './pass.js'; import { deinitGlobalSnapshotPatch } from './patch/snapshotPatch.js'; -import { renderBackground, renderMainThread } from './render.js'; +import { renderMainThread } from './render.js'; function reloadMainThread(data: any, options: UpdatePageOption): void { if (__PROFILE__) { @@ -74,7 +76,7 @@ function reloadBackground(updateData: Record): void { // COW when modify `lynx.__initData` to make sure Provider & Consumer works lynx.__initData = Object.assign({}, lynx.__initData, updateData); - renderBackground(__root.__jsx, __root as any); + render(__root.__jsx, __root as any); if (__PROFILE__) { console.profileEnd(); diff --git a/packages/react/runtime/src/lifecycle/render.ts b/packages/react/runtime/src/lifecycle/render.ts index 1c67d0e547..c7823a72fa 100644 --- a/packages/react/runtime/src/lifecycle/render.ts +++ b/packages/react/runtime/src/lifecycle/render.ts @@ -2,12 +2,10 @@ // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. import { render } from 'preact'; -import type { ComponentChild, ContainerNode } from 'preact'; import { renderOpcodesInto } from '../opcodes.js'; import { render as renderToString } from '../renderToOpcodes/index.js'; import { __root } from '../root.js'; -import { commitToMainThread } from './patch/commit.js'; function renderMainThread(): void { /* v8 ignore start */ @@ -47,9 +45,4 @@ function renderMainThread(): void { /* v8 ignore stop */ } -function renderBackground(vnode: ComponentChild, parent: ContainerNode): void { - render(vnode, parent); - void commitToMainThread(); -} - -export { renderMainThread, renderBackground }; +export { renderMainThread }; diff --git a/packages/react/runtime/src/lynx-api.ts b/packages/react/runtime/src/lynx-api.ts index 25b274c0bd..3c369b795a 100644 --- a/packages/react/runtime/src/lynx-api.ts +++ b/packages/react/runtime/src/lynx-api.ts @@ -1,13 +1,13 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +import { render } from 'preact'; import { createContext, createElement } from 'preact/compat'; import { useState } from 'preact/hooks'; import type { Consumer, FC, ReactNode } from 'react'; import { factory, withInitDataInState } from './compat/initData.js'; import { useLynxGlobalEventListener } from './hooks/useLynxGlobalEventListener.js'; -import { renderBackground } from './lifecycle/render.js'; import { LifecycleConstant } from './lifecycleConstant.js'; import { flushDelayedLifecycleEvents } from './lynx/tt.js'; import { __root } from './root.js'; @@ -86,7 +86,7 @@ export const root: Root = { __root.__jsx = jsx; } else { __root.__jsx = jsx; - renderBackground(jsx, __root as any); + render(jsx, __root as any); if (__FIRST_SCREEN_SYNC_TIMING__ === 'immediately') { // This is for cases where `root.render()` is called asynchronously, // `firstScreen` message might have been reached. diff --git a/packages/react/runtime/src/lynx/tt.ts b/packages/react/runtime/src/lynx/tt.ts index 85306bb958..22679d9302 100644 --- a/packages/react/runtime/src/lynx/tt.ts +++ b/packages/react/runtime/src/lynx/tt.ts @@ -1,34 +1,30 @@ // Copyright 2024 The Lynx Authors. All rights reserved. // Licensed under the Apache License Version 2.0 that can be found in the // LICENSE file in the root directory of this source tree. +import { render } from 'preact'; + import { LifecycleConstant, NativeUpdateDataType } from '../lifecycleConstant.js'; import { - PerformanceTimingKeys, PerformanceTimingFlags, + PerformanceTimingKeys, PipelineOrigins, beginPipeline, markTiming, } from './performance.js'; import { BackgroundSnapshotInstance, hydrate } from '../backgroundSnapshot.js'; +import { runWithForce } from './runWithForce.js'; import { destroyBackground } from '../lifecycle/destroy.js'; import { delayedEvents, delayedPublishEvent } from '../lifecycle/event/delayEvents.js'; import { delayLifecycleEvent, delayedLifecycleEvents } from '../lifecycle/event/delayLifecycleEvents.js'; -import { - clearPatchesToCommit, - commitPatchUpdate, - genCommitTaskId, - globalCommitTaskMap, - patchesToCommit, - type PatchList, -} from '../lifecycle/patch/commit.js'; +import { commitPatchUpdate, genCommitTaskId, globalCommitTaskMap } from '../lifecycle/patch/commit.js'; +import type { PatchList } from '../lifecycle/patch/commit.js'; import { reloadBackground } from '../lifecycle/reload.js'; -import { renderBackground } from '../lifecycle/render.js'; import { CHILDREN } from '../renderToOpcodes/constants.js'; import { __root } from '../root.js'; import { globalRefsToSet, updateBackgroundRefs } from '../snapshot/ref.js'; import { backgroundSnapshotInstanceManager } from '../snapshot.js'; import { destroyWorklet } from '../worklet/destroy.js'; -import { runWithForce } from './runWithForce.js'; + export { runWithForce }; function injectTt(): void { @@ -129,14 +125,11 @@ function onLifecycleEventImpl(type: string, data: any): void { console.profile('commitChanges'); } const commitTaskId = genCommitTaskId(); - patchesToCommit.push( - { snapshotPatch, id: commitTaskId }, - ); const patchList: PatchList = { - patchList: patchesToCommit, + patchList: [{ snapshotPatch, id: commitTaskId }], }; - clearPatchesToCommit(); const obj = commitPatchUpdate(patchList, { isHydration: true }); + lynx.getNativeApp().callLepusMethod(LifecycleConstant.patchUpdate, obj, () => { updateBackgroundRefs(commitTaskId); globalCommitTaskMap.forEach((commitTask, id) => { @@ -212,7 +205,7 @@ function updateGlobalProps(newData: Record): void { // This is already done because updateFromRoot will consume all dirty flags marked by // the setState, and setState's flush will be a noop. No extra diffs will be needed. Promise.resolve().then(() => { - runWithForce(() => renderBackground(__root.__jsx, __root as any)); + runWithForce(() => render(__root.__jsx, __root as any)); }); lynxCoreInject.tt.GlobalEventEmitter.emit('onGlobalPropsChanged'); } diff --git a/packages/react/testing-library/src/__tests__/worklet.test.jsx b/packages/react/testing-library/src/__tests__/worklet.test.jsx index 221a73a413..b17ffeda7f 100644 --- a/packages/react/testing-library/src/__tests__/worklet.test.jsx +++ b/packages/react/testing-library/src/__tests__/worklet.test.jsx @@ -441,7 +441,24 @@ describe('worklet', () => { [ "rLynxChange", { - "data": "{"patchList":[{"id":1,"workletRefInitValuePatch":[[1,null],[2,0]]},{"snapshotPatch":[3,-2,0,{"_wvid":1},3,-2,1,{"_c":{"ref":{"_wvid":1},"num":{"_wvid":2}},"_wkltId":"a45f:test:9","_execId":1}],"id":2}]}", + "data": "{"patchList":[{"id":1,"workletRefInitValuePatch":[[1,null],[2,0]]}]}", + "patchOptions": { + "pipelineOptions": { + "dsl": "reactLynx", + "needTimestamps": true, + "pipelineID": "pipelineID", + "pipelineOrigin": "reactLynxHydrate", + "stage": "hydrate", + }, + "reloadVersion": 0, + }, + }, + [Function], + ], + [ + "rLynxChange", + { + "data": "{"patchList":[{"snapshotPatch":[3,-2,0,{"_wvid":1},3,-2,1,{"_c":{"ref":{"_wvid":1},"num":{"_wvid":2}},"_wkltId":"a45f:test:9","_execId":1}],"id":2}]}", "patchOptions": { "isHydration": true, "pipelineOptions": { diff --git a/packages/react/testing-library/src/pure.jsx b/packages/react/testing-library/src/pure.jsx index cad285ac72..92064e9346 100644 --- a/packages/react/testing-library/src/pure.jsx +++ b/packages/react/testing-library/src/pure.jsx @@ -8,9 +8,9 @@ import { act } from 'preact/test-utils'; import { __root } from '@lynx-js/react/internal'; +import { commitToMainThread } from '../../runtime/lib/lifecycle/patch/commit.js'; import { flushDelayedLifecycleEvents } from '../../runtime/lib/lynx/tt.js'; import { clearPage } from '../../runtime/lib/snapshot.js'; -import { commitToMainThread } from '../../runtime/lib/lifecycle/patch/commit.js'; export function waitSchedule() { return new Promise(resolve => { @@ -93,8 +93,6 @@ export function cleanup() { globalThis.lynxEnv.switchToBackgroundThread(); act(() => { preactRender(null, __root); - // This is needed to ensure that the ui updates are sent to the main thread - commitToMainThread(); }); lynxEnv.mainThread.elementTree.root = undefined; diff --git a/packages/react/testing-library/src/vitest-global-setup.js b/packages/react/testing-library/src/vitest-global-setup.js index d8dc92bb52..3cf3f44542 100644 --- a/packages/react/testing-library/src/vitest-global-setup.js +++ b/packages/react/testing-library/src/vitest-global-setup.js @@ -1,23 +1,21 @@ import { options } from 'preact'; -import { SnapshotInstance } from '../../runtime/lib/snapshot.js'; -import { snapshotInstanceManager } from '../../runtime/lib/snapshot.js'; + import { BackgroundSnapshotInstance } from '../../runtime/lib/backgroundSnapshot.js'; -import { backgroundSnapshotInstanceManager } from '../../runtime/lib/snapshot.js'; -import { injectCalledByNative } from '../../runtime/lib/lynx/calledByNative.js'; +import { clearCommitTaskId, replaceCommitHook } from '../../runtime/lib/lifecycle/patch/commit.js'; +import { deinitGlobalSnapshotPatch } from '../../runtime/lib/lifecycle/patch/snapshotPatch.js'; import { injectUpdateMainThread } from '../../runtime/lib/lifecycle/patch/updateMainThread.js'; -import { - replaceCommitHook, - clearPatchesToCommit, - clearCommitTaskId, -} from '../../runtime/lib/lifecycle/patch/commit.js'; -import { injectTt } from '../../runtime/lib/lynx/tt.js'; +import { injectCalledByNative } from '../../runtime/lib/lynx/calledByNative.js'; +import { flushDelayedLifecycleEvents, injectTt } from '../../runtime/lib/lynx/tt.js'; import { setRoot } from '../../runtime/lib/root.js'; -import { deinitGlobalSnapshotPatch } from '../../runtime/lib/lifecycle/patch/snapshotPatch.js'; +import { + SnapshotInstance, + backgroundSnapshotInstanceManager, + snapshotInstanceManager, +} from '../../runtime/lib/snapshot.js'; +import { destroyWorklet } from '../../runtime/lib/worklet/destroy.js'; import { initApiEnv } from '../../worklet-runtime/lib/api/lynxApi.js'; import { initEventListeners } from '../../worklet-runtime/lib/listeners.js'; import { initWorklet } from '../../worklet-runtime/lib/workletRuntime.js'; -import { destroyWorklet } from '../../runtime/lib/worklet/destroy.js'; -import { flushDelayedLifecycleEvents } from '../../runtime/lib/lynx/tt.js'; const { onInjectMainThreadGlobals, @@ -133,7 +131,6 @@ globalThis.onInjectBackgroundThreadGlobals = (target) => { // re-init global snapshot patch to undefined deinitGlobalSnapshotPatch(); - clearPatchesToCommit(); clearCommitTaskId(); }; globalThis.onResetLynxEnv = () => { diff --git a/packages/rspeedy/plugin-react/package.json b/packages/rspeedy/plugin-react/package.json index f27cd5be17..ea63568640 100644 --- a/packages/rspeedy/plugin-react/package.json +++ b/packages/rspeedy/plugin-react/package.json @@ -64,7 +64,7 @@ "typia-rspack-plugin": "2.0.1" }, "peerDependencies": { - "@lynx-js/react": "^0.103.0 || ^0.104.0 || ^0.105.0 || ^0.106.0 || ^0.107.0" + "@lynx-js/react": "^0.103.0 || ^0.104.0 || ^0.105.0 || ^0.106.0 || ^0.107.0 || ^0.108.0" }, "peerDependenciesMeta": { "@lynx-js/react": { diff --git a/packages/webpack/react-webpack-plugin/package.json b/packages/webpack/react-webpack-plugin/package.json index 2e0b82ba10..d7266d58be 100644 --- a/packages/webpack/react-webpack-plugin/package.json +++ b/packages/webpack/react-webpack-plugin/package.json @@ -53,7 +53,7 @@ "webpack": "^5.99.6" }, "peerDependencies": { - "@lynx-js/react": "^0.103.0 || ^0.104.0 || ^0.105.0 || ^0.106.0 || ^0.107.0", + "@lynx-js/react": "^0.103.0 || ^0.104.0 || ^0.105.0 || ^0.106.0 || ^0.107.0 || ^0.108.0", "@lynx-js/template-webpack-plugin": "^0.4.0 || ^0.5.0 || ^0.6.0" }, "peerDependenciesMeta": {