@lynx-js/web-mainthread-apis 0.15.1 → 0.15.3

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-mainthread-apis
2
2
 
3
+ ## 0.15.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`0da5ef0`](https://github.com/lynx-family/lynx-stack/commit/0da5ef03e41f20e9f8019c6dc03cb4a38ab18854)]:
8
+ - @lynx-js/web-constants@0.15.3
9
+
10
+ ## 0.15.2
11
+
12
+ ### Patch Changes
13
+
14
+ - feat: support SSR for all-on-ui ([#1029](https://github.com/lynx-family/lynx-stack/pull/1029))
15
+
16
+ - feat: move SSR hydrate essential info to the ssr attribute ([#1292](https://github.com/lynx-family/lynx-stack/pull/1292))
17
+
18
+ We found that in browser there is no simple tool to decode a base64 string
19
+
20
+ Therefore we move the data to `ssr` attribute
21
+
22
+ Also fix some ssr issues
23
+
24
+ - feat: support \_\_MarkTemplateElement, \_\_MarkPartElement and \_\_GetTemplateParts for all-on-ui ([#1275](https://github.com/lynx-family/lynx-stack/pull/1275))
25
+
26
+ - feat: mark template elements for SSR and update part ID handling ([#1286](https://github.com/lynx-family/lynx-stack/pull/1286))
27
+
28
+ - Updated dependencies [[`1443e46`](https://github.com/lynx-family/lynx-stack/commit/1443e468a353363e29aab0d90cd8b91c232a5525), [`5062128`](https://github.com/lynx-family/lynx-stack/commit/5062128c68e21abcf276ebcb40d7cc8f6e54244b)]:
29
+ - @lynx-js/web-constants@0.15.2
30
+
3
31
  ## 0.15.1
4
32
 
5
33
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { type LynxTemplate, type PageConfig, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type RpcCallType, type LynxContextEventTarget, type LynxJSModule, type MainThreadGlobalThis, type WebFiberElementImpl, type I18nResourceTranslationOptions } from '@lynx-js/web-constants';
1
+ import { type LynxTemplate, type PageConfig, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type RpcCallType, type LynxContextEventTarget, type LynxJSModule, type MainThreadGlobalThis, type WebFiberElementImpl, type I18nResourceTranslationOptions, type SSRHydrateInfo, type SSRDehydrateHooks } from '@lynx-js/web-constants';
2
2
  export interface MainThreadRuntimeCallbacks {
3
3
  mainChunkReady: () => void;
4
4
  flushElementTree: (options: FlushElementTreeOptions, timingFlags: string[], exposureChangedElements: WebFiberElementImpl[]) => void;
@@ -19,7 +19,9 @@ export interface MainThreadRuntimeConfig {
19
19
  lepusCode: Record<string, LynxJSModule>;
20
20
  browserConfig: BrowserConfig;
21
21
  tagMap: Record<string, string>;
22
- rootDom: Pick<Element, 'append' | 'addEventListener'>;
22
+ rootDom: Pick<Element, 'append' | 'addEventListener'> & Partial<Pick<Element, 'querySelectorAll'>>;
23
23
  jsContext: LynxContextEventTarget;
24
+ ssrHydrateInfo?: SSRHydrateInfo;
25
+ ssrHooks?: SSRDehydrateHooks;
24
26
  }
25
27
  export declare function createMainThreadGlobalThis(config: MainThreadRuntimeConfig): MainThreadGlobalThis;
@@ -5,7 +5,7 @@ import { lynxUniqueIdAttribute, systemInfo, parentComponentUniqueIdAttribute, co
5
5
  import { globalMuteableVars } from '@lynx-js/web-constants';
6
6
  import { createMainThreadLynx } from './createMainThreadLynx.js';
7
7
  import { flattenStyleInfo, genCssContent, genCssOGInfo, transformToWebCss, } from './utils/processStyleInfo.js';
8
- import { __AddClass, __AddConfig, __AddDataset, __AddInlineStyle, __AppendElement, __ElementIsEqual, __FirstElement, __GetAttributes, __GetChildren, __GetClasses, __GetComponentID, __GetDataByKey, __GetDataset, __GetElementConfig, __GetElementUniqueID, __GetID, __GetParent, __GetTag, __InsertElementBefore, __LastElement, __NextElement, __RemoveElement, __ReplaceElement, __ReplaceElements, __SetClasses, __SetConfig, __SetCSSId, __SetDataset, __SetID, __SetInlineStyles, __UpdateComponentID, } from './pureElementPAPIs.js';
8
+ import { __AddClass, __AddConfig, __AddDataset, __AddInlineStyle, __AppendElement, __ElementIsEqual, __FirstElement, __GetAttributes, __GetChildren, __GetClasses, __GetComponentID, __GetDataByKey, __GetDataset, __GetElementConfig, __GetElementUniqueID, __GetID, __GetParent, __GetTag, __GetTemplateParts, __InsertElementBefore, __LastElement, __MarkPartElement, __MarkTemplateElement, __NextElement, __RemoveElement, __ReplaceElement, __ReplaceElements, __SetClasses, __SetConfig, __SetCSSId, __SetDataset, __SetID, __SetInlineStyles, __UpdateComponentID, } from './pureElementPAPIs.js';
9
9
  import { createCrossThreadEvent } from './utils/createCrossThreadEvent.js';
10
10
  import { decodeCssOG } from './utils/decodeCssOG.js';
11
11
  const exposureRelatedAttributes = new Set([
@@ -21,14 +21,15 @@ const exposureRelatedAttributes = new Set([
21
21
  'exposure-ui-margin-left',
22
22
  ]);
23
23
  export function createMainThreadGlobalThis(config) {
24
- let pageElement;
25
- let uniqueIdInc = 1;
26
24
  let timingFlags = [];
27
25
  let renderPage;
28
- const { callbacks, tagMap, pageConfig, lepusCode, rootDom, globalProps, styleInfo, } = config;
29
- const lynxUniqueIdToElement = [];
26
+ const { callbacks, tagMap, pageConfig, lepusCode, rootDom, globalProps, styleInfo, ssrHydrateInfo, ssrHooks, } = config;
27
+ const lynxUniqueIdToElement = ssrHydrateInfo?.lynxUniqueIdToElement ?? [];
28
+ const lynxUniqueIdToStyleRulesIndex = ssrHydrateInfo?.lynxUniqueIdToStyleRulesIndex ?? [];
30
29
  const elementToRuntimeInfoMap = new WeakMap();
31
- const lynxUniqueIdToStyleRulesIndex = [];
30
+ let pageElement = lynxUniqueIdToElement[1]
31
+ ?.deref();
32
+ let uniqueIdInc = lynxUniqueIdToElement.length || 1;
32
33
  /**
33
34
  * for "update" the globalThis.val in the main thread
34
35
  */
@@ -48,10 +49,15 @@ export function createMainThreadGlobalThis(config) {
48
49
  const cssOGInfo = pageConfig.enableCSSSelector
49
50
  ? {}
50
51
  : genCssOGInfo(styleInfo);
51
- const cardStyleElement = callbacks.createElement('style');
52
- cardStyleElement.innerHTML = genCssContent(styleInfo, pageConfig);
53
- // @ts-expect-error
54
- rootDom.append(cardStyleElement);
52
+ let cardStyleElement;
53
+ if (ssrHydrateInfo?.cardStyleElement) {
54
+ cardStyleElement = ssrHydrateInfo.cardStyleElement;
55
+ }
56
+ else {
57
+ cardStyleElement = callbacks.createElement('style');
58
+ cardStyleElement.innerHTML = genCssContent(styleInfo, pageConfig);
59
+ rootDom.append(cardStyleElement);
60
+ }
55
61
  const cardStyleElementSheet = cardStyleElement.sheet;
56
62
  const updateCssOGStyle = (uniqueId, newStyles) => {
57
63
  if (lynxUniqueIdToStyleRulesIndex[uniqueId] !== undefined) {
@@ -248,6 +254,7 @@ export function createMainThreadGlobalThis(config) {
248
254
  page.setAttribute(cssIdAttribute, cssID + '');
249
255
  page.setAttribute(parentComponentUniqueIdAttribute, '0');
250
256
  page.setAttribute(componentIdAttribute, componentID);
257
+ __MarkTemplateElement(page);
251
258
  if (pageConfig.defaultDisplayLinear === false) {
252
259
  page.setAttribute(lynxDefaultDisplayLinearAttribute, 'false');
253
260
  }
@@ -366,16 +373,18 @@ export function createMainThreadGlobalThis(config) {
366
373
  exposureChangedElements.clear();
367
374
  callbacks.flushElementTree(options, timingFlagsCopied, exposureChangedElementsArray);
368
375
  };
369
- const __GetTemplateParts = () => {
370
- return undefined;
371
- };
372
376
  const __GetPageElement = () => {
373
377
  return pageElement;
374
378
  };
375
379
  let release = '';
376
380
  const isCSSOG = !pageConfig.enableCSSSelector;
377
381
  const mtsGlobalThis = {
378
- __AddEvent,
382
+ __GetTemplateParts: rootDom.querySelectorAll
383
+ ? __GetTemplateParts
384
+ : undefined,
385
+ __MarkTemplateElement,
386
+ __MarkPartElement,
387
+ __AddEvent: ssrHooks?.__AddEvent ?? __AddEvent,
379
388
  __GetEvent,
380
389
  __GetEvents,
381
390
  __SetEvents,
@@ -426,7 +435,6 @@ export function createMainThreadGlobalThis(config) {
426
435
  __SetInlineStyles,
427
436
  __LoadLepusChunk,
428
437
  __GetPageElement,
429
- __GetTemplateParts,
430
438
  __globalProps: globalProps,
431
439
  SystemInfo: {
432
440
  ...systemInfo,
@@ -1,4 +1,4 @@
1
- import { type Rpc, type StartMainThreadContextConfig, type RpcCallType, type reportErrorEndpoint, type MainThreadGlobalThis, type I18nResourceTranslationOptions, type InitI18nResources, type I18nResources } from '@lynx-js/web-constants';
2
- export declare function prepareMainThreadAPIs(backgroundThreadRpc: Rpc, rootDom: Document | ShadowRoot, createElement: Document['createElement'], commitDocument: (exposureChangedElements: HTMLElement[]) => Promise<void> | void, markTimingInternal: (timingKey: string, pipelineId?: string) => void, flushMarkTimingInternal: () => void, reportError: RpcCallType<typeof reportErrorEndpoint>, triggerI18nResourceFallback: (options: I18nResourceTranslationOptions) => void, initialI18nResources: (data: InitI18nResources) => I18nResources): {
3
- startMainThread: (config: StartMainThreadContextConfig) => Promise<MainThreadGlobalThis>;
1
+ import { type Rpc, type StartMainThreadContextConfig, type RpcCallType, type reportErrorEndpoint, type MainThreadGlobalThis, type I18nResourceTranslationOptions, type InitI18nResources, type I18nResources, type SSRHydrateInfo, type SSRDehydrateHooks } from '@lynx-js/web-constants';
2
+ export declare function prepareMainThreadAPIs(backgroundThreadRpc: Rpc, rootDom: Document | ShadowRoot, createElement: Document['createElement'], commitDocument: (exposureChangedElements: HTMLElement[]) => Promise<void> | void, markTimingInternal: (timingKey: string, pipelineId?: string) => void, flushMarkTimingInternal: () => void, reportError: RpcCallType<typeof reportErrorEndpoint>, triggerI18nResourceFallback: (options: I18nResourceTranslationOptions) => void, initialI18nResources: (data: InitI18nResources) => I18nResources, ssrHooks?: SSRDehydrateHooks): {
3
+ startMainThread: (config: StartMainThreadContextConfig, ssrHydrateInfo?: SSRHydrateInfo) => Promise<MainThreadGlobalThis>;
4
4
  };
@@ -9,7 +9,7 @@ import { createExposureService } from './utils/createExposureService.js';
9
9
  import { initTokenizer } from './utils/tokenizer.js';
10
10
  const initTokenizerPromise = initTokenizer();
11
11
  const moduleCache = {};
12
- export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElement, commitDocument, markTimingInternal, flushMarkTimingInternal, reportError, triggerI18nResourceFallback, initialI18nResources) {
12
+ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElement, commitDocument, markTimingInternal, flushMarkTimingInternal, reportError, triggerI18nResourceFallback, initialI18nResources, ssrHooks) {
13
13
  const postTimingFlags = backgroundThreadRpc.createCall(postTimingFlagsEndpoint);
14
14
  const backgroundStart = backgroundThreadRpc.createCall(BackgroundThreadStartEndpoint);
15
15
  const publishEvent = backgroundThreadRpc.createCall(publishEventEndpoint);
@@ -17,7 +17,7 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
17
17
  const postExposure = backgroundThreadRpc.createCall(postExposureEndpoint);
18
18
  const dispatchI18nResource = backgroundThreadRpc.createCall(dispatchI18nResourceEndpoint);
19
19
  markTimingInternal('lepus_execute_start');
20
- async function startMainThread(config) {
20
+ async function startMainThread(config, ssrHydrateInfo) {
21
21
  let isFp = true;
22
22
  const { globalProps, template, browserConfig, nativeModulesMap, napiModulesMap, tagMap, initI18nResources, } = config;
23
23
  const { styleInfo, pageConfig, customSections, cardType, lepusCode } = template;
@@ -55,6 +55,8 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
55
55
  styleInfo,
56
56
  lepusCode: lepusCodeLoaded,
57
57
  rootDom,
58
+ ssrHydrateInfo,
59
+ ssrHooks,
58
60
  callbacks: {
59
61
  mainChunkReady: () => {
60
62
  markTimingInternal('data_processor_start');
@@ -78,8 +80,22 @@ export function prepareMainThreadAPIs(backgroundThreadRpc, rootDom, createElemen
78
80
  napiModulesMap,
79
81
  browserConfig,
80
82
  });
81
- mtsGlobalThis.renderPage(initData);
82
- mtsGlobalThis.__FlushElementTree(undefined, {});
83
+ if (!ssrHydrateInfo) {
84
+ mtsGlobalThis.renderPage(initData);
85
+ mtsGlobalThis.__FlushElementTree(undefined, {});
86
+ }
87
+ else {
88
+ // replay the hydrate event
89
+ for (const event of ssrHydrateInfo.events) {
90
+ const uniqueId = event[0];
91
+ const element = ssrHydrateInfo.lynxUniqueIdToElement[uniqueId]
92
+ ?.deref();
93
+ if (element) {
94
+ mtsGlobalThis.__AddEvent(element, event[1], event[2], event[3]);
95
+ }
96
+ }
97
+ mtsGlobalThis.ssrHydrate?.(ssrHydrateInfo.ssrEncodeData);
98
+ }
83
99
  },
84
100
  flushElementTree: async (options, timingFlags, exposureChangedElements) => {
85
101
  const pipelineId = options?.pipelineOptions?.pipelineID;
@@ -1,4 +1,4 @@
1
- import { type AddClassPAPI, type AddConfigPAPI, type AddDatasetPAPI, type AddInlineStylePAPI, type AppendElementPAPI, type ElementIsEqualPAPI, type FirstElementPAPI, type GetAttributesPAPI, type GetChildrenPAPI, type GetClassesPAPI, type GetComponentIdPAPI, type GetDataByKeyPAPI, type GetDatasetPAPI, type GetElementConfigPAPI, type GetElementUniqueIDPAPI, type GetIDPAPI, type GetParentPAPI, type GetTagPAPI, type InsertElementBeforePAPI, type LastElementPAPI, type NextElementPAPI, type RemoveElementPAPI, type ReplaceElementPAPI, type ReplaceElementsPAPI, type SetClassesPAPI, type SetConfigPAPI, type SetCSSIdPAPI, type SetDatasetPAPI, type SetIDPAPI, type SetInlineStylesPAPI, type UpdateComponentIDPAPI } from '@lynx-js/web-constants';
1
+ import { type AddClassPAPI, type AddConfigPAPI, type AddDatasetPAPI, type AddInlineStylePAPI, type AppendElementPAPI, type ElementIsEqualPAPI, type FirstElementPAPI, type GetAttributesPAPI, type GetChildrenPAPI, type GetClassesPAPI, type GetComponentIdPAPI, type GetDataByKeyPAPI, type GetDatasetPAPI, type GetElementConfigPAPI, type GetElementUniqueIDPAPI, type GetIDPAPI, type GetParentPAPI, type GetTagPAPI, type GetTemplatePartsPAPI, type InsertElementBeforePAPI, type LastElementPAPI, type MarkPartElementPAPI, type MarkTemplateElementPAPI, type NextElementPAPI, type RemoveElementPAPI, type ReplaceElementPAPI, type ReplaceElementsPAPI, type SetClassesPAPI, type SetConfigPAPI, type SetCSSIdPAPI, type SetDatasetPAPI, type SetIDPAPI, type SetInlineStylesPAPI, type UpdateComponentIDPAPI } from '@lynx-js/web-constants';
2
2
  export declare const __AppendElement: AppendElementPAPI;
3
3
  export declare const __ElementIsEqual: ElementIsEqualPAPI;
4
4
  export declare const __FirstElement: FirstElementPAPI;
@@ -30,3 +30,6 @@ export declare const __SetClasses: SetClassesPAPI;
30
30
  export declare const __AddInlineStyle: AddInlineStylePAPI;
31
31
  export declare const __AddClass: AddClassPAPI;
32
32
  export declare const __SetInlineStyles: SetInlineStylesPAPI;
33
+ export declare const __GetTemplateParts: GetTemplatePartsPAPI;
34
+ export declare const __MarkTemplateElement: MarkTemplateElementPAPI;
35
+ export declare const __MarkPartElement: MarkPartElementPAPI;
@@ -1,14 +1,14 @@
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 { componentIdAttribute, cssIdAttribute, lynxComponentConfigAttribute, lynxDatasetAttribute, lynxTagAttribute, lynxUniqueIdAttribute, } from '@lynx-js/web-constants';
4
+ import { componentIdAttribute, cssIdAttribute, lynxComponentConfigAttribute, lynxDatasetAttribute, lynxElementTemplateMarkerAttribute, lynxPartIdAttribute, lynxTagAttribute, lynxUniqueIdAttribute, } from '@lynx-js/web-constants';
5
5
  import { queryCSSProperty } from './style/cssPropertyMap.js';
6
6
  import { transformInlineStyleString, transformParsedStyles, } from './style/transformInlineStyle.js';
7
7
  import hyphenateStyleName from 'hyphenate-style-name';
8
8
  export const __AppendElement = /*#__PURE__*/ (parent, child) => parent.appendChild(child);
9
9
  export const __ElementIsEqual = /*#__PURE__*/ (left, right) => left === right;
10
10
  export const __FirstElement = /*#__PURE__*/ (element) => element.firstElementChild;
11
- export const __GetChildren = /*#__PURE__*/ (element) => element.children;
11
+ export const __GetChildren = /*#__PURE__*/ (element) => element.children ? [...element.children] : null;
12
12
  export const __GetParent = /*#__PURE__*/ (element) => element.parentElement;
13
13
  export const __InsertElementBefore = /*#__PURE__*/ (parent, child, ref) => parent.insertBefore(child, ref);
14
14
  export const __LastElement = /*#__PURE__*/ (element) => element.lastElementChild;
@@ -134,10 +134,33 @@ export const __SetInlineStyles = /*#__PURE__*/ (element, value) => {
134
134
  else {
135
135
  const { transformedStyle } = transformParsedStyles(Object.entries(value).map(([k, value]) => [
136
136
  hyphenateStyleName(k),
137
- value,
137
+ value?.toString?.() ?? '',
138
138
  ]));
139
139
  const transformedStyleStr = transformedStyle.map(([property, value]) => `${property}:${value};`).join('');
140
140
  element.setAttribute('style', transformedStyleStr);
141
141
  }
142
142
  };
143
+ export const __GetTemplateParts = (templateElement) => {
144
+ const isTemplate = templateElement.getAttribute(lynxElementTemplateMarkerAttribute)
145
+ !== null;
146
+ if (!isTemplate) {
147
+ return {};
148
+ }
149
+ const templateUniqueId = __GetElementUniqueID(templateElement);
150
+ const parts = {};
151
+ const partElements = templateElement.querySelectorAll(`[${lynxUniqueIdAttribute}="${templateUniqueId}"] [${lynxPartIdAttribute}]:not([${lynxUniqueIdAttribute}="${templateUniqueId}"] [${lynxElementTemplateMarkerAttribute}] [${lynxPartIdAttribute}])`);
152
+ for (const partElement of partElements) {
153
+ const partId = partElement.getAttribute(lynxPartIdAttribute);
154
+ if (partId) {
155
+ parts[partId] = partElement;
156
+ }
157
+ }
158
+ return parts;
159
+ };
160
+ export const __MarkTemplateElement = (element) => {
161
+ element.setAttribute(lynxElementTemplateMarkerAttribute, '');
162
+ };
163
+ export const __MarkPartElement = (element, partId) => {
164
+ element.setAttribute(lynxPartIdAttribute, partId);
165
+ };
143
166
  //# sourceMappingURL=pureElementPAPIs.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-mainthread-apis",
3
- "version": "0.15.1",
3
+ "version": "0.15.3",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "keywords": [],
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "hyphenate-style-name": "^1.1.0",
28
- "@lynx-js/web-constants": "0.15.1",
28
+ "@lynx-js/web-constants": "0.15.3",
29
29
  "@lynx-js/web-style-transformer": "0.3.3"
30
30
  }
31
31
  }