@lynx-js/web-core 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/dist/uiThread/createRenderAllOnUI.d.ts +3 -4
- package/dist/uiThread/createRenderAllOnUI.js +30 -19
- package/dist/uiThread/createRenderMultiThread.d.ts +3 -3
- package/dist/uiThread/createRenderMultiThread.js +3 -2
- package/dist/uiThread/startUIThread.d.ts +2 -2
- package/dist/uiThread/startUIThread.js +5 -6
- package/dist/utils/loadTemplate.d.ts +2 -2
- package/dist/utils/loadTemplate.js +36 -18
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# @lynx-js/web-core
|
|
2
2
|
|
|
3
|
+
## 0.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- break(web): temporary remove support for chunk split ([#1739](https://github.com/lynx-family/lynx-stack/pull/1739))
|
|
8
|
+
|
|
9
|
+
Since the global variables cannot be accessed in the splited chunk, we temporary remove supporting for chunk spliting
|
|
10
|
+
|
|
11
|
+
Developers could easily remove the chunk Split settings in Rspeedy for migration
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
import { defineConfig } from '@lynx-js/rspeedy'
|
|
15
|
+
|
|
16
|
+
export default defineConfig({
|
|
17
|
+
performance: {
|
|
18
|
+
chunkSplit: {
|
|
19
|
+
strategy: 'all-in-one',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
})
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- fix: lazy component load error ([#1794](https://github.com/lynx-family/lynx-stack/pull/1794))
|
|
28
|
+
|
|
29
|
+
Some special version template may have chunk loading error. We fixed it.
|
|
30
|
+
|
|
31
|
+
- fix: avoid duplicate style transformation ([#1748](https://github.com/lynx-family/lynx-stack/pull/1748))
|
|
32
|
+
|
|
33
|
+
After this commit, we use DAG methods to handle the styleInfos
|
|
34
|
+
|
|
35
|
+
- fix: add sandbox attribute to iframe for enhanced security ([#1709](https://github.com/lynx-family/lynx-stack/pull/1709))
|
|
36
|
+
|
|
37
|
+
- fix: the default template loader won't fetch twice for one url ([#1709](https://github.com/lynx-family/lynx-stack/pull/1709))
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [[`721635d`](https://github.com/lynx-family/lynx-stack/commit/721635de6c1d2d617c7cbaa86e7d816c42d62930), [`93d707b`](https://github.com/lynx-family/lynx-stack/commit/93d707b82a59f7256952e21da6dcad2999f8233d), [`d150ed4`](https://github.com/lynx-family/lynx-stack/commit/d150ed440a4f1e9d9a3a2911adf6e6fa39a0c589)]:
|
|
40
|
+
- @lynx-js/web-mainthread-apis@0.17.0
|
|
41
|
+
- @lynx-js/web-constants@0.17.0
|
|
42
|
+
- @lynx-js/web-worker-runtime@0.17.0
|
|
43
|
+
- @lynx-js/web-worker-rpc@0.17.0
|
|
44
|
+
|
|
45
|
+
## 0.16.1
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- refactor: improve chunk loading ([#1703](https://github.com/lynx-family/lynx-stack/pull/1703))
|
|
50
|
+
|
|
51
|
+
- feat: supports lazy bundle. (This feature requires `@lynx-js/lynx-core >= 0.1.3`) ([#1235](https://github.com/lynx-family/lynx-stack/pull/1235))
|
|
52
|
+
|
|
53
|
+
- Updated dependencies [[`608f375`](https://github.com/lynx-family/lynx-stack/commit/608f375e20732cc4c9f141bfbf9800ba6896100b)]:
|
|
54
|
+
- @lynx-js/web-mainthread-apis@0.16.1
|
|
55
|
+
- @lynx-js/web-worker-runtime@0.16.1
|
|
56
|
+
- @lynx-js/web-constants@0.16.1
|
|
57
|
+
- @lynx-js/web-worker-rpc@0.16.1
|
|
58
|
+
|
|
3
59
|
## 0.16.0
|
|
4
60
|
|
|
5
61
|
### Minor Changes
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { type StartMainThreadContextConfig, type Cloneable, type SSRDumpInfo } from '@lynx-js/web-constants';
|
|
1
|
+
import { type StartMainThreadContextConfig, type Cloneable, type SSRDumpInfo, type TemplateLoader } from '@lynx-js/web-constants';
|
|
2
2
|
import { Rpc } from '@lynx-js/web-worker-rpc';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}, ssrDumpInfo: SSRDumpInfo | undefined): {
|
|
3
|
+
import type { StartUIThreadCallbacks } from './startUIThread.js';
|
|
4
|
+
export declare function createRenderAllOnUI(mainToBackgroundRpc: Rpc, shadowRoot: ShadowRoot, loadTemplate: TemplateLoader, markTimingInternal: (timingKey: string, pipelineId?: string, timeStamp?: number) => void, flushMarkTimingInternal: () => void, callbacks: StartUIThreadCallbacks, ssrDumpInfo: SSRDumpInfo | undefined): {
|
|
6
5
|
start: (configs: StartMainThreadContextConfig) => Promise<void>;
|
|
7
6
|
updateDataMainThread: (args_0: Cloneable, args_1: Record<string, string>) => Promise<void>;
|
|
8
7
|
updateI18nResourcesMainThread: (data: Cloneable) => void;
|
|
@@ -18,29 +18,37 @@ const { prepareMainThreadAPIs, } = await import(
|
|
|
18
18
|
*/
|
|
19
19
|
function createIFrameRealm(parent) {
|
|
20
20
|
const iframe = document.createElement('iframe');
|
|
21
|
-
const iframeLoaded = new Promise((resolve) => {
|
|
22
|
-
iframe.onload = () => resolve();
|
|
23
|
-
});
|
|
24
21
|
iframe.style.display = 'none';
|
|
25
|
-
iframe.
|
|
22
|
+
iframe.srcdoc =
|
|
23
|
+
'<!DOCTYPE html><html><head></head><body style="display:none"></body></html>';
|
|
24
|
+
iframe.sandbox = 'allow-same-origin allow-scripts'; // Restrict capabilities for security
|
|
25
|
+
iframe.loading = 'eager';
|
|
26
26
|
parent.appendChild(iframe);
|
|
27
27
|
const iframeWindow = iframe.contentWindow;
|
|
28
|
-
const
|
|
29
|
-
|
|
28
|
+
const loadScript = async (url) => {
|
|
29
|
+
const script = iframe.contentDocument.createElement('script');
|
|
30
|
+
script.fetchPriority = 'high';
|
|
31
|
+
script.defer = true;
|
|
32
|
+
script.async = false;
|
|
33
|
+
if (!iframe.contentDocument.head) {
|
|
34
|
+
await new Promise((resolve) => {
|
|
35
|
+
iframe.onload = () => resolve();
|
|
36
|
+
// In case iframe is already loaded, wait a macro task
|
|
37
|
+
setTimeout(() => resolve(), 0);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
iframe.contentDocument.head.appendChild(script);
|
|
30
41
|
return new Promise(async (resolve, reject) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
script.defer = true;
|
|
38
|
-
script.async = false;
|
|
39
|
-
script.onload = () => resolve(iframeWindow?.module?.exports);
|
|
42
|
+
script.onload = () => {
|
|
43
|
+
const ret = iframeWindow?.module?.exports;
|
|
44
|
+
// @ts-expect-error
|
|
45
|
+
iframeWindow.module = { exports: undefined };
|
|
46
|
+
resolve(ret);
|
|
47
|
+
};
|
|
40
48
|
script.onerror = (err) => reject(new Error(`Failed to load script: ${url}`, { cause: err }));
|
|
41
49
|
// @ts-expect-error
|
|
42
50
|
iframeWindow.module = { exports: undefined };
|
|
43
|
-
|
|
51
|
+
script.src = url;
|
|
44
52
|
});
|
|
45
53
|
};
|
|
46
54
|
const loadScriptSync = (url) => {
|
|
@@ -53,7 +61,10 @@ function createIFrameRealm(parent) {
|
|
|
53
61
|
// @ts-expect-error
|
|
54
62
|
iframeWindow.module = { exports: undefined };
|
|
55
63
|
iframe.contentDocument.head.appendChild(script);
|
|
56
|
-
|
|
64
|
+
const ret = iframeWindow?.module?.exports;
|
|
65
|
+
// @ts-expect-error
|
|
66
|
+
iframeWindow.module = { exports: undefined };
|
|
67
|
+
return ret;
|
|
57
68
|
}
|
|
58
69
|
else {
|
|
59
70
|
throw new Error(`Failed to load script: ${url}`, { cause: xhr });
|
|
@@ -61,7 +72,7 @@ function createIFrameRealm(parent) {
|
|
|
61
72
|
};
|
|
62
73
|
return { globalWindow: iframeWindow, loadScript, loadScriptSync };
|
|
63
74
|
}
|
|
64
|
-
export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, markTimingInternal, flushMarkTimingInternal, callbacks, ssrDumpInfo) {
|
|
75
|
+
export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, loadTemplate, markTimingInternal, flushMarkTimingInternal, callbacks, ssrDumpInfo) {
|
|
65
76
|
if (!globalThis.module) {
|
|
66
77
|
Object.assign(globalThis, { module: {} });
|
|
67
78
|
}
|
|
@@ -77,7 +88,7 @@ export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, markTimingI
|
|
|
77
88
|
}, triggerI18nResourceFallback, (initI18nResources) => {
|
|
78
89
|
i18nResources.setData(initI18nResources);
|
|
79
90
|
return i18nResources;
|
|
80
|
-
});
|
|
91
|
+
}, loadTemplate);
|
|
81
92
|
const pendingUpdateCalls = [];
|
|
82
93
|
const start = async (configs) => {
|
|
83
94
|
if (ssrDumpInfo) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { type TemplateLoader } from '@lynx-js/web-constants';
|
|
1
2
|
import type { Rpc } from '@lynx-js/web-worker-rpc';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}): {
|
|
3
|
+
import type { StartUIThreadCallbacks } from './startUIThread.js';
|
|
4
|
+
export declare function createRenderMultiThread(mainThreadRpc: Rpc, shadowRoot: ShadowRoot, loadTemplate: TemplateLoader, callbacks: StartUIThreadCallbacks): {
|
|
5
5
|
start: (args_0: import("@lynx-js/web-constants").StartMainThreadContextConfig) => void;
|
|
6
6
|
updateDataMainThread: (args_0: import("@lynx-js/web-constants").Cloneable, args_1: Record<string, string>) => Promise<void>;
|
|
7
7
|
updateI18nResourcesMainThread: (args_0: import("@lynx-js/web-constants").Cloneable) => void;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
// Copyright 2023 The Lynx Authors. All rights reserved.
|
|
2
2
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
3
3
|
// LICENSE file in the root directory of this source tree.
|
|
4
|
-
import { mainThreadStartEndpoint, updateDataEndpoint, updateI18nResourcesEndpoint, } from '@lynx-js/web-constants';
|
|
4
|
+
import { loadTemplateMultiThread, mainThreadStartEndpoint, updateDataEndpoint, updateI18nResourcesEndpoint, } from '@lynx-js/web-constants';
|
|
5
5
|
import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
|
|
6
6
|
import { registerFlushElementTreeHandler } from './crossThreadHandlers/registerFlushElementTreeHandler.js';
|
|
7
7
|
import { registerDispatchLynxViewEventHandler } from './crossThreadHandlers/registerDispatchLynxViewEventHandler.js';
|
|
8
8
|
import { createExposureMonitorForMultiThread } from './crossThreadHandlers/createExposureMonitor.js';
|
|
9
|
-
export function createRenderMultiThread(mainThreadRpc, shadowRoot, callbacks) {
|
|
9
|
+
export function createRenderMultiThread(mainThreadRpc, shadowRoot, loadTemplate, callbacks) {
|
|
10
10
|
registerReportErrorHandler(mainThreadRpc, 'lepus.js', callbacks.onError);
|
|
11
11
|
registerFlushElementTreeHandler(mainThreadRpc, { shadowRoot });
|
|
12
12
|
registerDispatchLynxViewEventHandler(mainThreadRpc, shadowRoot);
|
|
13
13
|
createExposureMonitorForMultiThread(mainThreadRpc, shadowRoot);
|
|
14
|
+
mainThreadRpc.registerHandler(loadTemplateMultiThread, loadTemplate);
|
|
14
15
|
const start = mainThreadRpc.createCall(mainThreadStartEndpoint);
|
|
15
16
|
const updateDataMainThread = mainThreadRpc.createCall(updateDataEndpoint);
|
|
16
17
|
const updateI18nResourcesMainThread = mainThreadRpc.createCall(updateI18nResourcesEndpoint);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { LynxView } from '../apis/createLynxView.js';
|
|
2
|
-
import { type
|
|
2
|
+
import { type StartMainThreadContextConfig, type NapiModulesCall, type NativeModulesCall, type SSRDumpInfo, type TemplateLoader } from '@lynx-js/web-constants';
|
|
3
3
|
export type StartUIThreadCallbacks = {
|
|
4
4
|
nativeModulesCall: NativeModulesCall;
|
|
5
5
|
napiModulesCall: NapiModulesCall;
|
|
6
6
|
onError?: (err: Error, release: string, fileName: string) => void;
|
|
7
|
-
customTemplateLoader?:
|
|
7
|
+
customTemplateLoader?: TemplateLoader;
|
|
8
8
|
};
|
|
9
9
|
export declare function startUIThread(templateUrl: string, configs: Omit<StartMainThreadContextConfig, 'template'>, shadowRoot: ShadowRoot, lynxGroupId: number | undefined, threadStrategy: 'all-on-ui' | 'multi-thread', callbacks: StartUIThreadCallbacks, ssr?: SSRDumpInfo): LynxView;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { bootWorkers } from './bootWorkers.js';
|
|
5
5
|
import { createDispose } from './crossThreadHandlers/createDispose.js';
|
|
6
6
|
import { updateGlobalPropsEndpoint, dispatchMarkTiming, flushMarkTiming, } from '@lynx-js/web-constants';
|
|
7
|
-
import {
|
|
7
|
+
import { createTemplateLoader } from '../utils/loadTemplate.js';
|
|
8
8
|
import { createUpdateData } from './crossThreadHandlers/createUpdateData.js';
|
|
9
9
|
import { startBackground } from './startBackground.js';
|
|
10
10
|
import { createRenderMultiThread } from './createRenderMultiThread.js';
|
|
@@ -28,15 +28,14 @@ export function startUIThread(templateUrl, configs, shadowRoot, lynxGroupId, thr
|
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
30
|
const flushMarkTimingInternal = () => flushMarkTiming(markTiming, cacheMarkTimings);
|
|
31
|
+
const templateLoader = createTemplateLoader(callbacks.customTemplateLoader, markTimingInternal);
|
|
31
32
|
const { start, updateDataMainThread, updateI18nResourcesMainThread } = allOnUI
|
|
32
33
|
? createRenderAllOnUI(
|
|
33
|
-
/* main-to-bg rpc*/ mainThreadRpc, shadowRoot, markTimingInternal, flushMarkTimingInternal, callbacks, ssr)
|
|
34
|
+
/* main-to-bg rpc*/ mainThreadRpc, shadowRoot, templateLoader, markTimingInternal, flushMarkTimingInternal, callbacks, ssr)
|
|
34
35
|
: createRenderMultiThread(
|
|
35
|
-
/* main-to-ui rpc*/ mainThreadRpc, shadowRoot, callbacks);
|
|
36
|
+
/* main-to-ui rpc*/ mainThreadRpc, shadowRoot, templateLoader, callbacks);
|
|
36
37
|
markTimingInternal('create_lynx_start', undefined, createLynxStartTiming);
|
|
37
|
-
|
|
38
|
-
loadTemplate(templateUrl, callbacks.customTemplateLoader).then((template) => {
|
|
39
|
-
markTimingInternal('load_template_end');
|
|
38
|
+
templateLoader(templateUrl).then((template) => {
|
|
40
39
|
flushMarkTimingInternal();
|
|
41
40
|
start({
|
|
42
41
|
...configs,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export declare function
|
|
1
|
+
import { type MarkTimingInternal, type TemplateLoader } from '@lynx-js/web-constants';
|
|
2
|
+
export declare function createTemplateLoader(customTemplateLoader: TemplateLoader | undefined, markTimingInternal: MarkTimingInternal): TemplateLoader;
|
|
@@ -1,23 +1,41 @@
|
|
|
1
|
-
import { generateTemplate } from '@lynx-js/web-constants';
|
|
2
|
-
const templateCache =
|
|
1
|
+
import { generateTemplate, } from '@lynx-js/web-constants';
|
|
2
|
+
const templateCache = new Map();
|
|
3
3
|
function createJsModuleUrl(content) {
|
|
4
4
|
return URL.createObjectURL(new Blob([content], { type: 'text/javascript' }));
|
|
5
5
|
}
|
|
6
|
-
export
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
export function createTemplateLoader(customTemplateLoader, markTimingInternal) {
|
|
7
|
+
const loadTemplate = async (url) => {
|
|
8
|
+
markTimingInternal('load_template_start');
|
|
9
|
+
const cachedTemplate = templateCache.get(url);
|
|
10
|
+
if (cachedTemplate) {
|
|
11
|
+
markTimingInternal('load_template_end');
|
|
12
|
+
return cachedTemplate;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
16
|
+
try {
|
|
17
|
+
const template = customTemplateLoader
|
|
18
|
+
? await customTemplateLoader(url)
|
|
19
|
+
: (await (await fetch(url, {
|
|
20
|
+
method: 'GET',
|
|
21
|
+
})).json());
|
|
22
|
+
const decodedTemplate = await generateTemplate(template, createJsModuleUrl);
|
|
23
|
+
resolve(decodedTemplate);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
templateCache.delete(url);
|
|
27
|
+
reject(e);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
templateCache.set(url, promise);
|
|
31
|
+
/**
|
|
32
|
+
* This will cause a memory leak, which is expected.
|
|
33
|
+
* We cannot ensure that the `URL.createObjectURL` created url will never be used, therefore here we keep it for the entire lifetime of this page.
|
|
34
|
+
*/
|
|
35
|
+
markTimingInternal('load_template_end');
|
|
36
|
+
return promise;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return loadTemplate;
|
|
22
40
|
}
|
|
23
41
|
//# sourceMappingURL=loadTemplate.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynx-js/web-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"keywords": [],
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@lynx-js/offscreen-document": "0.1.4",
|
|
28
|
-
"@lynx-js/web-constants": "0.
|
|
29
|
-
"@lynx-js/web-mainthread-apis": "0.
|
|
30
|
-
"@lynx-js/web-worker-rpc": "0.
|
|
31
|
-
"@lynx-js/web-worker-runtime": "0.
|
|
28
|
+
"@lynx-js/web-constants": "0.17.0",
|
|
29
|
+
"@lynx-js/web-mainthread-apis": "0.17.0",
|
|
30
|
+
"@lynx-js/web-worker-rpc": "0.17.0",
|
|
31
|
+
"@lynx-js/web-worker-runtime": "0.17.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@lynx-js/lynx-core": "0.1.3",
|
|
35
|
-
"@lynx-js/web-elements": "0.8.
|
|
35
|
+
"@lynx-js/web-elements": "0.8.7"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@lynx-js/lynx-core": "0.1.3",
|