Skip to content

Commit 1af3b60

Browse files
authored
feat(web): add dispatchNapiModules of onNapiModulesCall (#414)
## Summary feat: onNapiModulesCall function add new param: `dispatchNapiModules`, napiModulesMap val add new param: `handleDispatch`. Now you can use them to actively communicate to napiModules (background thread) in onNapiModulesCall (ui thread). ## Checklist - [x] Tests updated (or not required). - [x] Documentation updated (or not required).
1 parent 6e8ebf4 commit 1af3b60

File tree

8 files changed

+97
-6
lines changed

8 files changed

+97
-6
lines changed

.changeset/solid-otters-live.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@lynx-js/web-constants": patch
3+
"@lynx-js/web-core": patch
4+
"@lynx-js/web-worker-runtime": patch
5+
---
6+
7+
feat: onNapiModulesCall function add new param: `dispatchNapiModules`, napiModulesMap val add new param: `handleDispatch`.
8+
9+
Now you can use them to actively communicate to napiModules (background thread) in onNapiModulesCall (ui thread).

packages/web-platform/web-constants/src/endpoints.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,8 @@ export const dispatchLynxViewEventEndpoint = createRpcEndpoint<
210210
],
211211
void
212212
>('dispatchLynxViewEvent', false, true);
213+
214+
export const dispatchNapiModuleEndpoint = createRpcEndpoint<
215+
[data: Cloneable],
216+
void
217+
>('dispatchNapiModule', false, false);

packages/web-platform/web-constants/src/types/NapiModules.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
// Licensed under the Apache License Version 2.0 that can be found in the
33
// LICENSE file in the root directory of this source tree.
44

5+
import type { Cloneable } from './Cloneable.js';
6+
57
export type NapiModulesMap = Record<string, string>;
68

79
export type NapiModulesCall = (
810
name: string,
911
data: any,
1012
moduleName: string,
13+
dispatchNapiModules: (data: Cloneable) => void,
1114
) => Promise<{ data: unknown; transfer?: unknown[] }> | {
1215
data: unknown;
1316
transfer?: unknown[];

packages/web-platform/web-core/src/apis/LynxView.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type INapiModulesCall = (
2121
data: any,
2222
moduleName: string,
2323
lynxView: LynxView,
24+
dispatchNapiModules: (data: Cloneable) => void,
2425
) => Promise<{ data: unknown; transfer?: Transferable[] }> | {
2526
data: unknown;
2627
transfer?: Transferable[];
@@ -194,8 +195,8 @@ export class LynxView extends HTMLElement {
194195
return this.#onNapiModulesCall;
195196
}
196197
set onNapiModulesCall(handler: INapiModulesCall) {
197-
this.#onNapiModulesCall = (name, data, moduleName) => {
198-
return handler(name, data, moduleName, this);
198+
this.#onNapiModulesCall = (name, data, moduleName, dispatchNapiModules) => {
199+
return handler(name, data, moduleName, this, dispatchNapiModules);
199200
};
200201
}
201202

packages/web-platform/web-core/src/uiThread/crossThreadHandlers/registerNapiModulesCallHandler.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,30 @@
33
// LICENSE file in the root directory of this source tree.
44
import type { Rpc } from '@lynx-js/web-worker-rpc';
55
import {
6+
dispatchNapiModuleEndpoint,
67
napiModulesCallEndpoint,
8+
type Cloneable,
79
type NapiModulesCall,
810
} from '@lynx-js/web-constants';
911

1012
export function registerNapiModulesCallHandler(
1113
rpc: Rpc,
1214
napiModulesCall: NapiModulesCall,
1315
) {
16+
const dispatchNapiModules = rpc.createCall(dispatchNapiModuleEndpoint);
1417
rpc.registerHandler(
1518
napiModulesCallEndpoint,
16-
napiModulesCall,
19+
(
20+
name: string,
21+
data: Cloneable,
22+
moduleName: string,
23+
) => {
24+
return napiModulesCall(
25+
name,
26+
data,
27+
moduleName,
28+
dispatchNapiModules,
29+
);
30+
},
1731
);
1832
}

packages/web-platform/web-tests/shell-project/web-core.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const color_environment = URL.createObjectURL(
3131
{ type: 'text/javascript' },
3232
),
3333
);
34-
3534
const color_methods = URL.createObjectURL(
3635
new Blob(
3736
[`export default function(NapiModules, NapiModulesCall) {
@@ -45,6 +44,19 @@ const color_methods = URL.createObjectURL(
4544
{ type: 'text/javascript' },
4645
),
4746
);
47+
const event_method = URL.createObjectURL(
48+
new Blob(
49+
[`export default function(NapiModules, NapiModulesCall, handleDispatch) {
50+
return {
51+
async bindEvent() {
52+
await NapiModulesCall('bindEvent');
53+
handleDispatch((data) => console.log(\`bts:\${data}\`))
54+
},
55+
};
56+
};`],
57+
{ type: 'text/javascript' },
58+
),
59+
);
4860

4961
async function run() {
5062
const lepusjs = '/resources/web-core.main-thread.json';
@@ -56,13 +68,26 @@ async function run() {
5668
lynxView.napiModulesMap = {
5769
'color_environment': color_environment,
5870
'color_methods': color_methods,
71+
'event_method': event_method,
5972
};
60-
lynxView.onNapiModulesCall = (name, data, moduleName, lynxView) => {
73+
lynxView.onNapiModulesCall = (
74+
name,
75+
data,
76+
moduleName,
77+
lynxView,
78+
dispatchNapiModules,
79+
) => {
6180
if (name === 'getColor' && moduleName === 'color_methods') {
6281
return {
6382
data: { color: data.color, tagName: lynxView.tagName },
6483
};
6584
}
85+
if (name === 'bindEvent' && moduleName === 'event_method') {
86+
document.querySelector('lynx-view')?.addEventListener('click', () => {
87+
dispatchNapiModules('lynx-view');
88+
});
89+
return;
90+
}
6691
};
6792
lynxView.addEventListener('error', () => {
6893
lynxView.setAttribute('style', 'display:none');

packages/web-platform/web-tests/tests/web-core.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ test.describe('web core tests', () => {
298298
expect(successCallback).toBeTruthy();
299299
expect(successCallback2).toBeTruthy();
300300
});
301-
302301
test('api-onNapiModulesCall-class', async ({ page, browserName }) => {
303302
// firefox dose not support this.
304303
test.skip(browserName === 'firefox');
@@ -331,4 +330,34 @@ test.describe('web core tests', () => {
331330
expect(successCallback).toBeTruthy();
332331
expect(successCallback2).toBeTruthy();
333332
});
333+
test('api-onNapiModulesCall-dispatchNapiModules', async ({ page, browserName }) => {
334+
// firefox dose not support this.
335+
test.skip(browserName === 'firefox');
336+
await goto(page);
337+
const mainWorker = await getMainThreadWorker(page);
338+
await mainWorker.evaluate(() => {
339+
globalThis.runtime.renderPage = () => {};
340+
});
341+
await wait(3000);
342+
const backWorker = await getBackgroundThreadWorker(page);
343+
let successDispatchNapiModule = false;
344+
await page.on('console', async (message) => {
345+
if (message.text() === 'bts:lynx-view') {
346+
successDispatchNapiModule = true;
347+
}
348+
});
349+
await backWorker.evaluate(() => {
350+
const nativeApp = globalThis.runtime.lynx.getNativeApp();
351+
const eventMethod = globalThis[`napiLoaderOnRT${nativeApp.id}`].load(
352+
'event_method',
353+
);
354+
eventMethod.bindEvent();
355+
});
356+
await wait(1000);
357+
await page.evaluate(() => {
358+
document.querySelector('lynx-view')?.click();
359+
});
360+
await wait(1000);
361+
expect(successDispatchNapiModule).toBeTruthy();
362+
});
334363
});

packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNapiLoader.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// LICENSE file in the root directory of this source tree.
44

55
import {
6+
dispatchNapiModuleEndpoint,
67
napiModulesCallEndpoint,
78
type Cloneable,
89
type NapiModulesMap,
@@ -25,6 +26,10 @@ export const createNapiLoader = async (
2526
napiModules,
2627
(name: string, data: Cloneable) =>
2728
napiModulesCall(name, data, moduleName),
29+
(func: (data: unknown) => void) => {
30+
rpc.registerHandler(dispatchNapiModuleEndpoint, (data) =>
31+
func(data));
32+
},
2833
),
2934
)
3035
),

0 commit comments

Comments
 (0)