@lynx-js/web-mainthread-apis 0.11.0 → 0.13.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 CHANGED
@@ -1,5 +1,65 @@
1
1
  # @lynx-js/web-mainthread-apis
2
2
 
3
+ ## 0.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - fix: mts lynx will no longer provide requireModule, requireModuleAsync methods, which is aligned with Native. ([#537](https://github.com/lynx-family/lynx-stack/pull/537))
8
+
9
+ ### Patch Changes
10
+
11
+ - refactor: isolate SystemInfo ([#628](https://github.com/lynx-family/lynx-stack/pull/628))
12
+
13
+ Never assign `SystemInfo` on worker's self object.
14
+
15
+ - feat: support thread strategy `all-on-ui` ([#625](https://github.com/lynx-family/lynx-stack/pull/625))
16
+
17
+ ```html
18
+ <lynx-view thread-strategy="all-on-ui"></lynx-view>
19
+ ```
20
+
21
+ This will make the lynx's main-thread run on the UA's main thread.
22
+
23
+ Note that the `all-on-ui` does not support the HMR & chunk splitting yet.
24
+
25
+ - fix(web): `:root` not work on web platform ([#607](https://github.com/lynx-family/lynx-stack/pull/607))
26
+
27
+ Note: To solve this issue, you need to upgrade your `react-rsbuild-plugin`
28
+
29
+ - refactor: move mainthread impl into mainthread-api packages ([#622](https://github.com/lynx-family/lynx-stack/pull/622))
30
+
31
+ - fix(web): css selector not work for selectors with combinator and pseudo-class on WEB ([#608](https://github.com/lynx-family/lynx-stack/pull/608))
32
+
33
+ like `.parent > :not([hidden]) ~ :not([hidden])`
34
+
35
+ you will need to upgrade your `react-rsbuild-plugin` to fix this issue
36
+
37
+ - Updated dependencies [[`4ee0465`](https://github.com/lynx-family/lynx-stack/commit/4ee0465f6e5846a0d038b49d2a7c95e87c9e5c77), [`5a3d9af`](https://github.com/lynx-family/lynx-stack/commit/5a3d9afe52ba639987db124ca35580261e0718b5), [`5269cab`](https://github.com/lynx-family/lynx-stack/commit/5269cabef7609159bdd0dd14a03c5da667907424)]:
38
+ - @lynx-js/web-constants@0.13.0
39
+
40
+ ## 0.12.0
41
+
42
+ ### Patch Changes
43
+
44
+ - feat: fully support MTS ([#569](https://github.com/lynx-family/lynx-stack/pull/569))
45
+
46
+ Now use support the following usage
47
+
48
+ - mainthread event
49
+ - mainthread ref
50
+ - runOnMainThread/runOnBackground
51
+ - ref.current.xx
52
+
53
+ - feat: support mts event with target methods ([#564](https://github.com/lynx-family/lynx-stack/pull/564))
54
+
55
+ After this commit, developers are allowed to invoke `event.target.setStyleProperty` in mts handler
56
+
57
+ - fix: crash on removing a id attribute ([#582](https://github.com/lynx-family/lynx-stack/pull/582))
58
+
59
+ - Updated dependencies [[`f1ca29b`](https://github.com/lynx-family/lynx-stack/commit/f1ca29bd766377dd46583f15e1e75bca447699cd), [`7edf478`](https://github.com/lynx-family/lynx-stack/commit/7edf478410cb57eeedc18aac6f5d3950b16c7fa8)]:
60
+ - @lynx-js/web-constants@0.12.0
61
+ - @lynx-js/web-style-transformer@0.3.0
62
+
3
63
  ## 0.11.0
4
64
 
5
65
  ### Patch Changes
@@ -1,11 +1,9 @@
1
- import { type MainThreadConfig, MainThreadRuntime } from './MainThreadRuntime.js';
2
- export declare function createMainThreadLynx(config: MainThreadConfig, lepusRuntime: MainThreadRuntime): {
3
- getJSContext(): EventTarget;
1
+ import { type MainThreadConfig } from './MainThreadRuntime.js';
2
+ export declare function createMainThreadLynx(config: MainThreadConfig): {
3
+ getJSContext(): import("@lynx-js/web-constants").LynxContextEventTarget;
4
4
  requestAnimationFrame(cb: FrameRequestCallback): number;
5
5
  cancelAnimationFrame(handler: number): void;
6
6
  __globalProps: unknown;
7
- requireModule(path: string): unknown;
8
- requireModuleAsync(path: string, callback: (error: Error | null, exports?: unknown) => void): void;
9
7
  getCustomSectionSync(key: string): import("@lynx-js/web-constants").Cloneable;
10
8
  markPipelineTiming: (pipelineId: string, timingKey: string) => void;
11
9
  };
@@ -1,9 +1,11 @@
1
- import { MainThreadRuntime, } from './MainThreadRuntime.js';
2
- export function createMainThreadLynx(config, lepusRuntime) {
1
+ // Copyright 2023 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import {} from './MainThreadRuntime.js';
5
+ export function createMainThreadLynx(config) {
3
6
  return {
4
7
  getJSContext() {
5
- // TODO: implement this
6
- return new EventTarget();
8
+ return config.jsContext;
7
9
  },
8
10
  requestAnimationFrame(cb) {
9
11
  return requestAnimationFrame(cb);
@@ -12,33 +14,6 @@ export function createMainThreadLynx(config, lepusRuntime) {
12
14
  return cancelAnimationFrame(handler);
13
15
  },
14
16
  __globalProps: config.globalProps,
15
- requireModule(path) {
16
- // @ts-expect-error
17
- if (self.WorkerGlobalScope) {
18
- const lepusChunkUrl = config.lepusCode[`${path}`];
19
- if (lepusChunkUrl)
20
- path = lepusChunkUrl;
21
- // @ts-expect-error
22
- importScripts(path);
23
- const entry = globalThis.module.exports;
24
- return entry?.(lepusRuntime);
25
- }
26
- else {
27
- throw new Error('importing scripts synchronously is only available for the multi-thread running mode');
28
- }
29
- },
30
- requireModuleAsync(path, callback) {
31
- const lepusChunkUrl = config.lepusCode[`${path}`];
32
- if (lepusChunkUrl)
33
- path = lepusChunkUrl;
34
- import(
35
- /* webpackIgnore: true */
36
- path).catch(callback).then(() => {
37
- const entry = globalThis.module.exports;
38
- const ret = entry?.(lepusRuntime);
39
- callback(null, ret);
40
- });
41
- },
42
17
  getCustomSectionSync(key) {
43
18
  return config.customSections[key]?.content;
44
19
  },
@@ -1,4 +1,4 @@
1
- import { type LynxTemplate, type PageConfig, type ProcessDataCallback, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type RpcCallType, type postExposureEndpoint } from '@lynx-js/web-constants';
1
+ import { type LynxTemplate, type PageConfig, type ProcessDataCallback, type StyleInfo, type FlushElementTreeOptions, type Cloneable, type BrowserConfig, type publishEventEndpoint, type publicComponentEventEndpoint, type reportErrorEndpoint, type RpcCallType, type postExposureEndpoint, type LynxContextEventTarget, type LynxJSModule, systemInfo } from '@lynx-js/web-constants';
2
2
  import { type MainThreadLynx } from './MainThreadLynx.js';
3
3
  import type { LynxRuntimeInfo } from './elementAPI/ElementThreadElement.js';
4
4
  export interface MainThreadRuntimeCallbacks {
@@ -17,10 +17,11 @@ export interface MainThreadConfig {
17
17
  callbacks: MainThreadRuntimeCallbacks;
18
18
  styleInfo: StyleInfo;
19
19
  customSections: LynxTemplate['customSections'];
20
- lepusCode: LynxTemplate['lepusCode'];
20
+ lepusCode: Record<string, LynxJSModule>;
21
21
  browserConfig: BrowserConfig;
22
22
  tagMap: Record<string, string>;
23
23
  docu: Pick<Document, 'append' | 'createElement' | 'addEventListener'>;
24
+ jsContext: LynxContextEventTarget;
24
25
  }
25
26
  export declare const elementToRuntimeInfoMap: unique symbol;
26
27
  export declare const getElementByUniqueId: unique symbol;
@@ -69,6 +70,7 @@ export declare class MainThreadRuntime {
69
70
  */
70
71
  __lynxGlobalBindingValues: Record<string, any>;
71
72
  get globalThis(): this;
73
+ SystemInfo: typeof systemInfo;
72
74
  lynx: MainThreadLynx;
73
75
  __globalProps: unknown;
74
76
  processData?: ProcessDataCallback;
@@ -1,7 +1,7 @@
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 { lynxUniqueIdAttribute, } from '@lynx-js/web-constants';
4
+ import { lynxUniqueIdAttribute, systemInfo, } from '@lynx-js/web-constants';
5
5
  import { globalMuteableVars } from '@lynx-js/web-constants';
6
6
  import { createMainThreadLynx } from './MainThreadLynx.js';
7
7
  import { initializeElementCreatingFunction } from './elementAPI/elementCreating/elementCreatingFunctions.js';
@@ -49,7 +49,7 @@ export class MainThreadRuntime {
49
49
  constructor(config) {
50
50
  this.config = config;
51
51
  this.__globalProps = config.globalProps;
52
- this.lynx = createMainThreadLynx(config, this);
52
+ this.lynx = createMainThreadLynx(config);
53
53
  /**
54
54
  * now create the style content
55
55
  * 1. flatten the styleInfo
@@ -63,7 +63,6 @@ export class MainThreadRuntime {
63
63
  const cssInJsInfo = this.config.pageConfig.enableCSSSelector
64
64
  ? {}
65
65
  : genCssInJsInfo(this.config.styleInfo);
66
- this._rootDom = this.config.docu.createElement('div');
67
66
  const cardStyleElement = this.config.docu.createElement('style');
68
67
  cardStyleElement.innerHTML = genCssContent(this.config.styleInfo, this.config.pageConfig);
69
68
  this._rootDom = this.config.docu;
@@ -74,6 +73,10 @@ export class MainThreadRuntime {
74
73
  Object.assign(this, createAttributeAndPropertyFunctions(this), domTreeApis, createEventFunctions(this), createStyleFunctions(this, cssInJsInfo), initializeElementCreatingFunction(this));
75
74
  this._ReportError = this.config.callbacks._ReportError;
76
75
  this.__OnLifecycleEvent = this.config.callbacks.__OnLifecycleEvent;
76
+ this.SystemInfo = {
77
+ ...systemInfo,
78
+ pixelRatio: config.browserConfig.pixelRatio,
79
+ };
77
80
  /**
78
81
  * Start the exposure service
79
82
  */
@@ -128,6 +131,7 @@ export class MainThreadRuntime {
128
131
  get globalThis() {
129
132
  return this;
130
133
  }
134
+ SystemInfo;
131
135
  lynx;
132
136
  __globalProps;
133
137
  processData;
@@ -135,18 +139,20 @@ export class MainThreadRuntime {
135
139
  _ReportError;
136
140
  __OnLifecycleEvent;
137
141
  __LoadLepusChunk = (path) => {
138
- try {
139
- this.lynx.requireModule(path);
142
+ const lepusModule = this.config.lepusCode[`${path}`];
143
+ if (lepusModule) {
144
+ const entry = lepusModule.exports;
145
+ entry?.(this);
140
146
  return true;
141
147
  }
142
- catch {
148
+ else {
149
+ return false;
143
150
  }
144
- return false;
145
151
  };
146
152
  __FlushElementTree = (_subTree, options) => {
147
153
  const timingFlags = this._timingFlags;
148
154
  this._timingFlags = [];
149
- if (this._page && !this._page.parentElement) {
155
+ if (this._page && !this._page.parentNode) {
150
156
  this._rootDom.append(this._page);
151
157
  }
152
158
  this.config.callbacks.flushElementTree(options, timingFlags);
@@ -0,0 +1,3 @@
1
+ import { type Rpc } from '@lynx-js/web-constants';
2
+ import type { MainThreadRuntime } from '../MainThreadRuntime.js';
3
+ export declare function registerCallLepusMethodHandler(rpc: Rpc, runtime: MainThreadRuntime): void;
@@ -0,0 +1,10 @@
1
+ // Copyright 2023 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import { callLepusMethodEndpoint } from '@lynx-js/web-constants';
5
+ export function registerCallLepusMethodHandler(rpc, runtime) {
6
+ rpc.registerHandler(callLepusMethodEndpoint, (methodName, data) => {
7
+ (runtime[methodName])(data);
8
+ });
9
+ }
10
+ //# sourceMappingURL=registerCallLepusMethodHandler.js.map
@@ -0,0 +1,2 @@
1
+ import { type LynxTemplate, type Rpc } from '@lynx-js/web-constants';
2
+ export declare function registerGetCustomSectionHandler(rpc: Rpc, customSections: LynxTemplate['customSections']): void;
@@ -0,0 +1,10 @@
1
+ // Copyright 2023 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import { getCustomSectionsEndpoint, } from '@lynx-js/web-constants';
5
+ export function registerGetCustomSectionHandler(rpc, customSections) {
6
+ rpc.registerHandler(getCustomSectionsEndpoint, (key) => {
7
+ return customSections[key]?.content;
8
+ });
9
+ }
10
+ //# sourceMappingURL=registerGetCustomSectionHandler.js.map
@@ -21,7 +21,7 @@ export declare function createAttributeAndPropertyFunctions(runtime: MainThreadR
21
21
  __GetTag: (element: HTMLElement) => string;
22
22
  __SetConfig: (element: HTMLElement, config: Record<string, any>) => void;
23
23
  __SetDataset: (element: HTMLElement, dataset: Record<string, any>) => void;
24
- __SetID: (element: HTMLElement, id: string) => void;
24
+ __SetID: (element: HTMLElement, id: string | null) => void;
25
25
  __UpdateComponentID: (element: HTMLElement, componentID: string) => void;
26
26
  __UpdateListCallbacks: (element: HTMLElement, componentAtIndex: ComponentAtIndexCallback, enqueueComponent: EnqueueComponentCallback) => void;
27
27
  __GetConfig: (element: HTMLElement) => Record<string, import("@lynx-js/web-constants").Cloneable>;
@@ -57,7 +57,12 @@ export function createAttributeAndPropertyFunctions(runtime) {
57
57
  }
58
58
  }
59
59
  function __SetID(element, id) {
60
- element.id = id;
60
+ if (typeof id === 'string') {
61
+ element.id = id;
62
+ }
63
+ else {
64
+ element.removeAttribute('id');
65
+ }
61
66
  }
62
67
  function __UpdateComponentID(element, componentID) {
63
68
  element.setAttribute(componentIdAttribute, componentID);
@@ -18,8 +18,8 @@ export function createEventFunctions(runtime) {
18
18
  ?.handler
19
19
  : runtimeInfo.eventHandlerMap[lynxEventName]?.bind
20
20
  ?.handler;
21
+ const crossThreadEvent = createCrossThreadEvent(runtime, event, lynxEventName);
21
22
  if (typeof hname === 'string') {
22
- const crossThreadEvent = createCrossThreadEvent(runtime, event, lynxEventName);
23
23
  const parentComponentUniqueId = runtimeInfo.parentComponentUniqueId;
24
24
  const parentComponent = runtime[getElementByUniqueId](Number(parentComponentUniqueId));
25
25
  const componentId = parentComponent?.getAttribute(lynxTagAttribute) !== 'page'
@@ -34,7 +34,13 @@ export function createEventFunctions(runtime) {
34
34
  return true;
35
35
  }
36
36
  else if (hname) {
37
- runtime.runWorklet?.(hname.value, []);
37
+ crossThreadEvent.target.elementRefptr =
38
+ event.target;
39
+ if (crossThreadEvent.currentTarget) {
40
+ crossThreadEvent.currentTarget
41
+ .elementRefptr = event.currentTarget;
42
+ }
43
+ runtime.runWorklet?.(hname.value, [crossThreadEvent]);
38
44
  }
39
45
  return false;
40
46
  };
@@ -30,14 +30,20 @@ export function createStyleFunctions(runtime, cssInJsInfo) {
30
30
  return (element.className ?? '').split(' ').filter(e => e);
31
31
  }
32
32
  function __AddInlineStyle(element, key, value) {
33
- const lynxStyleInfo = queryCSSProperty(Number(key));
33
+ let dashName;
34
+ if (typeof key === 'number') {
35
+ dashName = queryCSSProperty(key).dashName;
36
+ }
37
+ else {
38
+ dashName = key;
39
+ }
34
40
  const valueStr = typeof value === 'number' ? value.toString() : value;
35
41
  if (!valueStr) { // null or undefined
36
- element.style.removeProperty(lynxStyleInfo.dashName);
42
+ element.style.removeProperty(dashName);
37
43
  }
38
44
  else {
39
45
  const { transformedStyle } = transfromParsedStyles([[
40
- lynxStyleInfo.dashName,
46
+ dashName,
41
47
  valueStr,
42
48
  ]]);
43
49
  for (const [property, value] of transformedStyle) {
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ export { loadMainThread } from './loadMainThread.js';
1
2
  export * from './MainThreadRuntime.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
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
+ export { loadMainThread } from './loadMainThread.js';
4
5
  export * from './MainThreadRuntime.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,5 @@
1
+ import { type Rpc, type MainThreadStartConfigs, type RpcCallType, type reportErrorEndpoint } from '@lynx-js/web-constants';
2
+ import { MainThreadRuntime } from './MainThreadRuntime.js';
3
+ export declare function loadMainThread(backgroundThreadRpc: Rpc, docu: Pick<Document, 'append' | 'createElement' | 'addEventListener'>, commitDocument: () => Promise<void> | void, markTimingInternal: (timingKey: string, pipelineId?: string) => void, reportError: RpcCallType<typeof reportErrorEndpoint>): {
4
+ startMainThread: (config: MainThreadStartConfigs) => Promise<MainThreadRuntime>;
5
+ };
@@ -0,0 +1,120 @@
1
+ // Copyright 2023 The Lynx Authors. All rights reserved.
2
+ // Licensed under the Apache License Version 2.0 that can be found in the
3
+ // LICENSE file in the root directory of this source tree.
4
+ import { BackgroundThreadStartEndpoint, publishEventEndpoint, publicComponentEventEndpoint, postExposureEndpoint, switchExposureServiceEndpoint, postTimingFlagsEndpoint, dispatchCoreContextOnBackgroundEndpoint, dispatchJSContextOnMainThreadEndpoint, LynxCrossThreadContext, } from '@lynx-js/web-constants';
5
+ import { registerCallLepusMethodHandler } from './crossThreadHandlers/registerCallLepusMethodHandler.js';
6
+ import { registerGetCustomSectionHandler } from './crossThreadHandlers/registerGetCustomSectionHandler.js';
7
+ import { MainThreadRuntime, switchExposureService, } from './MainThreadRuntime.js';
8
+ const moduleCache = {};
9
+ export function loadMainThread(backgroundThreadRpc, docu, commitDocument, markTimingInternal, reportError) {
10
+ const postTimingFlags = backgroundThreadRpc.createCall(postTimingFlagsEndpoint);
11
+ const backgroundStart = backgroundThreadRpc.createCall(BackgroundThreadStartEndpoint);
12
+ const publishEvent = backgroundThreadRpc.createCall(publishEventEndpoint);
13
+ const publicComponentEvent = backgroundThreadRpc.createCall(publicComponentEventEndpoint);
14
+ const postExposure = backgroundThreadRpc.createCall(postExposureEndpoint);
15
+ markTimingInternal('lepus_execute_start');
16
+ async function startMainThread(config) {
17
+ let isFp = true;
18
+ const { globalProps, template, browserConfig, nativeModulesMap, napiModulesMap, tagMap, } = config;
19
+ const { styleInfo, pageConfig, customSections, cardType, lepusCode } = template;
20
+ markTimingInternal('decode_start');
21
+ const lepusCodeEntries = await Promise.all(Object.entries(lepusCode).map(async ([name, url]) => {
22
+ const cachedModule = moduleCache[name];
23
+ if (cachedModule) {
24
+ return [name, cachedModule];
25
+ }
26
+ else {
27
+ Object.assign(globalThis, { module: {} });
28
+ await import(/* webpackIgnore: true */ url);
29
+ const module = globalThis.module;
30
+ Object.assign(globalThis, { module: {} });
31
+ moduleCache[name] = module;
32
+ return [name, module];
33
+ }
34
+ }));
35
+ const lepusCodeLoaded = Object.fromEntries(lepusCodeEntries);
36
+ const entry = lepusCodeLoaded['root'].exports;
37
+ const jsContext = new LynxCrossThreadContext({
38
+ rpc: backgroundThreadRpc,
39
+ receiveEventEndpoint: dispatchJSContextOnMainThreadEndpoint,
40
+ sendEventEndpoint: dispatchCoreContextOnBackgroundEndpoint,
41
+ });
42
+ const runtime = new MainThreadRuntime({
43
+ jsContext,
44
+ tagMap,
45
+ browserConfig,
46
+ customSections,
47
+ globalProps,
48
+ pageConfig,
49
+ styleInfo,
50
+ lepusCode: lepusCodeLoaded,
51
+ docu,
52
+ callbacks: {
53
+ mainChunkReady: () => {
54
+ markTimingInternal('data_processor_start');
55
+ const initData = runtime.processData
56
+ ? runtime.processData(config.initData)
57
+ : config.initData;
58
+ markTimingInternal('data_processor_end');
59
+ registerCallLepusMethodHandler(backgroundThreadRpc, runtime);
60
+ registerGetCustomSectionHandler(backgroundThreadRpc, customSections);
61
+ backgroundThreadRpc.registerHandler(switchExposureServiceEndpoint, runtime[switchExposureService]);
62
+ backgroundStart({
63
+ initData,
64
+ globalProps,
65
+ template,
66
+ cardType: cardType ?? 'react',
67
+ customSections: Object.fromEntries(Object.entries(customSections).filter(([, value]) => value.type !== 'lazy').map(([k, v]) => [k, v.content])),
68
+ nativeModulesMap,
69
+ napiModulesMap,
70
+ browserConfig,
71
+ });
72
+ runtime.renderPage(initData);
73
+ runtime.__FlushElementTree(undefined, {});
74
+ },
75
+ flushElementTree: async (options, timingFlags) => {
76
+ const pipelineId = options?.pipelineOptions?.pipelineID;
77
+ markTimingInternal('dispatch_start', pipelineId);
78
+ if (isFp) {
79
+ isFp = false;
80
+ jsContext.dispatchEvent({
81
+ type: '__OnNativeAppReady',
82
+ data: undefined,
83
+ });
84
+ }
85
+ markTimingInternal('layout_start', pipelineId);
86
+ markTimingInternal('ui_operation_flush_start', pipelineId);
87
+ await commitDocument();
88
+ markTimingInternal('ui_operation_flush_end', pipelineId);
89
+ markTimingInternal('layout_end', pipelineId);
90
+ markTimingInternal('dispatch_end', pipelineId);
91
+ requestAnimationFrame(() => {
92
+ postTimingFlags(timingFlags, pipelineId);
93
+ });
94
+ },
95
+ _ReportError: reportError,
96
+ __OnLifecycleEvent: (data) => {
97
+ jsContext.dispatchEvent({
98
+ type: '__OnLifecycleEvent',
99
+ data,
100
+ });
101
+ },
102
+ /**
103
+ * Note :
104
+ * The parameter of lynx.performance.markTiming is (pipelineId:string, timingFlag:string)=>void
105
+ * But our markTimingInternal is (timingFlag:string, pipelineId?:string, timeStamp?:number) => void
106
+ */
107
+ markTiming: (a, b) => markTimingInternal(b, a),
108
+ publishEvent,
109
+ publicComponentEvent,
110
+ postExposure,
111
+ },
112
+ }).globalThis;
113
+ markTimingInternal('decode_end');
114
+ entry(runtime);
115
+ jsContext.__start(); // start the jsContext after the runtime is created
116
+ return runtime;
117
+ }
118
+ return { startMainThread };
119
+ }
120
+ //# sourceMappingURL=loadMainThread.js.map
@@ -34,11 +34,9 @@ export function transformToWebCss(styleInfo) {
34
34
  rule.decl = transformedStyle;
35
35
  if (childStyle.length > 0) {
36
36
  cssInfos.rules.push({
37
- sel: selectors.map(selector => [
38
- selector[0].concat(['>', '*']),
39
- selector[1],
40
- selector[2],
41
- ]),
37
+ sel: selectors.map(selector => selector.toSpliced(-2, 1,
38
+ /* replace the last combinator and insert at the end */
39
+ ['>'], ['*'], [], [], [])),
42
40
  decl: childStyle,
43
41
  });
44
42
  }
@@ -50,7 +48,7 @@ export function transformToWebCss(styleInfo) {
50
48
  */
51
49
  export function genCssContent(styleInfo, pageConfig) {
52
50
  function getExtraSelectors(cssId) {
53
- let prepend = '', suffix = '';
51
+ let suffix = '';
54
52
  if (!pageConfig.enableRemoveCSSScope) {
55
53
  if (cssId !== undefined) {
56
54
  suffix += `[${cssIdAttribute}="${cssId}"]`;
@@ -63,21 +61,16 @@ export function genCssContent(styleInfo, pageConfig) {
63
61
  else {
64
62
  suffix += `[${lynxTagAttribute}]`;
65
63
  }
66
- return { prepend, suffix };
64
+ return suffix;
67
65
  }
68
66
  const finalCssContent = [];
69
67
  for (const [cssId, cssInfos] of Object.entries(styleInfo)) {
70
- const { prepend, suffix } = getExtraSelectors(cssId);
68
+ const suffix = getExtraSelectors(cssId);
71
69
  const declarationContent = cssInfos.rules.map((rule) => {
72
- const { sel: selectors, decl: declarations } = rule;
73
- const selectorString = selectors.map(([plainSelectors, pseudoClassSelectors, pseudoElementSelectors]) => {
74
- return [
75
- prepend,
76
- plainSelectors.join(''),
77
- suffix,
78
- pseudoClassSelectors.join(''),
79
- pseudoElementSelectors.join(''),
80
- ].join('');
70
+ const { sel: selectorList, decl: declarations } = rule;
71
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
72
+ const selectorString = selectorList.map((selectors) => {
73
+ return selectors.toSpliced(-4, 0, [suffix]).join('');
81
74
  }).join(',');
82
75
  const declarationString = declarations.map(([k, v]) => `${k}:${v};`).join('');
83
76
  return `${selectorString}{${declarationString}}`;
@@ -94,10 +87,13 @@ export function genCssInJsInfo(styleInfo) {
94
87
  const oneCssInJsInfo = {};
95
88
  cssInfos.rules = cssInfos.rules.filter(oneCssInfo => {
96
89
  oneCssInfo.sel = oneCssInfo.sel.filter(selectorList => {
97
- const [classSelectors, pseudoClassSelectors, pseudoElementSelectors] = selectorList;
98
- if (classSelectors.length === 1 && classSelectors[0][0] === '.'
90
+ const [classSelectors, pseudoClassSelectors, pseudoElementSelectors, combinator,] = selectorList;
91
+ if (
92
+ // only one class selector
93
+ classSelectors.length === 1 && classSelectors[0][0] === '.'
99
94
  && pseudoClassSelectors.length === 0
100
- && pseudoElementSelectors.length === 0) {
95
+ && pseudoElementSelectors.length === 0
96
+ && combinator.length === 0) {
101
97
  const selectorName = classSelectors[0].substring(1);
102
98
  const currentDeclarations = oneCssInJsInfo[selectorName];
103
99
  if (currentDeclarations) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-mainthread-apis",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "keywords": [],
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "css-tree": "^3.1.0",
27
27
  "hyphenate-style-name": "^1.1.0",
28
- "@lynx-js/web-constants": "0.11.0",
29
- "@lynx-js/web-style-transformer": "0.2.3"
28
+ "@lynx-js/web-constants": "0.13.0",
29
+ "@lynx-js/web-style-transformer": "0.3.0"
30
30
  }
31
31
  }