diff --git a/.changeset/all-melons-fall.md b/.changeset/all-melons-fall.md new file mode 100644 index 0000000000..8cba95252c --- /dev/null +++ b/.changeset/all-melons-fall.md @@ -0,0 +1,11 @@ +--- +"@lynx-js/web-mainthread-apis": patch +"@lynx-js/web-worker-runtime": patch +"@lynx-js/web-constants": patch +"@lynx-js/web-webpack-plugin": patch +"@lynx-js/web-core": patch +--- + +feat: support mts event handler (1/n) + +now the main-thread:bind handler could be invoked. The params of the handler will be implemented later. diff --git a/packages/web-platform/web-constants/src/constants.ts b/packages/web-platform/web-constants/src/constants.ts index 78dbf5c1e2..5e007a1121 100644 --- a/packages/web-platform/web-constants/src/constants.ts +++ b/packages/web-platform/web-constants/src/constants.ts @@ -20,4 +20,6 @@ export const __lynx_timing_flag = '__lynx_timing_flag' as const; export const globalMuteableVars = [ 'registerDataProcessor', + 'registerWorkletInternal', + 'lynxWorkletImpl', ] as const; diff --git a/packages/web-platform/web-core/src/utils/loadTemplate.ts b/packages/web-platform/web-core/src/utils/loadTemplate.ts index f119ef7d1d..d153bfce9d 100644 --- a/packages/web-platform/web-core/src/utils/loadTemplate.ts +++ b/packages/web-platform/web-core/src/utils/loadTemplate.ts @@ -98,6 +98,7 @@ const mainThreadInjectVars = [ '__SetCSSId', '__OnLifecycleEvent', '__FlushElementTree', + '__LoadLepusChunk', ]; const backgroundInjectVars = [ diff --git a/packages/web-platform/web-mainthread-apis/src/MainThreadLynx.ts b/packages/web-platform/web-mainthread-apis/src/MainThreadLynx.ts index 301972d977..98513c654a 100644 --- a/packages/web-platform/web-mainthread-apis/src/MainThreadLynx.ts +++ b/packages/web-platform/web-mainthread-apis/src/MainThreadLynx.ts @@ -12,6 +12,10 @@ export function createMainThreadLynx( lepusRuntime: MainThreadRuntime, ) { return { + getJSContext() { + // TODO: implement this + return new EventTarget(); + }, requestAnimationFrame(cb: FrameRequestCallback) { return requestAnimationFrame(cb); }, @@ -23,8 +27,8 @@ export function createMainThreadLynx( requireModule(path: string) { // @ts-expect-error if (self.WorkerGlobalScope) { - const mainfestUrl = config.lepusCode[`/${path}`]; - if (mainfestUrl) path = mainfestUrl; + const lepusChunkUrl = config.lepusCode[`${path}`]; + if (lepusChunkUrl) path = lepusChunkUrl; // @ts-expect-error importScripts(path); const entry = (globalThis.module as LynxJSModule).exports; @@ -39,8 +43,8 @@ export function createMainThreadLynx( path: string, callback: (error: Error | null, exports?: unknown) => void, ) { - const mainfestUrl = config.lepusCode[`/${path}`]; - if (mainfestUrl) path = mainfestUrl; + const lepusChunkUrl = config.lepusCode[`${path}`]; + if (lepusChunkUrl) path = lepusChunkUrl; import( /* webpackIgnore: true */ path diff --git a/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts b/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts index 1b2b8bc35a..5a480c96a9 100644 --- a/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts +++ b/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts @@ -167,7 +167,9 @@ export class MainThreadRuntime { }, set: (v: any) => { this.__lynxGlobalBindingValues[nm] = v; - this._updateVars?.(); + for (const handler of this.__varsUpdateHandlers) { + handler(); + } }, }); } @@ -237,6 +239,10 @@ export class MainThreadRuntime { }; updatePage?: (data: Cloneable, options?: Record) => void; + runWorklet?: (obj: unknown, event: unknown) => void; - _updateVars?: () => void; + private __varsUpdateHandlers: (() => void)[] = []; + set _updateVars(handler: () => void) { + this.__varsUpdateHandlers.push(handler); + } } diff --git a/packages/web-platform/web-mainthread-apis/src/elementAPI/ElementThreadElement.ts b/packages/web-platform/web-mainthread-apis/src/elementAPI/ElementThreadElement.ts index 83af7ab62d..3e99998135 100644 --- a/packages/web-platform/web-mainthread-apis/src/elementAPI/ElementThreadElement.ts +++ b/packages/web-platform/web-mainthread-apis/src/elementAPI/ElementThreadElement.ts @@ -11,11 +11,11 @@ export interface LynxRuntimeInfo { eventHandlerMap: Record; componentAtIndex?: ComponentAtIndexCallback; diff --git a/packages/web-platform/web-mainthread-apis/src/elementAPI/event/eventFunctions.ts b/packages/web-platform/web-mainthread-apis/src/elementAPI/event/eventFunctions.ts index 1d3300ed2d..aa497e9ac5 100644 --- a/packages/web-platform/web-mainthread-apis/src/elementAPI/event/eventFunctions.ts +++ b/packages/web-platform/web-mainthread-apis/src/elementAPI/event/eventFunctions.ts @@ -7,7 +7,6 @@ import { LynxEventNameToW3cCommon, lynxTagAttribute, W3cEventNameToLynx, - type LynxCrossThreadEvent, type LynxEventType, } from '@lynx-js/web-constants'; import { @@ -31,7 +30,7 @@ export function createEventFunctions(runtime: MainThreadRuntime) { ?.handler : runtimeInfo.eventHandlerMap[lynxEventName]?.bind ?.handler; - if (hname) { + if (typeof hname === 'string') { const crossThreadEvent = createCrossThreadEvent( runtime, event, @@ -58,6 +57,8 @@ export function createEventFunctions(runtime: MainThreadRuntime) { ); } return true; + } else if (hname) { + runtime.runWorklet?.(hname.value, []); } return false; }; @@ -69,8 +70,7 @@ export function createEventFunctions(runtime: MainThreadRuntime) { element: HTMLElement, eventType: LynxEventType, eventName: string, - newEventHandler: string | undefined // | ((ev: LynxCrossThreadEvent) => void) | undefined, - , + newEventHandler: string | { type: 'worklet'; value: unknown } | undefined, ) { eventName = eventName.toLowerCase(); const isCatch = eventType === 'catchEvent' || eventType === 'capture-catch'; @@ -125,7 +125,7 @@ export function createEventFunctions(runtime: MainThreadRuntime) { element: HTMLElement, eventName: string, eventType: LynxEventType, - ): string | ((ev: LynxCrossThreadEvent) => void) | undefined { + ): string | { type: 'worklet'; value: unknown } | undefined { const runtimeInfo = runtime[elementToRuntimeInfoMap].get(element)!; eventName = eventName.toLowerCase(); const isCapture = eventType.startsWith('capture'); @@ -138,26 +138,25 @@ export function createEventFunctions(runtime: MainThreadRuntime) { function __GetEvents(element: HTMLElement): { type: LynxEventType; name: string; - function: string | ((ev: Event) => void) | undefined; + function: string | { type: 'worklet'; value: unknown } | undefined; }[] { const eventHandlerMap = runtime[elementToRuntimeInfoMap].get(element)!.eventHandlerMap; const eventInfos: { type: LynxEventType; name: string; - function: string | ((ev: Event) => void) | undefined; + function: string | { type: 'worklet'; value: unknown } | undefined; }[] = []; for (const [lynxEventName, info] of Object.entries(eventHandlerMap)) { for (const atomInfo of [info.bind, info.capture]) { if (atomInfo) { - for (const [type, handler] of Object.values(atomInfo)) { - if (handler) { - eventInfos.push({ - type: type as LynxEventType, - name: lynxEventName, - function: handler, - }); - } + const { type, handler } = atomInfo; + if (handler) { + eventInfos.push({ + type: type as LynxEventType, + name: lynxEventName, + function: handler, + }); } } } diff --git a/packages/web-platform/web-tests/resources/web-core.main-thread.json b/packages/web-platform/web-tests/resources/web-core.main-thread.json index 36503a8edc..2027acd174 100644 --- a/packages/web-platform/web-tests/resources/web-core.main-thread.json +++ b/packages/web-platform/web-tests/resources/web-core.main-thread.json @@ -2,8 +2,8 @@ "styleInfo": {}, "lepusCode": { "root": "self.runtime = lynx_runtime;self.__lynx_worker_type = 'main'; globalThis.registerDataProcessor='pass'; self.registerDataProcessor = registerDataProcessor;", - "/manifest-chunk.js": "module.exports = 'hello';", - "/manifest-chunk2.js": "module.exports = 'world';" + "manifest-chunk.js": "module.exports = 'hello';", + "manifest-chunk2.js": "module.exports = 'world';" }, "manifest": { "/app-service.js": "self.runtime = lynx_runtime; self.__lynx_worker_type = 'background'", diff --git a/packages/web-platform/web-tests/tests/react.spec.ts b/packages/web-platform/web-tests/tests/react.spec.ts index 52167a631c..12126096a0 100644 --- a/packages/web-platform/web-tests/tests/react.spec.ts +++ b/packages/web-platform/web-tests/tests/react.spec.ts @@ -255,6 +255,20 @@ test.describe('reactlynx3 tests', () => { await expect(target).toHaveCSS('width', '100px'); await expect(target).toHaveCSS('background-color', 'rgb(255, 192, 203)'); }); + test('basic-mts-bindtap', async ({ page }, { title }) => { + let eventHandlerTriggered = false; + page.on('console', (message) => { + if (message.text() === 'hello world') { + eventHandlerTriggered = true; + } + }); + await goto(page, title); + await wait(100); + const target = page.locator('#target'); + await target.click(); + await wait(100); + expect(eventHandlerTriggered).toBe(true); + }); }); test.describe('basic-css', () => { test('basic-css-asset-in-css', async ({ page }, { title }) => { diff --git a/packages/web-platform/web-tests/tests/react/basic-mts-bindtap/index.jsx b/packages/web-platform/web-tests/tests/react/basic-mts-bindtap/index.jsx new file mode 100644 index 0000000000..3fff7e79bf --- /dev/null +++ b/packages/web-platform/web-tests/tests/react/basic-mts-bindtap/index.jsx @@ -0,0 +1,22 @@ +// 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] = useState('pink'); + return ( + { + 'main thread'; + console.log('hello world'); + }} + style={{ + height: '100px', + width: '100px', + background: color, + }} + /> + ); +} +root.render(); diff --git a/packages/web-platform/web-worker-runtime/src/index.ts b/packages/web-platform/web-worker-runtime/src/index.ts index 8a297eb982..499e6f76b1 100644 --- a/packages/web-platform/web-worker-runtime/src/index.ts +++ b/packages/web-platform/web-worker-runtime/src/index.ts @@ -23,6 +23,6 @@ self.onmessage = (ev) => { } }; Object.assign(globalThis, { - SystemInfo: { platform: 'web' }, + SystemInfo: { platform: 'web', lynxSdkVersion: '3.0' }, module: { exports: null }, }); diff --git a/packages/webpack/web-webpack-plugin/src/index.ts b/packages/webpack/web-webpack-plugin/src/index.ts index 484ed8c9bc..4e5bcb957c 100644 --- a/packages/webpack/web-webpack-plugin/src/index.ts +++ b/packages/webpack/web-webpack-plugin/src/index.ts @@ -68,7 +68,11 @@ export class WebWebpackPlugin { manifest: encodeOptions.manifest, cardType: encodeOptions['cardType'], pageConfig: encodeOptions.compilerOptions, - lepusCode: encodeOptions.lepusCode, + lepusCode: { + // flatten the lepusCode to a single object + ...encodeOptions.lepusCode.lepusChunk, + root: encodeOptions.lepusCode.root, + }, customSections: encodeOptions.customSections, })), debugInfo: '',