@lynx-js/web-core 0.7.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +597 -0
  2. package/LICENSE.txt +202 -0
  3. package/Notice.txt +1 -0
  4. package/README.md +21 -0
  5. package/dist/apis/LynxView.d.ts +137 -0
  6. package/dist/apis/LynxView.js +368 -0
  7. package/dist/apis/createLynxView.d.ts +18 -0
  8. package/dist/apis/createLynxView.js +17 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.js +7 -0
  11. package/dist/types/LynxExposureModule.d.ts +4 -0
  12. package/dist/types/LynxExposureModule.js +5 -0
  13. package/dist/types/RuntimePropertyOnElement.d.ts +17 -0
  14. package/dist/types/RuntimePropertyOnElement.js +2 -0
  15. package/dist/types/UpdatePageCallback.d.ts +7 -0
  16. package/dist/types/UpdatePageCallback.js +2 -0
  17. package/dist/uiThread/bootWorkers.d.ts +8 -0
  18. package/dist/uiThread/bootWorkers.js +60 -0
  19. package/dist/uiThread/crossThreadHandlers/bootTimingSystem.d.ts +5 -0
  20. package/dist/uiThread/crossThreadHandlers/bootTimingSystem.js +50 -0
  21. package/dist/uiThread/crossThreadHandlers/createDispose.d.ts +3 -0
  22. package/dist/uiThread/crossThreadHandlers/createDispose.js +11 -0
  23. package/dist/uiThread/crossThreadHandlers/createExposureService.d.ts +2 -0
  24. package/dist/uiThread/crossThreadHandlers/createExposureService.js +55 -0
  25. package/dist/uiThread/crossThreadHandlers/createUpdateData.d.ts +3 -0
  26. package/dist/uiThread/crossThreadHandlers/createUpdateData.js +14 -0
  27. package/dist/uiThread/crossThreadHandlers/queryNodes.d.ts +2 -0
  28. package/dist/uiThread/crossThreadHandlers/queryNodes.js +65 -0
  29. package/dist/uiThread/crossThreadHandlers/registerFlushElementTreeHandler.d.ts +18 -0
  30. package/dist/uiThread/crossThreadHandlers/registerFlushElementTreeHandler.js +116 -0
  31. package/dist/uiThread/crossThreadHandlers/registerInvokeUIMethodHandler.d.ts +2 -0
  32. package/dist/uiThread/crossThreadHandlers/registerInvokeUIMethodHandler.js +51 -0
  33. package/dist/uiThread/crossThreadHandlers/registerLoadNewTagHandler.d.ts +3 -0
  34. package/dist/uiThread/crossThreadHandlers/registerLoadNewTagHandler.js +7 -0
  35. package/dist/uiThread/crossThreadHandlers/registerNativeModulesCallHandler.d.ts +3 -0
  36. package/dist/uiThread/crossThreadHandlers/registerNativeModulesCallHandler.js +5 -0
  37. package/dist/uiThread/crossThreadHandlers/registerReportErrorHandler.d.ts +2 -0
  38. package/dist/uiThread/crossThreadHandlers/registerReportErrorHandler.js +10 -0
  39. package/dist/uiThread/crossThreadHandlers/registerSelectComponentHandler.d.ts +2 -0
  40. package/dist/uiThread/crossThreadHandlers/registerSelectComponentHandler.js +15 -0
  41. package/dist/uiThread/crossThreadHandlers/registerSetNativePropsHandler.d.ts +2 -0
  42. package/dist/uiThread/crossThreadHandlers/registerSetNativePropsHandler.js +32 -0
  43. package/dist/uiThread/crossThreadHandlers/registerTriggerComponentEventHandler.d.ts +2 -0
  44. package/dist/uiThread/crossThreadHandlers/registerTriggerComponentEventHandler.js +14 -0
  45. package/dist/uiThread/decodeElementOperation.d.ts +13 -0
  46. package/dist/uiThread/decodeElementOperation.js +183 -0
  47. package/dist/uiThread/getElementTag.d.ts +1 -0
  48. package/dist/uiThread/getElementTag.js +20 -0
  49. package/dist/uiThread/startUIThread.d.ts +7 -0
  50. package/dist/uiThread/startUIThread.js +78 -0
  51. package/dist/utils/browser.d.ts +3 -0
  52. package/dist/utils/browser.js +9 -0
  53. package/dist/utils/createCrossThreadEvent.d.ts +2 -0
  54. package/dist/utils/createCrossThreadEvent.js +43 -0
  55. package/dist/utils/loadTemplate.d.ts +2 -0
  56. package/dist/utils/loadTemplate.js +53 -0
  57. package/index.css +66 -0
  58. package/package.json +34 -0
@@ -0,0 +1,368 @@
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 { createLynxView, } from './createLynxView.js';
5
+ import { cardIdAttribute, lynxViewEntryIdPrefix, lynxViewRootDomId, } from '@lynx-js/web-constants';
6
+ import { loadElement } from '@lynx-js/web-elements/lazy';
7
+ /**
8
+ * Based on our experiences, these elements are almost used in all lynx cards.
9
+ */
10
+ loadElement('lynx-wrapper');
11
+ loadElement('x-view');
12
+ loadElement('x-text');
13
+ loadElement('x-image');
14
+ loadElement('scroll-view');
15
+ /**
16
+ * @param {string} url [required] The url of the entry of your Lynx card
17
+ * @param {Cloneable} globalProps [optional] The globalProps value of this Lynx card
18
+ * @param {Cloneable} initData [oprional] The initial data of this Lynx card
19
+ * @param {Record<string,string>} overrideLynxTagToHTMLTagMap [optional] use this property/attribute to override the lynx tag -> html tag map
20
+ * @param {string} nativeModulesUrl [optional] It is a esm url, use to customize NativeModules.
21
+ * @param {INativeModulesCall} onNativeModulesCall [optional] the NativeModules value handler. Arguments will be cached before this property is assigned.
22
+ * @param {"auto" | null} height [optional] set it to "auto" for height auto-sizing
23
+ * @param {"auto" | null} width [optional] set it to "auto" for width auto-sizing
24
+ *
25
+ * @property entryId the currently Lynx view entryId.
26
+ *
27
+ * @event error lynx card fired an error
28
+ *
29
+ * @example
30
+ * HTML Exmaple
31
+ *
32
+ * Note that you should declarae the size of lynx-view
33
+ *
34
+ * ```html
35
+ * <lynx-view url="https://path/to/main-thread.js" rawData="{}" globalProps="{}" style="height:300px;width:300px">
36
+ * </lynx-view>
37
+ * ```
38
+ *
39
+ * React 19 Example
40
+ * ```jsx
41
+ * <lynx-view url={myLynxCardUrl} rawData={{}} globalProps={{}} style={{height:'300px', width:'300px'}}>
42
+ * </lynx-vew>
43
+ * ```
44
+ */
45
+ export class LynxView extends HTMLElement {
46
+ static lynxViewCount = 0;
47
+ static tag = 'lynx-view';
48
+ static observedAttributeAsProperties = [
49
+ 'url',
50
+ 'globalProps',
51
+ 'initData',
52
+ 'overrideLynxTagToHTMLTagMap',
53
+ 'nativeModulesUrl',
54
+ ];
55
+ static attributeCamelCaseMap = Object.fromEntries(this.observedAttributeAsProperties.map((nm) => [nm.toLocaleLowerCase(), nm]));
56
+ /**
57
+ * @private
58
+ */
59
+ static observedAttributes = LynxView.observedAttributeAsProperties.map(nm => nm.toLowerCase());
60
+ #instance;
61
+ #url;
62
+ /**
63
+ * @public
64
+ * @property the url of lynx view output entry file
65
+ */
66
+ get url() {
67
+ return this.#url;
68
+ }
69
+ set url(val) {
70
+ this.#url = val;
71
+ this.#render();
72
+ }
73
+ #globalProps = {};
74
+ /**
75
+ * @public
76
+ * @property globalProps
77
+ * @default {}
78
+ */
79
+ get globalProps() {
80
+ return this.#globalProps;
81
+ }
82
+ set globalProps(val) {
83
+ if (typeof val === 'string') {
84
+ this.#globalProps = JSON.parse(val);
85
+ }
86
+ else {
87
+ this.#globalProps = val;
88
+ }
89
+ }
90
+ #initData = {};
91
+ /**
92
+ * @public
93
+ * @property initData
94
+ * @default {}
95
+ */
96
+ get initData() {
97
+ return this.#initData;
98
+ }
99
+ set initData(val) {
100
+ if (typeof val === 'string') {
101
+ this.#initData = JSON.parse(val);
102
+ }
103
+ else {
104
+ this.#initData = val;
105
+ }
106
+ }
107
+ #entryId;
108
+ /**
109
+ * @public
110
+ * @readonly
111
+ * @property
112
+ * The random generated entryId of current lynxview
113
+ */
114
+ get entryId() {
115
+ return this.#entryId;
116
+ }
117
+ #overrideLynxTagToHTMLTagMap = { 'page': 'div' };
118
+ /**
119
+ * @public
120
+ * @property
121
+ * @default {page: 'div'}
122
+ */
123
+ get overrideLynxTagToHTMLTagMap() {
124
+ return this.#overrideLynxTagToHTMLTagMap;
125
+ }
126
+ set overrideLynxTagToHTMLTagMap(val) {
127
+ if (typeof val === 'string') {
128
+ this.#overrideLynxTagToHTMLTagMap = JSON.parse(val);
129
+ }
130
+ else {
131
+ this.#overrideLynxTagToHTMLTagMap = val;
132
+ }
133
+ }
134
+ #cachedNativeModulesCall = [];
135
+ #onNativeModulesCall;
136
+ /**
137
+ * @param
138
+ * @property
139
+ */
140
+ get onNativeModulesCall() {
141
+ return this.#onNativeModulesCall;
142
+ }
143
+ set onNativeModulesCall(handler) {
144
+ this.#onNativeModulesCall = handler;
145
+ if (this.#cachedNativeModulesCall) {
146
+ for (const callInfo of this.#cachedNativeModulesCall) {
147
+ handler.apply(undefined, callInfo);
148
+ }
149
+ }
150
+ }
151
+ #nativeModulesUrl;
152
+ /**
153
+ * @public
154
+ * @property nativeModules
155
+ */
156
+ get nativeModulesUrl() {
157
+ return this.#nativeModulesUrl;
158
+ }
159
+ set nativeModulesUrl(val) {
160
+ this.#nativeModulesUrl = val;
161
+ }
162
+ #autoHeight = false;
163
+ #autoWidth = false;
164
+ #currentWidth = 0;
165
+ #currentHeight = 0;
166
+ /**
167
+ * @public
168
+ * "auto" for auto calculated height
169
+ */
170
+ get height() {
171
+ return this.#autoHeight ? 'auto' : null;
172
+ }
173
+ /**
174
+ * @public
175
+ * "auto" for auto calculated width
176
+ */
177
+ get width() {
178
+ return this.#autoWidth ? 'auto' : null;
179
+ }
180
+ set height(val) {
181
+ this.#handleAutoSize();
182
+ this.#autoHeight = val === 'auto' ? true : false;
183
+ }
184
+ set width(val) {
185
+ this.#handleAutoSize();
186
+ this.#autoWidth = val === 'auto' ? true : false;
187
+ }
188
+ #handleAutoSize() {
189
+ if (this.#autoHeight || this.#autoWidth) {
190
+ if (this.#instance && !this.#instance.resizeObserver) {
191
+ this.#instance.resizeObserver = new ResizeObserver((sizes) => {
192
+ const size = sizes[0];
193
+ if (size) {
194
+ const { width, height } = size.contentRect;
195
+ if (this.#autoWidth) {
196
+ if (this.#currentWidth !== width) {
197
+ this.#currentWidth = width;
198
+ this.style.setProperty('--lynx-view-width', `${width}px`);
199
+ }
200
+ }
201
+ if (this.#autoHeight) {
202
+ if (this.#currentHeight !== height) {
203
+ this.#currentHeight = height;
204
+ this.style.setProperty('--lynx-view-height', `${height}px`);
205
+ }
206
+ }
207
+ }
208
+ });
209
+ this.#instance.resizeObserver.observe(this.#instance.rootDom);
210
+ }
211
+ }
212
+ else {
213
+ if (this.#instance?.resizeObserver) {
214
+ this.#instance.resizeObserver.disconnect();
215
+ }
216
+ }
217
+ if (this.#autoHeight) {
218
+ this.setAttribute('height', 'auto');
219
+ }
220
+ else {
221
+ this.removeAttribute('height');
222
+ }
223
+ if (this.#autoWidth) {
224
+ this.setAttribute('width', 'auto');
225
+ }
226
+ else {
227
+ this.removeAttribute('width');
228
+ }
229
+ }
230
+ /**
231
+ * @public
232
+ * @method
233
+ * update the `__initData` and trigger essential flow
234
+ */
235
+ updateData(data, updateDataType, callback) {
236
+ this.#instance?.lynxView.updateData(data, updateDataType, callback);
237
+ }
238
+ /**
239
+ * @public
240
+ * @method
241
+ * send global events, which can be listened to using the GlobalEventEmitter
242
+ */
243
+ sendGlobalEvent(eventName, params) {
244
+ this.#instance?.lynxView.sendGlobalEvent(eventName, params);
245
+ }
246
+ /**
247
+ * @public
248
+ * @method
249
+ * reload the current page
250
+ */
251
+ reload() {
252
+ this.#render();
253
+ }
254
+ /**
255
+ * @override
256
+ * "false" value will be omitted
257
+ *
258
+ * {@inheritdoc HTMLElement.setAttribute}
259
+ */
260
+ setAttribute(qualifiedName, value) {
261
+ if (value === 'false') {
262
+ this.removeAttribute(qualifiedName);
263
+ }
264
+ else {
265
+ super.setAttribute(qualifiedName, value);
266
+ }
267
+ }
268
+ /**
269
+ * @private
270
+ */
271
+ attributeChangedCallback(name, oldValue, newValue) {
272
+ if (oldValue !== newValue) {
273
+ name = LynxView.attributeCamelCaseMap[name] ?? name;
274
+ if (name in this) {
275
+ // @ts-expect-error
276
+ this[name] = newValue;
277
+ }
278
+ }
279
+ }
280
+ /**
281
+ * @private
282
+ */
283
+ disconnectedCallback() {
284
+ if (this.#instance) {
285
+ this.#instance.resizeObserver?.disconnect();
286
+ this.#instance.lynxView.dispose();
287
+ this.#instance.rootDom.remove();
288
+ }
289
+ this.#instance = undefined;
290
+ }
291
+ /**
292
+ * @private the flag to group all changes into one render operation
293
+ */
294
+ #rendering = false;
295
+ /**
296
+ * @private
297
+ */
298
+ #render() {
299
+ if (!this.#rendering) {
300
+ this.#rendering = true;
301
+ queueMicrotask(() => {
302
+ this.#rendering = false;
303
+ if (this.#instance) {
304
+ this.disconnectedCallback();
305
+ }
306
+ if (this.#url) {
307
+ const rootDom = document.createElement('div');
308
+ rootDom.id = lynxViewRootDomId;
309
+ const entryId = `${lynxViewEntryIdPrefix}-${LynxView
310
+ .lynxViewCount++}`;
311
+ this.#entryId = entryId;
312
+ rootDom.setAttribute(cardIdAttribute, entryId);
313
+ rootDom.setAttribute('part', lynxViewRootDomId);
314
+ const commonEventDetail = {
315
+ entryId,
316
+ };
317
+ const lynxView = createLynxView({
318
+ entryId,
319
+ rootDom,
320
+ templateUrl: this.#url,
321
+ globalProps: this.#globalProps,
322
+ initData: this.#initData,
323
+ overrideLynxTagToHTMLTagMap: this.#overrideLynxTagToHTMLTagMap,
324
+ nativeModulesUrl: this.#nativeModulesUrl,
325
+ callbacks: {
326
+ loadNewTag: loadElement,
327
+ nativeModulesCall: (...args) => {
328
+ if (this.#onNativeModulesCall) {
329
+ return this.#onNativeModulesCall(...args);
330
+ }
331
+ else if (this.#cachedNativeModulesCall) {
332
+ this.#cachedNativeModulesCall.push(args);
333
+ }
334
+ else {
335
+ this.#cachedNativeModulesCall = [args];
336
+ }
337
+ },
338
+ onError: () => {
339
+ this.dispatchEvent(new CustomEvent('error', {
340
+ detail: commonEventDetail,
341
+ }));
342
+ },
343
+ },
344
+ });
345
+ this.#instance = {
346
+ lynxView,
347
+ rootDom,
348
+ };
349
+ this.#handleAutoSize();
350
+ this.append(rootDom);
351
+ }
352
+ });
353
+ }
354
+ }
355
+ /**
356
+ * @private
357
+ */
358
+ connectedCallback() {
359
+ this.#render();
360
+ }
361
+ }
362
+ if (customElements.get(LynxView.tag)) {
363
+ console.warn(`[${LynxView.tag}] has already been defined`);
364
+ }
365
+ else {
366
+ customElements.define(LynxView.tag, LynxView);
367
+ }
368
+ //# sourceMappingURL=LynxView.js.map
@@ -0,0 +1,18 @@
1
+ import type { Cloneable, UpdateDataType } from '@lynx-js/web-constants';
2
+ import { startUIThread } from '../uiThread/startUIThread.js';
3
+ export interface LynxViewConfigs {
4
+ templateUrl: string;
5
+ initData: Cloneable;
6
+ globalProps: Cloneable;
7
+ entryId: string;
8
+ rootDom: HTMLElement;
9
+ callbacks: Parameters<typeof startUIThread>[3];
10
+ overrideLynxTagToHTMLTagMap?: Record<string, string>;
11
+ nativeModulesUrl: string | undefined;
12
+ }
13
+ export interface LynxView {
14
+ updateData(data: Cloneable, updateDataType: UpdateDataType, callback?: () => void): void;
15
+ dispose(): Promise<void>;
16
+ sendGlobalEvent(name: string, params?: Cloneable[]): void;
17
+ }
18
+ export declare function createLynxView(configs: LynxViewConfigs): LynxView;
@@ -0,0 +1,17 @@
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 { startUIThread } from '../uiThread/startUIThread.js';
5
+ import { supportAtScope } from '../utils/browser.js';
6
+ export function createLynxView(configs) {
7
+ const { rootDom, callbacks, templateUrl, globalProps, entryId, initData, overrideLynxTagToHTMLTagMap, nativeModulesUrl, } = configs;
8
+ return startUIThread(templateUrl, {
9
+ initData,
10
+ globalProps,
11
+ entryId,
12
+ browserConfig: {
13
+ supportAtScope,
14
+ },
15
+ }, rootDom, callbacks, overrideLynxTagToHTMLTagMap, nativeModulesUrl);
16
+ }
17
+ //# sourceMappingURL=createLynxView.js.map
@@ -0,0 +1,3 @@
1
+ export { createLynxView } from './apis/createLynxView.js';
2
+ export { LynxView } from './apis/LynxView.js';
3
+ export { lynxRuntimeValue } from '@lynx-js/web-constants';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
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
+ export { createLynxView } from './apis/createLynxView.js';
5
+ export { LynxView } from './apis/LynxView.js';
6
+ export { lynxRuntimeValue } from '@lynx-js/web-constants';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ export interface LynxExposureModule {
2
+ resumeExposure: () => void;
3
+ stopExposure: () => void;
4
+ }
@@ -0,0 +1,5 @@
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
+ export {};
5
+ //# sourceMappingURL=LynxExposureModule.js.map
@@ -0,0 +1,17 @@
1
+ import type { LynxEventType, Cloneable } from '@lynx-js/web-constants';
2
+ import { lynxRuntimeValue } from '@lynx-js/web-constants';
3
+ type RuntimeValue = {
4
+ dataset: {
5
+ [key: string]: Cloneable;
6
+ };
7
+ eventHandler: Record<string, {
8
+ type: LynxEventType;
9
+ handler: (ev: Event) => void;
10
+ hname: string;
11
+ } | undefined>;
12
+ [key: string]: any;
13
+ };
14
+ export type RuntimePropertyOnElement = {
15
+ [lynxRuntimeValue]: RuntimeValue;
16
+ };
17
+ export {};
@@ -0,0 +1,2 @@
1
+ import { lynxRuntimeValue } from '@lynx-js/web-constants';
2
+ //# sourceMappingURL=RuntimePropertyOnElement.js.map
@@ -0,0 +1,7 @@
1
+ export interface UpdatePageOption {
2
+ nativeUpdateDataOrder?: number;
3
+ reloadTemplate?: boolean;
4
+ reloadFromJS?: boolean;
5
+ resetPageData?: boolean;
6
+ }
7
+ export type UpdatePageCallback = (data: any, options: UpdatePageOption) => any;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=UpdatePageCallback.js.map
@@ -0,0 +1,8 @@
1
+ import { Rpc } from '@lynx-js/web-worker-rpc';
2
+ interface LynxViewRpc {
3
+ mainThreadRpc: Rpc;
4
+ backgroundRpc: Rpc;
5
+ terminateWorkers: () => void;
6
+ }
7
+ export declare function bootWorkers(): LynxViewRpc;
8
+ export {};
@@ -0,0 +1,60 @@
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 { Rpc } from '@lynx-js/web-worker-rpc';
5
+ let preHeatedMainWorker = createMainWorker();
6
+ export function bootWorkers() {
7
+ const curMainWorker = preHeatedMainWorker;
8
+ const curBackgroundWorker = createBackgroundWorker(curMainWorker.channelMainThreadWithBackground);
9
+ preHeatedMainWorker = createMainWorker();
10
+ return {
11
+ mainThreadRpc: curMainWorker.mainThreadRpc,
12
+ backgroundRpc: curBackgroundWorker.backgroundRpc,
13
+ terminateWorkers: () => {
14
+ curMainWorker.mainThreadWorker.terminate();
15
+ curBackgroundWorker.backgroundThreadWorker.terminate();
16
+ },
17
+ };
18
+ }
19
+ function createMainWorker() {
20
+ const channelToMainThread = new MessageChannel();
21
+ const channelMainThreadWithBackground = new MessageChannel();
22
+ const mainThreadWorker = new Worker(new URL('@lynx-js/web-worker-runtime', import.meta.url), {
23
+ type: 'module',
24
+ name: `lynx-main`,
25
+ });
26
+ const mainThreadMessage = {
27
+ mode: 'main',
28
+ toUIThread: channelToMainThread.port2,
29
+ toPeerThread: channelMainThreadWithBackground.port1,
30
+ };
31
+ mainThreadWorker.postMessage(mainThreadMessage, [
32
+ channelToMainThread.port2,
33
+ channelMainThreadWithBackground.port1,
34
+ ]);
35
+ const mainThreadRpc = new Rpc(channelToMainThread.port1, 'ui-to-main');
36
+ return {
37
+ mainThreadRpc,
38
+ mainThreadWorker,
39
+ channelMainThreadWithBackground,
40
+ };
41
+ }
42
+ function createBackgroundWorker(channelMainThreadWithBackground) {
43
+ const channelToBackground = new MessageChannel();
44
+ const backgroundThreadWorker = new Worker(new URL('@lynx-js/web-worker-runtime', import.meta.url), {
45
+ type: 'module',
46
+ name: `lynx-bg`,
47
+ });
48
+ const backgroundThreadMessage = {
49
+ mode: 'background',
50
+ toUIThread: channelToBackground.port2,
51
+ toPeerThread: channelMainThreadWithBackground.port2,
52
+ };
53
+ backgroundThreadWorker.postMessage(backgroundThreadMessage, [
54
+ channelToBackground.port2,
55
+ channelMainThreadWithBackground.port2,
56
+ ]);
57
+ const backgroundRpc = new Rpc(channelToBackground.port1, 'ui-to-bg');
58
+ return { backgroundRpc, backgroundThreadWorker };
59
+ }
60
+ //# sourceMappingURL=bootWorkers.js.map
@@ -0,0 +1,5 @@
1
+ import type { Rpc } from '@lynx-js/web-worker-rpc';
2
+ export declare function bootTimingSystem(mainThreadRpc: Rpc, backgroundThreadRpc: Rpc, rootDom: HTMLElement): {
3
+ markTimingInternal: (timingKey: string, pipelineId?: string, timeStamp?: number) => void;
4
+ sendTimingResult: (pipelineId: string | undefined, timingFlags: string[], isFp: boolean) => void;
5
+ };
@@ -0,0 +1,50 @@
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 { postTimingInfoFromBackgroundThread, postTimingInfoFromMainThread, postTimingResult, } from '@lynx-js/web-constants';
5
+ export function bootTimingSystem(mainThreadRpc, backgroundThreadRpc, rootDom) {
6
+ const setupTiming = {};
7
+ const pipelineIdToTiming = new Map();
8
+ let commonTimingFlags = [];
9
+ function markTimingInternal(timingKey, pipelineId, timeStamp) {
10
+ if (!timeStamp)
11
+ timeStamp = performance.now() + performance.timeOrigin;
12
+ if (!pipelineId) {
13
+ setupTiming[timingKey] = timeStamp;
14
+ return;
15
+ }
16
+ if (!pipelineIdToTiming.has(pipelineId)) {
17
+ pipelineIdToTiming.set(pipelineId, {});
18
+ }
19
+ const timingInfo = pipelineIdToTiming.get(pipelineId);
20
+ timingInfo[timingKey] = timeStamp;
21
+ }
22
+ function sendTimingResult(pipelineId, timingFlags, isFp) {
23
+ const timingInfo = (pipelineId ? pipelineIdToTiming.get(pipelineId) : undefined) ?? {};
24
+ if (!pipelineId)
25
+ commonTimingFlags = commonTimingFlags.concat(timingFlags);
26
+ else
27
+ timingFlags = timingFlags.concat(commonTimingFlags);
28
+ backgroundThreadRpc.invoke(postTimingResult, [
29
+ pipelineId,
30
+ timingInfo,
31
+ timingFlags,
32
+ isFp ? setupTiming : undefined,
33
+ ]);
34
+ rootDom.dispatchEvent(new CustomEvent('timing', {
35
+ detail: isFp ? setupTiming : timingInfo,
36
+ bubbles: true,
37
+ cancelable: true,
38
+ }));
39
+ if (pipelineId) {
40
+ pipelineIdToTiming.delete(pipelineId);
41
+ }
42
+ }
43
+ mainThreadRpc.registerHandler(postTimingInfoFromMainThread, markTimingInternal);
44
+ backgroundThreadRpc.registerHandler(postTimingInfoFromBackgroundThread, markTimingInternal);
45
+ return {
46
+ markTimingInternal,
47
+ sendTimingResult,
48
+ };
49
+ }
50
+ //# sourceMappingURL=bootTimingSystem.js.map
@@ -0,0 +1,3 @@
1
+ import type { Rpc } from '@lynx-js/web-worker-rpc';
2
+ import type { LynxView } from '../../apis/createLynxView.js';
3
+ export declare function createDispose(rpc: Rpc, terminateWorkers: () => void): LynxView['dispose'];
@@ -0,0 +1,11 @@
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 { disposeEndpoint } from '@lynx-js/web-constants';
5
+ export function createDispose(rpc, terminateWorkers) {
6
+ return async () => {
7
+ await rpc.invoke(disposeEndpoint, []);
8
+ terminateWorkers();
9
+ };
10
+ }
11
+ //# sourceMappingURL=createDispose.js.map
@@ -0,0 +1,2 @@
1
+ import type { Rpc } from '@lynx-js/web-worker-rpc';
2
+ export declare function createExposureService(rpc: Rpc, rootDom: Element): void;
@@ -0,0 +1,55 @@
1
+ import { lynxUniqueIdAttribute, postExposureEndpoint, switchExposureService, } from '@lynx-js/web-constants';
2
+ import { createCrossThreadEvent } from '../../utils/createCrossThreadEvent.js';
3
+ export function createExposureService(rpc, rootDom) {
4
+ let working = true;
5
+ let exposureCache = [];
6
+ let disexposureCache = [];
7
+ const onScreen = new Map();
8
+ async function exposureEventHandler(ev) {
9
+ const exposureEvent = createCrossThreadEvent(ev);
10
+ exposureEvent.detail['unique-id'] = parseFloat(ev.target.getAttribute(lynxUniqueIdAttribute));
11
+ const exposureID = exposureEvent.exposureID;
12
+ if (ev.type === 'exposure') {
13
+ exposureCache.push(exposureEvent);
14
+ onScreen.set(exposureID, exposureEvent);
15
+ }
16
+ else {
17
+ disexposureCache.push(exposureEvent);
18
+ onScreen.delete(exposureID);
19
+ }
20
+ }
21
+ setInterval(() => {
22
+ if (exposureCache.length > 0 || disexposureCache.length > 0) {
23
+ const currentExposure = exposureCache;
24
+ const currentDisexposure = disexposureCache;
25
+ exposureCache = [];
26
+ disexposureCache = [];
27
+ rpc.invoke(postExposureEndpoint, [{
28
+ exposures: currentExposure,
29
+ disExposures: currentDisexposure,
30
+ }]);
31
+ }
32
+ }, 1000 / 20);
33
+ rootDom.addEventListener('exposure', exposureEventHandler, { passive: true });
34
+ rootDom.addEventListener('disexposure', exposureEventHandler, {
35
+ passive: true,
36
+ });
37
+ rpc.registerHandler(switchExposureService, async (enable, sendEvent) => {
38
+ if (enable && !working) {
39
+ // send all onScreen info
40
+ rpc.invoke(postExposureEndpoint, [{
41
+ exposures: [...onScreen.values()],
42
+ disExposures: [],
43
+ }]);
44
+ }
45
+ else if (!enable && working) {
46
+ if (sendEvent) {
47
+ rpc.invoke(postExposureEndpoint, [{
48
+ exposures: [],
49
+ disExposures: [...onScreen.values()],
50
+ }]);
51
+ }
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=createExposureService.js.map
@@ -0,0 +1,3 @@
1
+ import type { Rpc } from '@lynx-js/web-worker-rpc';
2
+ import type { LynxView } from '../../apis/createLynxView.js';
3
+ export declare function createUpdateData(mainThreadRpc: Rpc, backgroundRpc: Rpc): LynxView['updateData'];