@lynx-js/web-core 0.14.0 → 0.14.2

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @lynx-js/web-core
2
2
 
3
+ ## 0.14.2
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: merge multiple markTiming RPC communication events together and send them together, which can effectively reduce the number of RPC communications. ([#1178](https://github.com/lynx-family/lynx-stack/pull/1178))
8
+
9
+ - chore: extract shared logic from web-core and web-core-server's loadTemplate into a unified generateTemplate function ([#1211](https://github.com/lynx-family/lynx-stack/pull/1211))
10
+
11
+ - Updated dependencies [[`e44b146`](https://github.com/lynx-family/lynx-stack/commit/e44b146b1bc2b58c0347af7fb4e4157688e07e36), [`5a9b38b`](https://github.com/lynx-family/lynx-stack/commit/5a9b38b783e611aa9761c4cd52191172270c09c7), [`6ca5b91`](https://github.com/lynx-family/lynx-stack/commit/6ca5b9106aade393dfac88914b160960a61a82f2)]:
12
+ - @lynx-js/web-mainthread-apis@0.14.2
13
+ - @lynx-js/web-worker-runtime@0.14.2
14
+ - @lynx-js/web-constants@0.14.2
15
+ - @lynx-js/web-worker-rpc@0.14.2
16
+
17
+ ## 0.14.1
18
+
19
+ ### Patch Changes
20
+
21
+ - feat: support BTS API `lynx.reportError` && `__SetSourceMapRelease`, now you can use it and handle it in lynx-view error event. ([#1059](https://github.com/lynx-family/lynx-stack/pull/1059))
22
+
23
+ - fix: under the all-on-ui strategy, reload() will add two page elements. ([#1147](https://github.com/lynx-family/lynx-stack/pull/1147))
24
+
25
+ - Updated dependencies [[`a64333e`](https://github.com/lynx-family/lynx-stack/commit/a64333ef28228d6b90c32e027f67bef8acbd8432), [`7751375`](https://github.com/lynx-family/lynx-stack/commit/775137521782ca5445f22029c39163c0a63bbfa5), [`b52a924`](https://github.com/lynx-family/lynx-stack/commit/b52a924a2375cb6f7ebafdd8abfbab0254eb2330)]:
26
+ - @lynx-js/web-worker-runtime@0.14.1
27
+ - @lynx-js/web-constants@0.14.1
28
+ - @lynx-js/web-mainthread-apis@0.14.1
29
+ - @lynx-js/web-worker-rpc@0.14.1
30
+
3
31
  ## 0.14.0
4
32
 
5
33
  ### Minor Changes
@@ -2,7 +2,7 @@
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
4
  import { createLynxView, } from './createLynxView.js';
5
- import { inShadowRootStyles, } from '@lynx-js/web-constants';
5
+ import { inShadowRootStyles, lynxDisposedAttribute, lynxTagAttribute, } from '@lynx-js/web-constants';
6
6
  /**
7
7
  * Based on our experiences, these elements are almost used in all lynx cards.
8
8
  */
@@ -315,6 +315,10 @@ export class LynxView extends HTMLElement {
315
315
  disconnectedCallback() {
316
316
  this.#instance?.dispose();
317
317
  this.#instance = undefined;
318
+ // under the all-on-ui strategy, when reload() triggers dsl flush, the previously removed pageElement will be used in __FlushElementTree.
319
+ // This attribute is added to filter this issue.
320
+ this.shadowRoot?.querySelector(`[${lynxTagAttribute}="page"]`)
321
+ ?.setAttribute(lynxDisposedAttribute, '');
318
322
  if (this.shadowRoot) {
319
323
  this.shadowRoot.innerHTML = '';
320
324
  }
@@ -1,6 +1,6 @@
1
1
  import { type StartMainThreadContextConfig, type Cloneable } from '@lynx-js/web-constants';
2
2
  import { Rpc } from '@lynx-js/web-worker-rpc';
3
- export declare function createRenderAllOnUI(mainToBackgroundRpc: Rpc, shadowRoot: ShadowRoot, markTimingInternal: (timingKey: string, pipelineId?: string, timeStamp?: number) => void, callbacks: {
3
+ export declare function createRenderAllOnUI(mainToBackgroundRpc: Rpc, shadowRoot: ShadowRoot, markTimingInternal: (timingKey: string, pipelineId?: string, timeStamp?: number) => void, flushMarkTimingInternal: () => void, callbacks: {
4
4
  onError?: (err: Error, release: string) => void;
5
5
  }): {
6
6
  start: (configs: StartMainThreadContextConfig) => Promise<void>;
@@ -2,7 +2,7 @@ import { i18nResourceMissedEventName, I18nResources, } from '@lynx-js/web-consta
2
2
  import { Rpc } from '@lynx-js/web-worker-rpc';
3
3
  import { dispatchLynxViewEvent } from '../utils/dispatchLynxViewEvent.js';
4
4
  const { prepareMainThreadAPIs, } = await import('@lynx-js/web-mainthread-apis');
5
- export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, markTimingInternal, callbacks) {
5
+ export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, markTimingInternal, flushMarkTimingInternal, callbacks) {
6
6
  if (!globalThis.module) {
7
7
  Object.assign(globalThis, { module: {} });
8
8
  }
@@ -10,7 +10,7 @@ export function createRenderAllOnUI(mainToBackgroundRpc, shadowRoot, markTimingI
10
10
  dispatchLynxViewEvent(shadowRoot, i18nResourceMissedEventName, options);
11
11
  };
12
12
  const i18nResources = new I18nResources();
13
- const { startMainThread } = prepareMainThreadAPIs(mainToBackgroundRpc, shadowRoot, document.createElement.bind(document), () => { }, markTimingInternal, (err, _, release) => {
13
+ const { startMainThread } = prepareMainThreadAPIs(mainToBackgroundRpc, shadowRoot, document.createElement.bind(document), () => { }, markTimingInternal, flushMarkTimingInternal, (err, _, release) => {
14
14
  callbacks.onError?.(err, release);
15
15
  }, triggerI18nResourceFallback, (initI18nResources) => {
16
16
  i18nResources.setData(initI18nResources);
@@ -1,11 +1,9 @@
1
- import { type Cloneable, type I18nResourceTranslationOptions, type InitI18nResources, type NapiModulesCall, type NativeModulesCall } from '@lynx-js/web-constants';
1
+ import { type Cloneable, type I18nResourceTranslationOptions, type InitI18nResources } from '@lynx-js/web-constants';
2
2
  import type { Rpc } from '@lynx-js/web-worker-rpc';
3
- export declare function startBackground(backgroundRpc: Rpc, shadowRoot: ShadowRoot, callbacks: {
4
- nativeModulesCall: NativeModulesCall;
5
- napiModulesCall: NapiModulesCall;
6
- }): {
3
+ import type { StartUIThreadCallbacks } from './startUIThread.js';
4
+ export declare function startBackground(backgroundRpc: Rpc, shadowRoot: ShadowRoot, callbacks: StartUIThreadCallbacks): {
7
5
  sendGlobalEvent: (args_0: string, args_1: Cloneable[] | undefined) => void;
8
- markTiming: (timingKey: string, pipelineId: string | undefined, timeStamp: number) => void;
6
+ markTiming: (args_0: import("@lynx-js/web-constants").MarkTiming[]) => void;
9
7
  updateDataBackground: (args_0: Cloneable, args_1: Record<string, string>) => Promise<void>;
10
8
  updateI18nResourceBackground: (data: InitI18nResources, options: I18nResourceTranslationOptions) => void;
11
9
  };
@@ -7,6 +7,7 @@ import { registerSelectComponentHandler } from './crossThreadHandlers/registerSe
7
7
  import { registerNapiModulesCallHandler } from './crossThreadHandlers/registerNapiModulesCallHandler.js';
8
8
  import { registerDispatchLynxViewEventHandler } from './crossThreadHandlers/registerDispatchLynxViewEventHandler.js';
9
9
  import { registerTriggerElementMethodEndpointHandler } from './crossThreadHandlers/registerTriggerElementMethodEndpointHandler.js';
10
+ import { registerReportErrorHandler } from './crossThreadHandlers/registerReportErrorHandler.js';
10
11
  export function startBackground(backgroundRpc, shadowRoot, callbacks) {
11
12
  registerInvokeUIMethodHandler(backgroundRpc, shadowRoot);
12
13
  registerNativePropsHandler(backgroundRpc, shadowRoot);
@@ -16,6 +17,7 @@ export function startBackground(backgroundRpc, shadowRoot, callbacks) {
16
17
  registerNapiModulesCallHandler(backgroundRpc, callbacks.napiModulesCall);
17
18
  registerDispatchLynxViewEventHandler(backgroundRpc, shadowRoot);
18
19
  registerTriggerElementMethodEndpointHandler(backgroundRpc, shadowRoot);
20
+ registerReportErrorHandler(backgroundRpc, callbacks.onError);
19
21
  const sendGlobalEvent = backgroundRpc.createCall(sendGlobalEventEndpoint);
20
22
  const markTiming = backgroundRpc.createCall(markTimingEndpoint);
21
23
  const updateDataBackground = backgroundRpc.createCall(updateDataEndpoint);
@@ -3,7 +3,7 @@
3
3
  // LICENSE file in the root directory of this source tree.
4
4
  import { bootWorkers } from './bootWorkers.js';
5
5
  import { createDispose } from './crossThreadHandlers/createDispose.js';
6
- import { updateGlobalPropsEndpoint, } from '@lynx-js/web-constants';
6
+ import { updateGlobalPropsEndpoint, dispatchMarkTiming, flushMarkTiming, } from '@lynx-js/web-constants';
7
7
  import { loadTemplate } from '../utils/loadTemplate.js';
8
8
  import { createUpdateData } from './crossThreadHandlers/createUpdateData.js';
9
9
  import { startBackground } from './startBackground.js';
@@ -14,20 +14,30 @@ export function startUIThread(templateUrl, configs, shadowRoot, lynxGroupId, thr
14
14
  const allOnUI = threadStrategy === 'all-on-ui';
15
15
  const { mainThreadRpc, backgroundRpc, terminateWorkers, } = bootWorkers(lynxGroupId, allOnUI);
16
16
  const { markTiming, sendGlobalEvent, updateDataBackground, updateI18nResourceBackground, } = startBackground(backgroundRpc, shadowRoot, callbacks);
17
+ const cacheMarkTimings = {
18
+ records: [],
19
+ timeout: null,
20
+ };
17
21
  const markTimingInternal = (timingKey, pipelineId, timeStamp) => {
18
- if (!timeStamp)
19
- timeStamp = performance.now() + performance.timeOrigin;
20
- markTiming(timingKey, pipelineId, timeStamp);
22
+ dispatchMarkTiming({
23
+ timingKey,
24
+ pipelineId,
25
+ timeStamp,
26
+ markTiming,
27
+ cacheMarkTimings,
28
+ });
21
29
  };
30
+ const flushMarkTimingInternal = () => flushMarkTiming(markTiming, cacheMarkTimings);
22
31
  const { start, updateDataMainThread, updateI18nResourcesMainThread } = allOnUI
23
32
  ? createRenderAllOnUI(
24
- /* main-to-bg rpc*/ mainThreadRpc, shadowRoot, markTimingInternal, callbacks)
33
+ /* main-to-bg rpc*/ mainThreadRpc, shadowRoot, markTimingInternal, flushMarkTimingInternal, callbacks)
25
34
  : createRenderMultiThread(
26
35
  /* main-to-ui rpc*/ mainThreadRpc, shadowRoot, callbacks);
27
36
  markTimingInternal('create_lynx_start', undefined, createLynxStartTiming);
28
37
  markTimingInternal('load_template_start');
29
38
  loadTemplate(templateUrl, callbacks.customTemplateLoader).then((template) => {
30
39
  markTimingInternal('load_template_end');
40
+ flushMarkTimingInternal();
31
41
  start({
32
42
  ...configs,
33
43
  template,
@@ -1,106 +1,10 @@
1
- import { globalMuteableVars } from '@lynx-js/web-constants';
2
- const TemplateCache = {};
1
+ import { generateTemplate } from '@lynx-js/web-constants';
2
+ const templateCache = {};
3
3
  function createJsModuleUrl(content) {
4
4
  return URL.createObjectURL(new Blob([content], { type: 'text/javascript' }));
5
5
  }
6
- function generateJavascriptUrl(obj, injectVars, injectWithBind, muteableVars) {
7
- injectVars = injectVars.concat(muteableVars);
8
- return Object.fromEntries(Object.entries(obj).map(([name, content]) => {
9
- return [
10
- name,
11
- createJsModuleUrl([
12
- '//# allFunctionsCalledOnLoad\n',
13
- 'globalThis.module.exports = function(lynx_runtime) {',
14
- 'const module= {exports:{}};let exports = module.exports;',
15
- 'var {',
16
- injectVars.join(','),
17
- '} = lynx_runtime;',
18
- ...injectWithBind.map((nm) => `const ${nm} = lynx_runtime.${nm}?.bind(lynx_runtime);`),
19
- ';var globDynamicComponentEntry = \'__Card__\';',
20
- 'var {__globalProps} = lynx;',
21
- 'lynx_runtime._updateVars=()=>{',
22
- ...muteableVars.map((nm) => `${nm} = lynx_runtime.__lynxGlobalBindingValues.${nm};`),
23
- '};\n',
24
- content,
25
- '\n return module.exports;}',
26
- ].join('')),
27
- ];
28
- }));
29
- }
30
- const mainThreadInjectVars = [
31
- 'lynx',
32
- 'globalThis',
33
- '_ReportError',
34
- '_SetSourceMapRelease',
35
- '__AddConfig',
36
- '__AddDataset',
37
- '__GetAttributes',
38
- '__GetComponentID',
39
- '__GetDataByKey',
40
- '__GetDataset',
41
- '__GetElementConfig',
42
- '__GetElementUniqueID',
43
- '__GetID',
44
- '__GetTag',
45
- '__SetAttribute',
46
- '__SetConfig',
47
- '__SetDataset',
48
- '__SetID',
49
- '__UpdateComponentID',
50
- '__GetConfig',
51
- '__UpdateListCallbacks',
52
- '__AppendElement',
53
- '__ElementIsEqual',
54
- '__FirstElement',
55
- '__GetChildren',
56
- '__GetParent',
57
- '__InsertElementBefore',
58
- '__LastElement',
59
- '__NextElement',
60
- '__RemoveElement',
61
- '__ReplaceElement',
62
- '__ReplaceElements',
63
- '__SwapElement',
64
- '__CreateComponent',
65
- '__CreateElement',
66
- '__CreatePage',
67
- '__CreateView',
68
- '__CreateText',
69
- '__CreateRawText',
70
- '__CreateImage',
71
- '__CreateScrollView',
72
- '__CreateWrapperElement',
73
- '__CreateList',
74
- '__AddEvent',
75
- '__GetEvent',
76
- '__GetEvents',
77
- '__SetEvents',
78
- '__AddClass',
79
- '__SetClasses',
80
- '__GetClasses',
81
- '__AddInlineStyle',
82
- '__SetInlineStyles',
83
- '__SetCSSId',
84
- '__OnLifecycleEvent',
85
- '__FlushElementTree',
86
- '__LoadLepusChunk',
87
- 'SystemInfo',
88
- '_I18nResourceTranslation',
89
- '_AddEventListener',
90
- ];
91
- const backgroundInjectVars = [
92
- 'NativeModules',
93
- 'globalThis',
94
- 'lynx',
95
- 'lynxCoreInject',
96
- 'SystemInfo',
97
- ];
98
- const backgroundInjectWithBind = [
99
- 'Card',
100
- 'Component',
101
- ];
102
6
  export async function loadTemplate(url, customTemplateLoader) {
103
- const cachedTemplate = TemplateCache[url];
7
+ const cachedTemplate = templateCache[url];
104
8
  if (cachedTemplate)
105
9
  return cachedTemplate;
106
10
  const template = customTemplateLoader
@@ -108,12 +12,8 @@ export async function loadTemplate(url, customTemplateLoader) {
108
12
  : (await (await fetch(url, {
109
13
  method: 'GET',
110
14
  })).json());
111
- const decodedTemplate = {
112
- ...template,
113
- lepusCode: generateJavascriptUrl(template.lepusCode, mainThreadInjectVars, [], globalMuteableVars),
114
- manifest: generateJavascriptUrl(template.manifest, backgroundInjectVars, backgroundInjectWithBind, []),
115
- };
116
- TemplateCache[url] = decodedTemplate;
15
+ const decodedTemplate = await generateTemplate(template, createJsModuleUrl);
16
+ templateCache[url] = decodedTemplate;
117
17
  /**
118
18
  * This will cause a memory leak, which is expected.
119
19
  * 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-core",
3
- "version": "0.14.0",
3
+ "version": "0.14.2",
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.2",
28
- "@lynx-js/web-constants": "0.14.0",
29
- "@lynx-js/web-mainthread-apis": "0.14.0",
30
- "@lynx-js/web-worker-rpc": "0.14.0",
31
- "@lynx-js/web-worker-runtime": "0.14.0"
28
+ "@lynx-js/web-constants": "0.14.2",
29
+ "@lynx-js/web-mainthread-apis": "0.14.2",
30
+ "@lynx-js/web-worker-rpc": "0.14.2",
31
+ "@lynx-js/web-worker-runtime": "0.14.2"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@lynx-js/lynx-core": "0.1.2",
35
- "@lynx-js/web-elements": "0.7.6"
35
+ "@lynx-js/web-elements": "0.7.7"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@lynx-js/lynx-core": "0.1.2",