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
9 changes: 9 additions & 0 deletions .changeset/fluffy-masks-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@lynx-js/web-mainthread-apis": patch
"@lynx-js/web-worker-runtime": patch
"@lynx-js/web-core-server": patch
"@lynx-js/web-constants": patch
"@lynx-js/web-core": patch
---

feat: supports lazy bundle. (This feature requires `@lynx-js/lynx-core >= 0.1.3`)
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ export class OffscreenElement extends EventTarget {
super.addEventListener(type, callback, options);
}

get textContent() {
return this[textContent];
}

Comment thread
Sherry-hue marked this conversation as resolved.
set textContent(text: string) {
this[ancestorDocument][operations].push(
OperationType.SetTextContent,
Expand Down
21 changes: 20 additions & 1 deletion packages/web-platform/web-constants/src/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import type { Cloneable, CloneableObject } from './types/Cloneable.js';
import type { StartMainThreadContextConfig } from './types/MainThreadStartConfigs.js';
import type { IdentifierType, InvokeCallbackRes } from './types/NativeApp.js';
import type { ElementAnimationOptions } from './types/Element.js';
import type { BackMainThreadContextConfig, MarkTiming } from './types/index.js';
import type {
BackMainThreadContextConfig,
LynxTemplate,
MarkTiming,
} from './types/index.js';

export const postExposureEndpoint = createRpcEndpoint<
[{ exposures: ExposureWorkerEvent[]; disExposures: ExposureWorkerEvent[] }],
Expand Down Expand Up @@ -240,3 +244,18 @@ export const dispatchI18nResourceEndpoint = createRpcEndpoint<
[Cloneable],
void
>('dispatchI18nResource', false, false);

export const queryComponentEndpoint = createRpcEndpoint<
[string],
{ code: number; detail: { schema: string } }
>('queryComponent', false, true);

export const updateBTSTemplateCacheEndpoint = createRpcEndpoint<
[/** url */ string, LynxTemplate],
void
>('updateBTSTemplateCacheEndpoint', false, true);

export const loadTemplateMultiThread = createRpcEndpoint<
[string],
LynxTemplate
>('loadTemplateMultiThread', false, true);
Comment thread
PupilTong marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ export type SetInlineStylesPAPI = (
export type SetCSSIdPAPI = (
elements: WebFiberElementImpl[],
cssId: number | null,
entryName: string | undefined,
) => void;
Comment thread
Sherry-hue marked this conversation as resolved.

export type GetPageElementPAPI = () => WebFiberElementImpl | undefined;
Expand Down Expand Up @@ -301,6 +302,17 @@ export type GetAttributeByNamePAPI = (
name: string,
) => string | null;

export type QueryComponentPAPI = (
source: string,
resultCallback?: (result: {
code: number;
data?: {
url: string;
evalResult: unknown;
};
}) => void,
) => null;

export interface MainThreadGlobalThis {
__ElementFromBinary: ElementFromBinaryPAPI;

Expand Down Expand Up @@ -381,6 +393,12 @@ export interface MainThreadGlobalThis {
) => unknown | undefined;
// This is an empty implementation, just to avoid business call errors
_AddEventListener: (...args: unknown[]) => void;
__QueryComponent: QueryComponentPAPI;
// DSL runtime binding
processEvalResult?: (
exports: unknown,
schema: string,
) => unknown;
// the following methods is assigned by the main thread user code
renderPage: ((data: unknown) => void) | undefined;
updatePage?: (data: Cloneable, options?: Record<string, string>) => void;
Expand Down
6 changes: 6 additions & 0 deletions packages/web-platform/web-constants/src/types/MarkTiming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ export interface MarkTiming {
pipelineId?: string;
timeStamp: number;
}

export type MarkTimingInternal = (
timingKey: string,
pipelineId?: string,
timeStamp?: number,
) => void;
13 changes: 12 additions & 1 deletion packages/web-platform/web-constants/src/types/NativeApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export interface NativeApp {

cancelAnimationFrame: (id: number) => void;

loadScript: (sourceURL: string) => BundleInitReturnObj;
loadScript: (sourceURL: string, entryName?: string) => BundleInitReturnObj;

loadScriptAsync(
sourceURL: string,
Expand Down Expand Up @@ -219,4 +219,15 @@ export interface NativeApp {

reportException: (error: Error, _: unknown) => void;
__SetSourceMapRelease: (err: Error) => void;

queryComponent: (
source: string,
callback: (
ret: { __hasReady: boolean } | {
code: number;
detail?: { schema: string };
},
) => void,
) => void;
tt: NativeTTObject | null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { LynxTemplate } from './LynxModule.js';

export type TemplateLoader = (url: string) => Promise<LynxTemplate>;
1 change: 1 addition & 0 deletions packages/web-platform/web-constants/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from './BackThreadStartConfigs.js';
export * from './MarkTiming.js';
export * from './SSR.js';
export * from './JSRealm.js';
export * from './TemplateLoader.js';
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,9 @@ const templateUpgraders: templateUpgrader[] = [
template.manifest = Object.fromEntries(
Object.entries(template.manifest).map(([key, value]) => [
key,
`module.exports={init: (lynxCoreInject) => { var {${defaultInjectStr}} = lynxCoreInject.tt; var module = {exports:null}; ${value}\n return module.exports; } }`,
`module.exports={init: (lynxCoreInject) => { var {${defaultInjectStr}} = lynxCoreInject.tt; var module = {exports:{}}; var exports=module.exports; ${value}\n return module.exports; } }`,
]),
) as typeof template.manifest;
template.lepusCode = Object.fromEntries(
Object.entries(template.lepusCode).map(([key, value]) => [
key,
`(()=>{${value}\n})();`,
]),
) as typeof template.lepusCode;
template.version = 2;
return template;
},
Expand All @@ -76,6 +70,7 @@ const templateUpgraders: templateUpgrader[] = [
const generateModuleContent = (
content: string,
eager: boolean,
appType: 'card' | 'lazy',
) =>
/**
* About the `allFunctionsCalledOnLoad` directive:
Expand All @@ -92,6 +87,7 @@ const generateModuleContent = (
'\n(function() { "use strict"; const ',
globalDisallowedVars.join('=void 0,'),
'=void 0;\n',
appType === 'lazy' ? 'module.exports=\n' : '',
content,
'\n})()',
].join('');
Expand All @@ -100,6 +96,7 @@ async function generateJavascriptUrl<T extends Record<string, string | {}>>(
obj: T,
createJsModuleUrl: (content: string, name: string) => Promise<string>,
eager: boolean,
appType: 'card' | 'lazy',
templateName?: string,
): Promise<T> {
const processEntry = async ([name, content]: [string, string]) => [
Expand All @@ -108,6 +105,7 @@ async function generateJavascriptUrl<T extends Record<string, string | {}>>(
generateModuleContent(
content,
eager,
appType,
),
`${templateName}-${name.replaceAll('/', '')}.js`,
),
Expand Down Expand Up @@ -147,12 +145,14 @@ export async function generateTemplate(
template.lepusCode,
createJsModuleUrl as (content: string, name: string) => Promise<string>,
true,
template.appType!,
templateName,
),
Comment thread
Sherry-hue marked this conversation as resolved.
manifest: await generateJavascriptUrl(
template.manifest,
createJsModuleUrl as (content: string, name: string) => Promise<string>,
false,
template.appType!,
templateName,
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ export async function createLynxView(
i18nResources.setData(initI18nResources);
return i18nResources;
},
(() => {}) as any,
{
Comment thread
Sherry-hue marked this conversation as resolved.
__AddEvent(element, eventName, eventData, eventOptions) {
events.push([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import {
lynxUniqueIdAttribute,
type SSRDumpInfo,
type JSRealm,
type TemplateLoader,
} from '@lynx-js/web-constants';
import { Rpc } from '@lynx-js/web-worker-rpc';
import { dispatchLynxViewEvent } from '../utils/dispatchLynxViewEvent.js';
import { createExposureMonitor } from './crossThreadHandlers/createExposureMonitor.js';
import type { StartUIThreadCallbacks } from './startUIThread.js';

const {
prepareMainThreadAPIs,
Expand Down Expand Up @@ -93,15 +95,14 @@ function createIFrameRealm(parent: Node): JSRealm {
export function createRenderAllOnUI(
mainToBackgroundRpc: Rpc,
shadowRoot: ShadowRoot,
loadTemplate: TemplateLoader,
markTimingInternal: (
timingKey: string,
pipelineId?: string,
timeStamp?: number,
) => void,
flushMarkTimingInternal: () => void,
callbacks: {
onError?: (err: Error, release: string, fileName: string) => void;
},
callbacks: StartUIThreadCallbacks,
ssrDumpInfo: SSRDumpInfo | undefined,
) {
Comment thread
Sherry-hue marked this conversation as resolved.
if (!globalThis.module) {
Expand Down Expand Up @@ -138,6 +139,7 @@ export function createRenderAllOnUI(
i18nResources.setData(initI18nResources);
return i18nResources;
},
loadTemplate,
);
const pendingUpdateCalls: Parameters<
RpcCallType<typeof updateDataEndpoint>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
// LICENSE file in the root directory of this source tree.

import {
loadTemplateMultiThread,
mainThreadStartEndpoint,
updateDataEndpoint,
updateI18nResourcesEndpoint,
type TemplateLoader,
} from '@lynx-js/web-constants';
import type { Rpc } from '@lynx-js/web-worker-rpc';
import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
import { registerFlushElementTreeHandler } from './crossThreadHandlers/registerFlushElementTreeHandler.js';
import { registerDispatchLynxViewEventHandler } from './crossThreadHandlers/registerDispatchLynxViewEventHandler.js';
import { createExposureMonitorForMultiThread } from './crossThreadHandlers/createExposureMonitor.js';
import type { StartUIThreadCallbacks } from './startUIThread.js';

export function createRenderMultiThread(
mainThreadRpc: Rpc,
shadowRoot: ShadowRoot,
callbacks: {
onError?: (err: Error, release: string, fileName: string) => void;
},
loadTemplate: TemplateLoader,
callbacks: StartUIThreadCallbacks,
) {
Comment thread
Sherry-hue marked this conversation as resolved.
registerReportErrorHandler(mainThreadRpc, 'lepus.js', callbacks.onError);
registerFlushElementTreeHandler(mainThreadRpc, { shadowRoot });
registerDispatchLynxViewEventHandler(mainThreadRpc, shadowRoot);
createExposureMonitorForMultiThread(mainThreadRpc, shadowRoot);
mainThreadRpc.registerHandler(loadTemplateMultiThread, loadTemplate);
const start = mainThreadRpc.createCall(mainThreadStartEndpoint);
const updateDataMainThread = mainThreadRpc.createCall(updateDataEndpoint);
const updateI18nResourcesMainThread = mainThreadRpc.createCall(
Expand Down
25 changes: 15 additions & 10 deletions packages/web-platform/web-core/src/uiThread/startUIThread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { LynxView } from '../apis/createLynxView.js';
import { bootWorkers } from './bootWorkers.js';
import { createDispose } from './crossThreadHandlers/createDispose.js';
import {
type LynxTemplate,
type StartMainThreadContextConfig,
type NapiModulesCall,
type NativeModulesCall,
Expand All @@ -15,8 +14,10 @@ import {
dispatchMarkTiming,
flushMarkTiming,
type SSRDumpInfo,
type TemplateLoader,
type MarkTimingInternal,
} from '@lynx-js/web-constants';
import { loadTemplate } from '../utils/loadTemplate.js';
import { createTemplateLoader } from '../utils/loadTemplate.js';
import { createUpdateData } from './crossThreadHandlers/createUpdateData.js';
import { startBackground } from './startBackground.js';
import { createRenderMultiThread } from './createRenderMultiThread.js';
Expand All @@ -26,7 +27,7 @@ export type StartUIThreadCallbacks = {
nativeModulesCall: NativeModulesCall;
napiModulesCall: NapiModulesCall;
onError?: (err: Error, release: string, fileName: string) => void;
customTemplateLoader?: (url: string) => Promise<LynxTemplate>;
customTemplateLoader?: TemplateLoader;
Comment thread
Sherry-hue marked this conversation as resolved.
};

export function startUIThread(
Expand Down Expand Up @@ -59,10 +60,10 @@ export function startUIThread(
records: [],
timeout: null,
};
const markTimingInternal = (
timingKey: string,
pipelineId?: string,
timeStamp?: number,
const markTimingInternal: MarkTimingInternal = (
timingKey,
pipelineId,
timeStamp,
) => {
dispatchMarkTiming({
timingKey,
Expand All @@ -74,10 +75,15 @@ export function startUIThread(
};
const flushMarkTimingInternal = () =>
flushMarkTiming(markTiming, cacheMarkTimings);
const templateLoader = createTemplateLoader(
callbacks.customTemplateLoader,
markTimingInternal,
);
const { start, updateDataMainThread, updateI18nResourcesMainThread } = allOnUI
? createRenderAllOnUI(
/* main-to-bg rpc*/ mainThreadRpc,
shadowRoot,
templateLoader,
markTimingInternal,
flushMarkTimingInternal,
callbacks,
Expand All @@ -86,12 +92,11 @@ export function startUIThread(
: createRenderMultiThread(
/* main-to-ui rpc*/ mainThreadRpc,
shadowRoot,
templateLoader,
callbacks,
);
markTimingInternal('create_lynx_start', undefined, createLynxStartTiming);
markTimingInternal('load_template_start');
loadTemplate(templateUrl, callbacks.customTemplateLoader).then((template) => {
markTimingInternal('load_template_end');
templateLoader(templateUrl).then((template) => {
flushMarkTimingInternal();
start({
...configs,
Expand Down
Loading
Loading