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

feat: add `updateI18nResources` method of lynx-view.

Now you can use `updateI18nResources` to update i18nResources, and then use _I18nResourceTranslation() to get the updated result.
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 @@ -213,3 +213,8 @@ export const updateGlobalPropsEndpoint = createRpcEndpoint<
[Cloneable],
void
>('updateGlobalProps', false, false);

export const updateI18nResourcesEndpoint = createRpcEndpoint<
[Cloneable],
void
>('updateI18nResources', false, false);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// LICENSE file in the root directory of this source tree.

import type { Cloneable } from './Cloneable.js';
import type { InitI18nResources } from './index.js';
import type { LynxTemplate } from './LynxModule.js';
import type { NapiModulesMap } from './NapiModules.js';
import type { NativeModulesMap } from './NativeModules.js';
Expand All @@ -18,5 +17,4 @@ export interface BackMainThreadContextConfig {
nativeModulesMap: NativeModulesMap;
napiModulesMap: NapiModulesMap;
browserConfig: BrowserConfig;
initI18nResources: InitI18nResources;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
export type Cloneable<T = string | number | null | boolean | undefined> =
| T
| Record<string, T>
| T[];
| T[]
| Array<Record<string, Cloneable>>;

export type CloneableObject<T = string | number | null | boolean | undefined> =
Record<
Expand Down
10 changes: 10 additions & 0 deletions packages/web-platform/web-constants/src/types/I18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ export type InitI18nResources = Array<{
}>;

export const i18nResourceMissedEventName = 'i18nResourceMissed' as const;

export class I18nResources {
data?: InitI18nResources;
constructor(data?: InitI18nResources) {
this.data = data;
}
setData(data: InitI18nResources) {
this.data = data;
}
}
7 changes: 7 additions & 0 deletions packages/web-platform/web-core-server/src/createLynxView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
I18nResources,
inShadowRootStyles,
lynxUniqueIdAttribute,
type InitI18nResources,
type StartMainThreadContextConfig,
} from '@lynx-js/web-constants';
import { Rpc } from '@lynx-js/web-worker-rpc';
Expand Down Expand Up @@ -111,6 +113,7 @@ export async function createLynxView(
onCommit: () => {
},
});
const i18nResources = new I18nResources();
const { startMainThread } = prepareMainThreadAPIs(
backgroundThreadRpc,
offscreenDocument,
Expand All @@ -127,6 +130,10 @@ export async function createLynxView(
() => {
// trigger i18n resource fallback
},
(initI18nResources: InitI18nResources) => {
i18nResources.setData(initI18nResources);
return i18nResources;
},
);
const runtime = await startMainThread({
template,
Expand Down
9 changes: 9 additions & 0 deletions packages/web-platform/web-core/src/apis/LynxView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@ export class LynxView extends HTMLElement {
}
}

/**
* @public
* @method
* update the `__initData` and trigger essential flow
*/
updateI18nResources(data: InitI18nResources) {
this.#instance?.updateI18nResources(data as Cloneable);
}

#overrideLynxTagToHTMLTagMap: Record<string, string> = { 'page': 'div' };
/**
* @public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface LynxView {
dispose(): Promise<void>;
sendGlobalEvent: RpcCallType<typeof sendGlobalEventEndpoint>;
updateGlobalProps: (data: Cloneable) => void;
updateI18nResources: (data: Cloneable) => void;
}

export function createLynxView(configs: LynxViewConfigs): LynxView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
type I18nResourceTranslationOptions,
type CloneableObject,
i18nResourceMissedEventName,
I18nResources,
type InitI18nResources,
type Cloneable,
} from '@lynx-js/web-constants';
import { Rpc } from '@lynx-js/web-worker-rpc';
import { dispatchLynxViewEvent } from '../utils/dispatchLynxViewEvent.js';
Expand Down Expand Up @@ -38,6 +41,7 @@ export function createRenderAllOnUI(
options as CloneableObject,
);
};
const i18nResources = new I18nResources();
const { startMainThread } = prepareMainThreadAPIs(
mainToBackgroundRpc,
shadowRoot,
Expand All @@ -48,6 +52,10 @@ export function createRenderAllOnUI(
callbacks.onError?.(err);
},
triggerI18nResourceFallback,
(initI18nResources: InitI18nResources) => {
i18nResources.setData(initI18nResources);
return i18nResources;
},
);
let mtsGlobalThis!: MainThreadGlobalThis;
const start = async (configs: StartMainThreadContextConfig) => {
Expand All @@ -59,8 +67,12 @@ export function createRenderAllOnUI(
) => {
mtsGlobalThis.updatePage?.(...args);
};
const updateI18nResourcesMainThread = (data: Cloneable) => {
i18nResources.setData(data as InitI18nResources);
};
return {
start,
updateDataMainThread,
updateI18nResourcesMainThread,
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
mainThreadStartEndpoint,
updateDataEndpoint,
updateI18nResourcesEndpoint,
} from '@lynx-js/web-constants';
import type { Rpc } from '@lynx-js/web-worker-rpc';
import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
Expand All @@ -27,8 +28,12 @@ export function createRenderMultiThread(
registerDispatchLynxViewEventHandler(mainThreadRpc, shadowRoot);
const start = mainThreadRpc.createCall(mainThreadStartEndpoint);
const updateDataMainThread = mainThreadRpc.createCall(updateDataEndpoint);
const updateI18nResourcesMainThread = mainThreadRpc.createCall(
updateI18nResourcesEndpoint,
);
return {
start,
updateDataMainThread,
updateI18nResourcesMainThread,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
type NapiModulesCall,
type NativeModulesCall,
updateGlobalPropsEndpoint,
type Cloneable,
} from '@lynx-js/web-constants';
import { loadTemplate } from '../utils/loadTemplate.js';
import { createUpdateData } from './crossThreadHandlers/createUpdateData.js';
Expand Down Expand Up @@ -53,7 +54,7 @@ export function startUIThread(
if (!timeStamp) timeStamp = performance.now() + performance.timeOrigin;
markTiming(timingKey, pipelineId, timeStamp);
};
const { start, updateDataMainThread } = allOnUI
const { start, updateDataMainThread, updateI18nResourcesMainThread } = allOnUI
? createRenderAllOnUI(
/* main-to-bg rpc*/ mainThreadRpc,
shadowRoot,
Expand Down Expand Up @@ -82,5 +83,7 @@ export function startUIThread(
),
sendGlobalEvent,
updateGlobalProps: backgroundRpc.createCall(updateGlobalPropsEndpoint),
updateI18nResources: (data: Cloneable) =>
updateI18nResourcesMainThread(data),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
switchExposureServiceEndpoint,
type I18nResourceTranslationOptions,
getCacheI18nResourcesKey,
type InitI18nResources,
type I18nResources,
} from '@lynx-js/web-constants';
import { registerCallLepusMethodHandler } from './crossThreadHandlers/registerCallLepusMethodHandler.js';
import { registerGetCustomSectionHandler } from './crossThreadHandlers/registerGetCustomSectionHandler.js';
Expand All @@ -37,6 +39,7 @@ export function prepareMainThreadAPIs(
triggerI18nResourceFallback: (
options: I18nResourceTranslationOptions,
) => void,
initialI18nResources: (data: InitI18nResources) => I18nResources,
) {
const postTimingFlags = backgroundThreadRpc.createCall(
postTimingFlagsEndpoint,
Expand Down Expand Up @@ -90,6 +93,7 @@ export function prepareMainThreadAPIs(
receiveEventEndpoint: dispatchJSContextOnMainThreadEndpoint,
sendEventEndpoint: dispatchCoreContextOnBackgroundEndpoint,
});
const i18nResources = initialI18nResources(initI18nResources);
const mtsGlobalThis = createMainThreadGlobalThis({
jsContext,
tagMap,
Expand Down Expand Up @@ -140,7 +144,6 @@ export function prepareMainThreadAPIs(
nativeModulesMap,
napiModulesMap,
browserConfig,
initI18nResources,
});
mtsGlobalThis.renderPage!(initData);
mtsGlobalThis.__FlushElementTree(undefined, {});
Expand Down Expand Up @@ -182,7 +185,7 @@ export function prepareMainThreadAPIs(
publicComponentEvent,
createElement,
_I18nResourceTranslation: (options: I18nResourceTranslationOptions) => {
const matchedInitI18nResources = initI18nResources.find(i =>
const matchedInitI18nResources = i18nResources.data?.find(i =>
getCacheI18nResourcesKey(i.options)
=== getCacheI18nResourcesKey(options)
);
Expand Down
61 changes: 61 additions & 0 deletions packages/web-platform/web-tests/tests/web-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,65 @@ test.describe('web core tests', () => {
await wait(2000);
expect(success).toBeTruthy();
});
test('api-update-i18n-resources', async ({ page, browserName }) => {
// firefox dose not support this.
test.skip(browserName === 'firefox');
await goto(page);
const mainWorker = await getMainThreadWorker(page);
const first = await mainWorker.evaluate(() => {
globalThis.runtime.renderPage = () => {};
if (
globalThis.runtime._I18nResourceTranslation({
locale: 'en',
channel: '2',
fallback_url: '',
}) === undefined
) {
return true;
}
});
await wait(500);
await page.evaluate(() => {
document.querySelector('lynx-view').updateI18nResources([
{
options: {
locale: 'en',
channel: '1',
fallback_url: '',
},
resource: {
hello: 'hello',
lynx: 'lynx web platform1',
},
},
{
options: {
locale: 'en',
channel: '2',
fallback_url: '',
},
resource: {
hello: 'hello',
lynx: 'lynx web platform2',
},
},
]);
});
await wait(500);
const second = await mainWorker.evaluate(() => {
globalThis.runtime.renderPage = () => {};
if (
JSON.stringify(globalThis.runtime._I18nResourceTranslation({
locale: 'en',
channel: '2',
fallback_url: '',
})) === '{"hello":"hello","lynx":"lynx web platform2"}'
) {
return true;
}
});
await wait(500);
expect(first).toBeTruthy();
expect(second).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
dispatchLynxViewEventEndpoint,
type CloneableObject,
i18nResourceMissedEventName,
I18nResources,
type InitI18nResources,
updateI18nResourcesEndpoint,
} from '@lynx-js/web-constants';
import { Rpc } from '@lynx-js/web-worker-rpc';
import { createMarkTimingInternal } from './crossThreadHandlers/createMainthreadMarkTimingInternal.js';
Expand Down Expand Up @@ -39,6 +42,7 @@ export function startMainThreadWorker(
const docu = new OffscreenDocument({
onCommit: uiFlush,
});
const i18nResources = new I18nResources();
uiThreadRpc.registerHandler(postOffscreenEventEndpoint, docu[_onEvent]);
const { startMainThread } = prepareMainThreadAPIs(
backgroundThreadRpc,
Expand All @@ -48,6 +52,10 @@ export function startMainThreadWorker(
markTimingInternal,
reportError,
triggerI18nResourceFallback,
(initI18nResources: InitI18nResources) => {
i18nResources.setData(initI18nResources);
return i18nResources;
},
);
uiThreadRpc.registerHandler(
mainThreadStartEndpoint,
Expand All @@ -57,4 +65,7 @@ export function startMainThreadWorker(
});
},
);
uiThreadRpc?.registerHandler(updateI18nResourcesEndpoint, data => {
i18nResources.setData(data as InitI18nResources);
});
}
Loading