Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/upset-bats-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@lynx-js/web-worker-runtime": patch
"@lynx-js/web-constants": patch
"@lynx-js/web-core": patch
---

feat: support lynx.reload()
5 changes: 5 additions & 0 deletions packages/web-platform/web-constants/src/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,8 @@ export const loadTemplateMultiThread = createRpcEndpoint<
[string],
LynxTemplate
>('loadTemplateMultiThread', false, true);

export const reloadEndpoint = createRpcEndpoint<
[],
void
>('reload', false, false);
13 changes: 13 additions & 0 deletions packages/web-platform/web-core-wasm-e2e/tests/reactlynx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,19 @@ test.describe('reactlynx3 tests', () => {
page.locator('#wheat'),
).toHaveAttribute('style', /wheat/g);
});

test('basic-lynx-reload', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
const target = page.locator('#target');
await target.click();
await wait(100);
await expect(await target.getAttribute('style')).toContain('green');
await page.locator('#reload').click();
await wait(100);
await expect(await target.getAttribute('style')).toContain('pink');
});

test(
'basic-wrapper-element-do-not-impact-layout',
async ({ page }, { title }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2023 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 { useState, root } from '@lynx-js/react';
function App() {
const [color, setColor] = useState('pink');
return (
<>
<view
id='target'
bindTap={() => setColor(color === 'pink' ? 'green' : 'pink')}
style={{
height: '100px',
width: '100px',
background: color,
}}
/>
<view
id='reload'
bindTap={() => {
lynx.reload();
}}
style={{
height: '100px',
width: '100px',
background: color,
}}
/>
</>
);
}
root.render(<App />);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import {
dispatchCoreContextOnBackgroundEndpoint,
dispatchJSContextOnMainThreadEndpoint,
reloadEndpoint,
} from '../../endpoints.js';
import type { Rpc } from '@lynx-js/web-worker-rpc';
import { createGetCustomSection } from './crossThreadHandlers/createGetCustomSection.js';
Expand Down Expand Up @@ -56,5 +57,8 @@ export function createBackgroundLynx(
},
) => void,
) => nativeApp.queryComponent(source, callback),
reload: () => {
mainThreadRpc.invoke(reloadEndpoint, []);
},
};
}
5 changes: 5 additions & 0 deletions packages/web-platform/web-core-wasm/ts/client/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,8 @@ export const updateBTSChunkEndpoint = createRpcEndpoint<
[/** url */ string, Record<string, string>],
void
>('updateBTSChunkEndpoint', false, true);

export const reloadEndpoint = createRpcEndpoint<
[],
void
>('reload', false, false);
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { registerTriggerComponentEventHandler } from './crossThreadHandlers/regi
import { registerTriggerElementMethodEndpointHandler } from './crossThreadHandlers/registerTriggerElementMethodEndpointHandler.js';
import { registerNapiModulesCallHandler } from './crossThreadHandlers/registerNapiModulesCallHandler.js';
import { registerNativeModulesCallHandler } from './crossThreadHandlers/registerNativeModulesCallHandler.js';
import { registerReloadHandler } from './crossThreadHandlers/registerReloadHandler.js';

function createWebWorker(): Worker {
return new Worker(
Expand Down Expand Up @@ -236,6 +237,7 @@ export class BackgroundThread implements AsyncDisposable {
});
},
);
registerReloadHandler(this.#rpc, this.#lynxViewInstance);
registerGetPathInfoHandler(this.#rpc, this.#lynxViewInstance);
registerInvokeUIMethodHandler(this.#rpc, this.#lynxViewInstance);
registerNapiModulesCallHandler(this.#rpc, this.#lynxViewInstance);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2026 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 type { Rpc } from '@lynx-js/web-worker-rpc';
import { reloadEndpoint } from '../../endpoints.js';
import type { LynxViewInstance } from '../LynxViewInstance.js';

export function registerReloadHandler(
rpc: Rpc,
lynxViewInstance: LynxViewInstance,
) {
rpc.registerHandler(
reloadEndpoint,
() => {
lynxViewInstance.parentDom.reload();
},
);
}
3 changes: 3 additions & 0 deletions packages/web-platform/web-core/src/apis/LynxView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,9 @@ export class LynxView extends HTMLElement {
);
},
customTemplateLoader: this.customTemplateLoader,
reload: () => {
this.reload();
},
},
ssr: ssrData
? JSON.parse(decodeURI(ssrData)) as SSRDumpInfo
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2026 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 type { Rpc } from '@lynx-js/web-worker-rpc';
import { reloadEndpoint } from '@lynx-js/web-constants';

export function registerReloadHandler(
rpc: Rpc,
reloadHandler: () => void,
) {
rpc.registerHandler(
reloadEndpoint,
reloadHandler,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { registerTriggerElementMethodEndpointHandler } from './crossThreadHandle
import type { StartUIThreadCallbacks } from './startUIThread.js';
import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
import { registerGetPathInfoHandler } from './crossThreadHandlers/registerGetPathInfoHandler.js';
import { registerReloadHandler } from './crossThreadHandlers/registerReloadHandler.js';

export function startBackground(
backgroundRpc: Rpc,
Expand Down Expand Up @@ -60,6 +61,10 @@ export function startBackground(
'app-service.js',
callbacks.onError,
);
registerReloadHandler(
backgroundRpc,
callbacks.reload,
);

const sendGlobalEvent = backgroundRpc.createCall(sendGlobalEventEndpoint);
const markTiming = backgroundRpc.createCall(markTimingEndpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type StartUIThreadCallbacks = {
napiModulesCall: NapiModulesCall;
onError?: (err: Error, release: string, fileName: string) => void;
customTemplateLoader?: TemplateLoader;
reload: () => void;
};

export function startUIThread(
Expand Down
12 changes: 12 additions & 0 deletions packages/web-platform/web-tests/tests/react.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
ReturnType<typeof expect<Page>>['toHaveScreenshot']
>[0],
) => {
await expect(page).toHaveScreenshot([

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4430:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder-font-size

10) [webkit] › tests/react.spec.ts:4430:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder-font-size Error: expect(page).toHaveScreenshot(expected) failed 5343 pixels (ratio 0.03 of all image pixels) are different. Snapshot: x-textarea/placeholder-font-size/font-size/index.png Call log: - Expect "toHaveScreenshot(x-textarea/placeholder-font-size/font-size/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 5343 pixels (ratio 0.03 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 5343 pixels (ratio 0.03 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4435:17

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4401:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder-style

9) [webkit] › tests/react.spec.ts:4401:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder-style Error: expect(page).toHaveScreenshot(expected) failed 80091 pixels (ratio 0.31 of all image pixels) are different. Snapshot: x-textarea/placeholder-style/init-value/index.png Call log: - Expect "toHaveScreenshot(x-textarea/placeholder-style/init-value/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 80091 pixels (ratio 0.31 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 80091 pixels (ratio 0.31 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4406:17

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4372:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder

8) [webkit] › tests/react.spec.ts:4372:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-placeholder Error: expect(page).toHaveScreenshot(expected) failed 79830 pixels (ratio 0.31 of all image pixels) are different. Snapshot: x-textarea/placeholder/init-value/index.png Call log: - Expect "toHaveScreenshot(x-textarea/placeholder/init-value/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 79830 pixels (ratio 0.31 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 79830 pixels (ratio 0.31 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4377:17

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4317:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-maxlines

7) [webkit] › tests/react.spec.ts:4317:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-maxlines Error: expect(page).toHaveScreenshot(expected) failed 21008 pixels (ratio 0.09 of all image pixels) are different. Snapshot: x-textarea/maxlines/init-value/index.png Call log: - Expect "toHaveScreenshot(x-textarea/maxlines/init-value/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 21008 pixels (ratio 0.09 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 21008 pixels (ratio 0.09 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4320:15

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4283:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-maxlength

6) [webkit] › tests/react.spec.ts:4283:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-maxlength Error: expect(page).toHaveScreenshot(expected) failed 21143 pixels (ratio 0.09 of all image pixels) are different. Snapshot: x-textarea/maxlength/default/index.png Call log: - Expect "toHaveScreenshot(x-textarea/maxlength/default/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 21143 pixels (ratio 0.09 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 21143 pixels (ratio 0.09 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4288:17

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4263:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-disabled

5) [webkit] › tests/react.spec.ts:4263:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-disabled Error: expect(page).toHaveScreenshot(expected) failed 80560 pixels (ratio 0.32 of all image pixels) are different. Snapshot: x-textarea/disabled/default/index.png Call log: - Expect "toHaveScreenshot(x-textarea/disabled/default/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 80560 pixels (ratio 0.32 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 80560 pixels (ratio 0.32 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4266:15

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4013:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-circular-carry

3) [webkit] › tests/react.spec.ts:4013:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-circular-carry Error: expect(page).toHaveScreenshot(expected) failed 53069 pixels (ratio 0.21 of all image pixels) are different. Snapshot: x-swiper/circular/carry/index.png Call log: - Expect "toHaveScreenshot(x-swiper/circular/carry/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 53069 pixels (ratio 0.21 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 53069 pixels (ratio 0.21 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4018:17

Check failure on line 24 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:3968:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-circular-flat-coverflow

2) [webkit] › tests/react.spec.ts:3968:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-circular-flat-coverflow Error: expect(page).toHaveScreenshot(expected) failed 35429 pixels (ratio 0.14 of all image pixels) are different. Snapshot: x-swiper/circular/flat-coverflow/index.png Call log: - Expect "toHaveScreenshot(x-swiper/circular/flat-coverflow/index.png)" with timeout 5000ms - verifying given screenshot expectation - taking page screenshot - waiting for fonts to load... - fonts loaded - 35429 pixels (ratio 0.14 of all image pixels) are different. - waiting 100ms before taking screenshot - taking page screenshot - waiting for fonts to load... - fonts loaded - captured a stable screenshot - 35429 pixels (ratio 0.14 of all image pixels) are different. 22 | >[0], 23 | ) => { > 24 | await expect(page).toHaveScreenshot([ | ^ 25 | `${caseName}`, 26 | `${subcaseName}`, 27 | `${label}.png`, at diffScreenShot (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:24:22) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:3973:17
`${caseName}`,
`${subcaseName}`,
`${label}.png`,
Expand Down Expand Up @@ -250,6 +250,18 @@
page.locator('#wheat'),
).toHaveAttribute('style', /wheat/g);
});

test('basic-lynx-reload', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
const target = page.locator('#target');
await target.click();
await wait(100);
await expect(await target.getAttribute('style')).toContain('green');
await page.locator('#reload').click();
await wait(100);
await expect(await target.getAttribute('style')).toContain('pink');
});
test(
'basic-wrapper-element-do-not-impact-layout',
async ({ page }, { title }) => {
Expand Down Expand Up @@ -4238,7 +4250,7 @@
// we may miss the first one
expect(autoplay[2]).toBe(true);
expect(autoplay[3]).toBe(true);
expect(programming).toBe(true);

Check failure on line 4253 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4202:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-bindscrollend

4) [webkit] › tests/react.spec.ts:4202:7 › reactlynx3 tests › elements › x-swiper › basic-element-x-swiper-bindscrollend Error: expect(received).toBe(expected) // Object.is equality Expected: true Received: false 4251 | expect(autoplay[2]).toBe(true); 4252 | expect(autoplay[3]).toBe(true); > 4253 | expect(programming).toBe(true); | ^ 4254 | if (browserName === 'chromium') { 4255 | expect(manual).toBe(true); 4256 | } at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4253:31
if (browserName === 'chromium') {
expect(manual).toBe(true);
}
Expand Down Expand Up @@ -4486,7 +4498,7 @@
await wait(100);
expect(bindblur).toBeTruthy();
expect(bindfocus).toBeTruthy();
expect(bindinput).toBeTruthy();

Check failure on line 4501 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4449:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-bindinput

11) [webkit] › tests/react.spec.ts:4449:7 › reactlynx3 tests › elements › x-textarea › basic-element-x-textarea-bindinput Error: expect(received).toBeTruthy() Received: false 4499 | expect(bindblur).toBeTruthy(); 4500 | expect(bindfocus).toBeTruthy(); > 4501 | expect(bindinput).toBeTruthy(); | ^ 4502 | }, 4503 | ); 4504 | // x-textarea/bindinput test-case end at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4501:29
},
);
// x-textarea/bindinput test-case end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2023 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 { useState, root } from '@lynx-js/react';
function App() {
const [color, setColor] = useState('pink');
return (
<>
<view
id='target'
bindTap={() => setColor(color === 'pink' ? 'green' : 'pink')}
style={{
height: '100px',
width: '100px',
background: color,
}}
/>
<view
id='reload'
bindTap={() => {
lynx.reload();
}}
style={{
height: '100px',
width: '100px',
background: color,
}}
/>
</>
);
}
root.render(<App />);
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
dispatchCoreContextOnBackgroundEndpoint,
dispatchJSContextOnMainThreadEndpoint,
LynxCrossThreadContext,
reloadEndpoint,
type BackMainThreadContextConfig,
type NativeApp,
} from '@lynx-js/web-constants';
Expand Down Expand Up @@ -57,5 +58,8 @@ export function createBackgroundLynx(
},
) => void,
) => nativeApp.queryComponent(source, callback),
reload: () => {
uiThreadRpc.invoke(reloadEndpoint, []);
},
};
}
Loading