@lynx-js/web-core-wasm-canary 0.0.0 → 0.0.1-canary-20260116-ce265e8f

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 (204) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/{LICENSE → LICENSE.txt} +1 -1
  3. package/Notice.txt +1 -0
  4. package/README.md +1 -0
  5. package/binary/client/client.d.ts +263 -0
  6. package/binary/client/client.js +1339 -0
  7. package/binary/client/client_bg.wasm +0 -0
  8. package/binary/client/client_bg.wasm.d.ts +70 -0
  9. package/binary/client/client_debug.d.ts +263 -0
  10. package/binary/client/client_debug.js +1339 -0
  11. package/binary/client/client_debug_bg.wasm +0 -0
  12. package/binary/client/client_debug_bg.wasm.d.ts +70 -0
  13. package/binary/encode/encode.d.ts +157 -0
  14. package/binary/encode/encode.js +17 -0
  15. package/binary/encode/encode_bg.js +749 -0
  16. package/binary/encode/encode_bg.wasm +0 -0
  17. package/binary/encode/encode_bg.wasm.d.ts +50 -0
  18. package/binary/encode/encode_debug.d.ts +157 -0
  19. package/binary/encode/encode_debug.js +17 -0
  20. package/binary/encode/encode_debug_bg.js +822 -0
  21. package/binary/encode/encode_debug_bg.wasm +0 -0
  22. package/binary/encode/encode_debug_bg.wasm.d.ts +50 -0
  23. package/binary/encode/package.json +4 -0
  24. package/css/in_shadow.css +10 -0
  25. package/css/index.css +119 -0
  26. package/dist/client/LynxCrossThreadContext.d.ts +22 -0
  27. package/dist/client/LynxCrossThreadContext.js +44 -0
  28. package/dist/client/background/background-apis/createBackgroundLynx.d.ts +24 -0
  29. package/dist/client/background/background-apis/createBackgroundLynx.js +38 -0
  30. package/dist/client/background/background-apis/createChunkLoading.d.ts +7 -0
  31. package/dist/client/background/background-apis/createChunkLoading.js +66 -0
  32. package/dist/client/background/background-apis/createElement.d.ts +5 -0
  33. package/dist/client/background/background-apis/createElement.js +18 -0
  34. package/dist/client/background/background-apis/createNapiLoader.d.ts +5 -0
  35. package/dist/client/background/background-apis/createNapiLoader.js +23 -0
  36. package/dist/client/background/background-apis/createNativeApp.d.ts +4 -0
  37. package/dist/client/background/background-apis/createNativeApp.js +98 -0
  38. package/dist/client/background/background-apis/createNativeModules.d.ts +3 -0
  39. package/dist/client/background/background-apis/createNativeModules.js +33 -0
  40. package/dist/client/background/background-apis/createPerformanceApis.d.ts +3 -0
  41. package/dist/client/background/background-apis/createPerformanceApis.js +47 -0
  42. package/dist/client/background/background-apis/createTimingSystem.d.ts +8 -0
  43. package/dist/client/background/background-apis/createTimingSystem.js +86 -0
  44. package/dist/client/background/background-apis/crossThreadHandlers/createGetCustomSection.d.ts +3 -0
  45. package/dist/client/background/background-apis/crossThreadHandlers/createGetCustomSection.js +14 -0
  46. package/dist/client/background/background-apis/crossThreadHandlers/createGetPathInfo.d.ts +3 -0
  47. package/dist/client/background/background-apis/crossThreadHandlers/createGetPathInfo.js +23 -0
  48. package/dist/client/background/background-apis/crossThreadHandlers/createInvokeUIMethod.d.ts +3 -0
  49. package/dist/client/background/background-apis/crossThreadHandlers/createInvokeUIMethod.js +24 -0
  50. package/dist/client/background/background-apis/crossThreadHandlers/createJSObjectDestructionObserver.d.ts +2 -0
  51. package/dist/client/background/background-apis/crossThreadHandlers/createJSObjectDestructionObserver.js +12 -0
  52. package/dist/client/background/background-apis/crossThreadHandlers/registerDisposeHandler.d.ts +3 -0
  53. package/dist/client/background/background-apis/crossThreadHandlers/registerDisposeHandler.js +9 -0
  54. package/dist/client/background/background-apis/crossThreadHandlers/registerPublicComponentEventHandler.d.ts +3 -0
  55. package/dist/client/background/background-apis/crossThreadHandlers/registerPublicComponentEventHandler.js +8 -0
  56. package/dist/client/background/background-apis/crossThreadHandlers/registerPublishEventHandler.d.ts +3 -0
  57. package/dist/client/background/background-apis/crossThreadHandlers/registerPublishEventHandler.js +8 -0
  58. package/dist/client/background/background-apis/crossThreadHandlers/registerSendGlobalEvent.d.ts +3 -0
  59. package/dist/client/background/background-apis/crossThreadHandlers/registerSendGlobalEvent.js +10 -0
  60. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateDataHandler.d.ts +3 -0
  61. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateDataHandler.js +5 -0
  62. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateGlobalPropsHandler.d.ts +3 -0
  63. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateGlobalPropsHandler.js +5 -0
  64. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateI18nResource.d.ts +3 -0
  65. package/dist/client/background/background-apis/crossThreadHandlers/registerUpdateI18nResource.js +9 -0
  66. package/dist/client/background/background-apis/startBackgroundThread.d.ts +2 -0
  67. package/dist/client/background/background-apis/startBackgroundThread.js +42 -0
  68. package/dist/client/background/index.d.ts +1 -0
  69. package/dist/client/background/index.js +15 -0
  70. package/dist/client/decodeWorker/cssLoader.d.ts +12 -0
  71. package/dist/client/decodeWorker/cssLoader.js +96 -0
  72. package/dist/client/decodeWorker/decode.worker.d.ts +1 -0
  73. package/dist/client/decodeWorker/decode.worker.js +338 -0
  74. package/dist/client/decodeWorker/types.d.ts +32 -0
  75. package/dist/client/decodeWorker/types.js +2 -0
  76. package/dist/client/endpoints.d.ts +53 -0
  77. package/dist/client/endpoints.js +37 -0
  78. package/dist/client/index.d.ts +3 -0
  79. package/dist/client/index.js +3 -0
  80. package/dist/client/mainthread/Background.d.ts +30 -0
  81. package/dist/client/mainthread/Background.js +207 -0
  82. package/dist/client/mainthread/ExposureServices.d.ts +11 -0
  83. package/dist/client/mainthread/ExposureServices.js +211 -0
  84. package/dist/client/mainthread/I18n.d.ts +9 -0
  85. package/dist/client/mainthread/I18n.js +44 -0
  86. package/dist/client/mainthread/LynxView.d.ts +170 -0
  87. package/dist/client/mainthread/LynxView.js +367 -0
  88. package/dist/client/mainthread/LynxViewInstance.d.ts +56 -0
  89. package/dist/client/mainthread/LynxViewInstance.js +196 -0
  90. package/dist/client/mainthread/StyleManager.d.ts +15 -0
  91. package/dist/client/mainthread/StyleManager.js +72 -0
  92. package/dist/client/mainthread/TemplateManager.d.ts +11 -0
  93. package/dist/client/mainthread/TemplateManager.js +257 -0
  94. package/dist/client/mainthread/createIFrameRealm.d.ts +6 -0
  95. package/dist/client/mainthread/createIFrameRealm.js +68 -0
  96. package/dist/client/mainthread/createMainThreadGlobalAPIs.d.ts +3 -0
  97. package/dist/client/mainthread/createMainThreadGlobalAPIs.js +82 -0
  98. package/dist/client/mainthread/crossThreadHandlers/queryNodes.d.ts +3 -0
  99. package/dist/client/mainthread/crossThreadHandlers/queryNodes.js +74 -0
  100. package/dist/client/mainthread/crossThreadHandlers/registerGetPathInfoHandler.d.ts +3 -0
  101. package/dist/client/mainthread/crossThreadHandlers/registerGetPathInfoHandler.js +51 -0
  102. package/dist/client/mainthread/crossThreadHandlers/registerInvokeUIMethodHandler.d.ts +3 -0
  103. package/dist/client/mainthread/crossThreadHandlers/registerInvokeUIMethodHandler.js +49 -0
  104. package/dist/client/mainthread/crossThreadHandlers/registerNapiModulesCallHandler.d.ts +3 -0
  105. package/dist/client/mainthread/crossThreadHandlers/registerNapiModulesCallHandler.js +8 -0
  106. package/dist/client/mainthread/crossThreadHandlers/registerNativeModulesCallHandler.d.ts +3 -0
  107. package/dist/client/mainthread/crossThreadHandlers/registerNativeModulesCallHandler.js +7 -0
  108. package/dist/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.d.ts +3 -0
  109. package/dist/client/mainthread/crossThreadHandlers/registerSelectComponentHandler.js +20 -0
  110. package/dist/client/mainthread/crossThreadHandlers/registerSetNativePropsHandler.d.ts +3 -0
  111. package/dist/client/mainthread/crossThreadHandlers/registerSetNativePropsHandler.js +28 -0
  112. package/dist/client/mainthread/crossThreadHandlers/registerTriggerComponentEventHandler.d.ts +3 -0
  113. package/dist/client/mainthread/crossThreadHandlers/registerTriggerComponentEventHandler.js +12 -0
  114. package/dist/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.d.ts +3 -0
  115. package/dist/client/mainthread/crossThreadHandlers/registerTriggerElementMethodEndpointHandler.js +29 -0
  116. package/dist/client/mainthread/elementAPIs/WASMJSBinding.d.ts +38 -0
  117. package/dist/client/mainthread/elementAPIs/WASMJSBinding.js +122 -0
  118. package/dist/client/mainthread/elementAPIs/createCrossThreadEvent.d.ts +2 -0
  119. package/dist/client/mainthread/elementAPIs/createCrossThreadEvent.js +77 -0
  120. package/dist/client/mainthread/elementAPIs/createElementAPI.d.ts +3 -0
  121. package/dist/client/mainthread/elementAPIs/createElementAPI.js +346 -0
  122. package/dist/client/mainthread/elementAPIs/index.d.ts +2 -0
  123. package/dist/client/mainthread/elementAPIs/index.js +3 -0
  124. package/dist/client/mainthread/elementAPIs/pureElementPAPIs.d.ts +26 -0
  125. package/dist/client/mainthread/elementAPIs/pureElementPAPIs.js +85 -0
  126. package/dist/client/mainthread/utils/convertLengthToPx.d.ts +1 -0
  127. package/dist/client/mainthread/utils/convertLengthToPx.js +25 -0
  128. package/dist/client/wasm.d.ts +11 -0
  129. package/dist/client/wasm.js +52 -0
  130. package/dist/client/webElementsDynamicLoader.d.ts +8 -0
  131. package/dist/client/webElementsDynamicLoader.js +80 -0
  132. package/dist/client_prod/static/css/async/web-core-main-chunk.css +1 -0
  133. package/dist/client_prod/static/css/client.css +1 -0
  134. package/dist/client_prod/static/js/async/lynx-core-chunk.js +3 -0
  135. package/dist/client_prod/static/js/async/web-core-main-chunk.js +303 -0
  136. package/dist/client_prod/static/js/async/web-core-template-loader-thread.js +8 -0
  137. package/dist/client_prod/static/js/async/web-core-worker-chunk.js +1 -0
  138. package/dist/client_prod/static/js/async/web-elements-audio.js +1 -0
  139. package/dist/client_prod/static/js/async/web-elements-foldview.js +1 -0
  140. package/dist/client_prod/static/js/async/web-elements-input.js +1 -0
  141. package/dist/client_prod/static/js/async/web-elements-list.js +1 -0
  142. package/dist/client_prod/static/js/async/web-elements-overlay.js +1 -0
  143. package/dist/client_prod/static/js/async/web-elements-refrshview.js +1 -0
  144. package/dist/client_prod/static/js/async/web-elements-swiper.js +1 -0
  145. package/dist/client_prod/static/js/async/web-elements-textarea.js +1 -0
  146. package/dist/client_prod/static/js/async/web-elements-viewpager.js +1 -0
  147. package/dist/client_prod/static/js/client.js +2 -0
  148. package/dist/client_prod/static/wasm/7ff75609.module.wasm +0 -0
  149. package/dist/constants.d.ts +58 -0
  150. package/dist/constants.js +114 -0
  151. package/dist/encode/encodeCSS.d.ts +3 -0
  152. package/dist/encode/encodeCSS.js +99 -0
  153. package/dist/encode/encodeElementTemplate.d.ts +2 -0
  154. package/dist/encode/encodeElementTemplate.js +52 -0
  155. package/dist/encode/index.d.ts +1 -0
  156. package/dist/encode/index.js +7 -0
  157. package/dist/encode/webEncoder.d.ts +21 -0
  158. package/dist/encode/webEncoder.js +125 -0
  159. package/dist/types/BTSChunk.d.ts +3 -0
  160. package/dist/types/BTSChunk.js +5 -0
  161. package/dist/types/Cloneable.d.ts +2 -0
  162. package/dist/types/Cloneable.js +2 -0
  163. package/dist/types/DecodedTemplate.d.ts +10 -0
  164. package/dist/types/DecodedTemplate.js +7 -0
  165. package/dist/types/Element.d.ts +35 -0
  166. package/dist/types/Element.js +5 -0
  167. package/dist/types/ElementTemplateData.d.ts +15 -0
  168. package/dist/types/ElementTemplateData.js +7 -0
  169. package/dist/types/EventType.d.ts +56 -0
  170. package/dist/types/EventType.js +5 -0
  171. package/dist/types/I18nTypes.d.ts +21 -0
  172. package/dist/types/I18nTypes.js +2 -0
  173. package/dist/types/IElementPAPI.d.ts +184 -0
  174. package/dist/types/IElementPAPI.js +2 -0
  175. package/dist/types/IMtsBinding.d.ts +11 -0
  176. package/dist/types/IMtsBinding.js +7 -0
  177. package/dist/types/JSRealm.d.ts +5 -0
  178. package/dist/types/JSRealm.js +7 -0
  179. package/dist/types/LynxContextEventTarget.d.ts +12 -0
  180. package/dist/types/LynxContextEventTarget.js +5 -0
  181. package/dist/types/MainThreadLynx.d.ts +15 -0
  182. package/dist/types/MainThreadLynx.js +2 -0
  183. package/dist/types/NapiModules.d.ts +9 -0
  184. package/dist/types/NapiModules.js +5 -0
  185. package/dist/types/NativeApp.d.ts +120 -0
  186. package/dist/types/NativeApp.js +5 -0
  187. package/dist/types/NativeModules.d.ts +2 -0
  188. package/dist/types/NativeModules.js +5 -0
  189. package/dist/types/PageConfig.d.ts +9 -0
  190. package/dist/types/PageConfig.js +2 -0
  191. package/dist/types/ProcessDataCallback.d.ts +1 -0
  192. package/dist/types/ProcessDataCallback.js +2 -0
  193. package/dist/types/TimingAPIs.d.ts +32 -0
  194. package/dist/types/TimingAPIs.js +5 -0
  195. package/dist/types/UpdateDataOptions.d.ts +8 -0
  196. package/dist/types/UpdateDataOptions.js +6 -0
  197. package/dist/types/WorkerStartMessage.d.ts +14 -0
  198. package/dist/types/WorkerStartMessage.js +5 -0
  199. package/dist/types/index.d.ts +20 -0
  200. package/dist/types/index.js +7 -0
  201. package/eslint.config.js +34 -0
  202. package/package.json +87 -4
  203. package/index.js +0 -1
  204. package/selfIdentity.plist +0 -0
@@ -0,0 +1,207 @@
1
+ /*
2
+ * Copyright (C) 2025 The Lynx Authors. All rights reserved.
3
+ * Licensed under the Apache License Version 2.0 that can be found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import { Rpc } from '@lynx-js/web-worker-rpc';
7
+ import { dispatchCoreContextOnBackgroundEndpoint, dispatchJSContextOnMainThreadEndpoint, disposeEndpoint, markTimingEndpoint, postTimingFlagsEndpoint, publicComponentEventEndpoint, publishEventEndpoint, sendGlobalEventEndpoint, dispatchI18nResourceEndpoint, updateDataEndpoint, updateGlobalPropsEndpoint, BackgroundThreadStartEndpoint, callLepusMethodEndpoint, switchExposureServiceEndpoint, reportErrorEndpoint, dispatchLynxViewEventEndpoint, updateBTSChunkEndpoint, queryComponentEndpoint, } from '../endpoints.js';
8
+ import { LynxCrossThreadContext } from '../LynxCrossThreadContext.js';
9
+ import { systemInfo } from './LynxViewInstance.js';
10
+ import { registerInvokeUIMethodHandler } from './crossThreadHandlers/registerInvokeUIMethodHandler.js';
11
+ import { registerNativePropsHandler } from './crossThreadHandlers/registerSetNativePropsHandler.js';
12
+ import { registerGetPathInfoHandler } from './crossThreadHandlers/registerGetPathInfoHandler.js';
13
+ import { registerSelectComponentHandler } from './crossThreadHandlers/registerSelectComponentHandler.js';
14
+ import { registerTriggerComponentEventHandler } from './crossThreadHandlers/registerTriggerComponentEventHandler.js';
15
+ import { registerTriggerElementMethodEndpointHandler } from './crossThreadHandlers/registerTriggerElementMethodEndpointHandler.js';
16
+ import { registerNapiModulesCallHandler } from './crossThreadHandlers/registerNapiModulesCallHandler.js';
17
+ import { registerNativeModulesCallHandler } from './crossThreadHandlers/registerNativeModulesCallHandler.js';
18
+ function createWebWorker() {
19
+ return new Worker(
20
+ /* webpackFetchPriority: "high" */
21
+ /* webpackChunkName: "web-core-worker-chunk" */
22
+ /* webpackPrefetch: true */
23
+ /* webpackPreload: true */
24
+ new URL('../background/index.js', import.meta.url), {
25
+ type: 'module',
26
+ name: 'lynx-bg',
27
+ });
28
+ }
29
+ export class BackgroundThread {
30
+ static contextIdToBackgroundWorker = [];
31
+ #rpc;
32
+ #webWorker;
33
+ #nextMacroTask = null;
34
+ #caughtTimingInfo = [];
35
+ #batchSendTimingInfo;
36
+ jsContext;
37
+ postTimingFlags;
38
+ sendGlobalEvent;
39
+ publicComponentEvent;
40
+ publishEvent;
41
+ dispatchI18nResource;
42
+ updateData;
43
+ updateGlobalProps;
44
+ updateBTSChunk;
45
+ #lynxGroupId;
46
+ #lynxViewInstance;
47
+ #btsReady;
48
+ #btsReadyResolver;
49
+ #btsStarted = false;
50
+ constructor(lynxGroupId, lynxViewInstance) {
51
+ this.#lynxGroupId = lynxGroupId;
52
+ this.#lynxViewInstance = lynxViewInstance;
53
+ const btsRpc = new Rpc(undefined, 'main-to-bg');
54
+ this.#rpc = btsRpc;
55
+ this.jsContext = new LynxCrossThreadContext({
56
+ rpc: this.#rpc,
57
+ receiveEventEndpoint: dispatchJSContextOnMainThreadEndpoint,
58
+ sendEventEndpoint: dispatchCoreContextOnBackgroundEndpoint,
59
+ });
60
+ this.#btsReady = new Promise((resolve) => {
61
+ this.#btsReadyResolver = resolve;
62
+ });
63
+ this.jsContext.__start();
64
+ this.#batchSendTimingInfo = this.#rpc.createCall(markTimingEndpoint);
65
+ this.postTimingFlags = this.#rpc.createCall(postTimingFlagsEndpoint);
66
+ this.sendGlobalEvent = this.#rpc.createCall(sendGlobalEventEndpoint);
67
+ this.publicComponentEvent = this.#rpc.createCall(publicComponentEventEndpoint);
68
+ this.publishEvent = this.#rpc.createCall(publishEventEndpoint);
69
+ this.dispatchI18nResource = this.#rpc.createCall(dispatchI18nResourceEndpoint);
70
+ this.updateData = this.#rpc.createCall(updateDataEndpoint);
71
+ this.updateGlobalProps = this.#rpc.createCall(updateGlobalPropsEndpoint);
72
+ this.updateBTSChunk = this.#rpc.createCall(updateBTSChunkEndpoint);
73
+ }
74
+ startWebWorker(initData, globalProps, cardType, customSections, nativeModulesMap, napiModulesMap) {
75
+ if (this.#webWorker)
76
+ return;
77
+ // now start the background worker
78
+ if (this.#lynxGroupId !== undefined) {
79
+ const group = BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId];
80
+ if (group) {
81
+ group.runningCards += 1;
82
+ }
83
+ else {
84
+ BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId] = {
85
+ worker: createWebWorker(),
86
+ runningCards: 1,
87
+ };
88
+ }
89
+ this.#webWorker = BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId].worker;
90
+ }
91
+ else {
92
+ this.#webWorker = createWebWorker();
93
+ }
94
+ const messageChannel = new MessageChannel();
95
+ this.#webWorker.postMessage({
96
+ mainThreadMessagePort: messageChannel.port2,
97
+ systemInfo,
98
+ initData,
99
+ globalProps,
100
+ cardType,
101
+ customSections,
102
+ nativeModulesMap,
103
+ napiModulesMap,
104
+ entryTemplateUrl: this.#lynxViewInstance.templateUrl,
105
+ }, [messageChannel.port2]);
106
+ this.#rpc.setMessagePort(messageChannel.port1);
107
+ }
108
+ startBTS() {
109
+ if (this.#btsStarted)
110
+ return;
111
+ this.#btsStarted = true;
112
+ // prepare bts rpc handlers
113
+ this.#rpc.registerHandler(callLepusMethodEndpoint, (methodName, data) => {
114
+ const method = this.#lynxViewInstance.mainThreadGlobalThis[methodName];
115
+ if (typeof method === 'function') {
116
+ method.call(this.#lynxViewInstance.mainThreadGlobalThis, data);
117
+ }
118
+ else {
119
+ console.error(`Method ${methodName} not found on mainThreadGlobalThis`);
120
+ }
121
+ });
122
+ this.#rpc.registerHandler(switchExposureServiceEndpoint, this.#lynxViewInstance.exposureServices.switchExposureService.bind(this.#lynxViewInstance.exposureServices));
123
+ this.#rpc.registerHandler(reportErrorEndpoint, (e, _, release) => {
124
+ this.#lynxViewInstance.reportError(e, release, 'app-service.js');
125
+ });
126
+ this.#rpc.registerHandler(dispatchLynxViewEventEndpoint, (eventType, detail) => {
127
+ this.#lynxViewInstance.rootDom.dispatchEvent(new CustomEvent(eventType, {
128
+ detail,
129
+ bubbles: true,
130
+ cancelable: true,
131
+ composed: true,
132
+ }));
133
+ });
134
+ this.#rpc.registerHandler(queryComponentEndpoint, (url) => {
135
+ return this.#lynxViewInstance.queryComponent(url).then(() => {
136
+ this.jsContext.dispatchEvent({
137
+ type: '__OnDynamicJSSourcePrepared',
138
+ data: url,
139
+ });
140
+ return {
141
+ code: 0,
142
+ detail: {
143
+ schema: url,
144
+ },
145
+ };
146
+ });
147
+ });
148
+ registerGetPathInfoHandler(this.#rpc, this.#lynxViewInstance);
149
+ registerInvokeUIMethodHandler(this.#rpc, this.#lynxViewInstance);
150
+ registerNapiModulesCallHandler(this.#rpc, this.#lynxViewInstance);
151
+ registerNativeModulesCallHandler(this.#rpc, this.#lynxViewInstance);
152
+ registerSelectComponentHandler(this.#rpc, this.#lynxViewInstance);
153
+ registerNativePropsHandler(this.#rpc, this.#lynxViewInstance);
154
+ registerTriggerComponentEventHandler(this.#rpc, this.#lynxViewInstance);
155
+ registerTriggerElementMethodEndpointHandler(this.#rpc, this.#lynxViewInstance);
156
+ this.#rpc.invoke(BackgroundThreadStartEndpoint, []).then(this.#btsReadyResolver);
157
+ }
158
+ markTiming(timingKey, pipelineId, timeStamp) {
159
+ this.#caughtTimingInfo.push({
160
+ timingKey,
161
+ pipelineId,
162
+ timeStamp: timeStamp ?? (performance.now() + performance.timeOrigin),
163
+ });
164
+ if (this.#nextMacroTask === null) {
165
+ this.#nextMacroTask = setTimeout(() => {
166
+ this.flushTimingInfo();
167
+ }, 500);
168
+ }
169
+ }
170
+ /**
171
+ * Flush the timing info immediately.
172
+ */
173
+ flushTimingInfo() {
174
+ this.#batchSendTimingInfo(this.#caughtTimingInfo);
175
+ this.#caughtTimingInfo = [];
176
+ if (this.#nextMacroTask !== null) {
177
+ clearTimeout(this.#nextMacroTask);
178
+ this.#nextMacroTask = null;
179
+ }
180
+ }
181
+ async [Symbol.asyncDispose]() {
182
+ await this.#btsReady;
183
+ /*
184
+ * TODO:
185
+ * Potential deadlock if startBTS() was never called.
186
+ * If [Symbol.asyncDispose]() is invoked on a BackgroundThread instance where startBTS() was never called,
187
+ * #btsReady will never resolve, causing the disposal to hang indefinitely.
188
+ * Consider guarding with the existing #btsStarted flag.
189
+ */
190
+ await this.#rpc.invoke(disposeEndpoint, []);
191
+ if (this.#lynxGroupId !== undefined) {
192
+ const group = BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId];
193
+ if (group) {
194
+ group.runningCards -= 1;
195
+ if (group.runningCards === 0) {
196
+ group.worker.terminate();
197
+ BackgroundThread.contextIdToBackgroundWorker[this.#lynxGroupId] = undefined;
198
+ }
199
+ }
200
+ }
201
+ else {
202
+ this.#webWorker?.terminate();
203
+ }
204
+ this.#nextMacroTask && clearTimeout(this.#nextMacroTask);
205
+ }
206
+ }
207
+ //# sourceMappingURL=Background.js.map
@@ -0,0 +1,11 @@
1
+ import type { LynxViewInstance } from './LynxViewInstance.js';
2
+ export declare class ExposureServices {
3
+ #private;
4
+ constructor(lynxViewInstance: LynxViewInstance);
5
+ /**
6
+ * diff the current exposure enabled elements with the previous ones, and start/stop IntersectionObserver accordingly
7
+ * If an element's exposure-id attribute has changed, we also need to send a new disexposure event with the old one
8
+ */
9
+ updateExposureStatus(elementsToBeEnabled: HTMLElement[], elementsToBeDisabled: HTMLElement[]): void;
10
+ switchExposureService(toEnable: boolean, sendEvent: boolean): void;
11
+ }
@@ -0,0 +1,211 @@
1
+ /*
2
+ * Copyright 2021-2024 The Lynx Authors. All rights reserved.
3
+ * Licensed under the Apache License Version 2.0 that can be found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import { scrollContainerDom } from '../../constants.js';
7
+ import { convertLengthToPx } from './utils/convertLengthToPx.js';
8
+ export class ExposureServices {
9
+ #exposureEnabledElementsToIntersectionObserver = new Map();
10
+ #exposureEnabledElementsToOldExposureIdAttributeValue = new Map();
11
+ #globalExposureEventCache = [];
12
+ #globalDisexposureEventCache = [];
13
+ #globalExposureEventBatchTimer = null;
14
+ /**
15
+ * The elements that are currently exposed
16
+ * We only send the event when the element enters or leaves the exposed state
17
+ */
18
+ #exposedElements = new Set();
19
+ /**
20
+ * note that this flag only affects the global exposure events.
21
+ * The uiappear/uidisappear events are always dispatched when the element enters or leaves the viewport
22
+ */
23
+ #isExposureServiceOn = true;
24
+ #lynxViewInstance;
25
+ constructor(lynxViewInstance) {
26
+ this.#lynxViewInstance = lynxViewInstance;
27
+ }
28
+ /**
29
+ * diff the current exposure enabled elements with the previous ones, and start/stop IntersectionObserver accordingly
30
+ * If an element's exposure-id attribute has changed, we also need to send a new disexposure event with the old one
31
+ */
32
+ updateExposureStatus(elementsToBeEnabled, elementsToBeDisabled) {
33
+ const elementsToBeEnabledSet = new Set(elementsToBeEnabled);
34
+ // start observing newly enabled elements
35
+ for (const element of elementsToBeEnabledSet.values()) {
36
+ if (this.#exposureEnabledElementsToIntersectionObserver.has(element)) {
37
+ this.#stopIntersectionObserver(element);
38
+ }
39
+ this.#startIntersectionObserver(element);
40
+ }
41
+ const elementsToBeDisabledSet = new Set(elementsToBeDisabled);
42
+ // stop observing newly disabled elements
43
+ for (const element of elementsToBeDisabledSet.values()) {
44
+ this.#stopIntersectionObserver(element);
45
+ }
46
+ }
47
+ #IntersectionObserverEventHandler = (entries) => {
48
+ entries.forEach(({ target, isIntersecting }) => {
49
+ if (isIntersecting && !this.#exposedElements.has(target)) {
50
+ this.#sendExposureEvent(target, true, null, true);
51
+ this.#exposedElements.add(target);
52
+ }
53
+ else if (!isIntersecting && this.#exposedElements.has(target)) {
54
+ this.#sendExposureEvent(target, false, null, true);
55
+ this.#exposedElements.delete(target);
56
+ }
57
+ });
58
+ };
59
+ #stopIntersectionObserver(element) {
60
+ const intersectionObserver = this
61
+ .#exposureEnabledElementsToIntersectionObserver.get(element);
62
+ if (intersectionObserver) {
63
+ const oldExposureId = this
64
+ .#exposureEnabledElementsToOldExposureIdAttributeValue.get(element);
65
+ intersectionObserver.unobserve(element);
66
+ intersectionObserver.disconnect();
67
+ this.#exposureEnabledElementsToIntersectionObserver.delete(element);
68
+ this.#exposureEnabledElementsToOldExposureIdAttributeValue.delete(element);
69
+ const currentExposureId = element.getAttribute('exposure-id');
70
+ if (oldExposureId != null && currentExposureId !== oldExposureId) {
71
+ this.#sendExposureEvent(element, false, oldExposureId, false);
72
+ }
73
+ }
74
+ this.#exposedElements.delete(element);
75
+ }
76
+ #startIntersectionObserver(target) {
77
+ const threshold = parseFloat(target.getAttribute('exposure-area') ?? '0')
78
+ / 100;
79
+ const screenMarginTop = convertLengthToPx(target, target.getAttribute('exposure-screen-margin-top'));
80
+ const screenMarginRight = convertLengthToPx(target, target.getAttribute('exposure-screen-margin-right'));
81
+ const screenMarginBottom = convertLengthToPx(target, target.getAttribute('exposure-screen-margin-bottom'));
82
+ const screenMarginLeft = convertLengthToPx(target, target.getAttribute('exposure-screen-margin-left'));
83
+ const uiMarginTop = convertLengthToPx(target, target.getAttribute('exposure-ui-margin-top'));
84
+ const uiMarginRight = convertLengthToPx(target, target.getAttribute('exposure-ui-margin-right'));
85
+ const uiMarginBottom = convertLengthToPx(target, target.getAttribute('exposure-ui-margin-bottom'));
86
+ const uiMarginLeft = convertLengthToPx(target, target.getAttribute('exposure-ui-margin-left'));
87
+ /**
88
+ * TODO: @haoyang.wang support the switch `enableExposureUIMargin`
89
+ */
90
+ const calcedRootMarginTop = (uiMarginBottom ? -1 : 1)
91
+ * (screenMarginTop - uiMarginBottom);
92
+ const calcedRootMarginRight = (uiMarginLeft ? -1 : 1)
93
+ * (screenMarginRight - uiMarginLeft);
94
+ const calcedRootMarginBottom = (uiMarginTop ? -1 : 1)
95
+ * (screenMarginBottom - uiMarginTop);
96
+ const calcedRootMarginLeft = (uiMarginRight ? -1 : 1)
97
+ * (screenMarginLeft - uiMarginRight);
98
+ // get the parent scroll container
99
+ let root = target.parentElement;
100
+ while (root) {
101
+ // @ts-expect-error
102
+ if (root[scrollContainerDom]) {
103
+ // @ts-expect-error
104
+ root = root[scrollContainerDom];
105
+ break;
106
+ }
107
+ else {
108
+ root = root.parentElement;
109
+ }
110
+ }
111
+ const rootContainer = root ?? this.#lynxViewInstance.rootDom.parentElement;
112
+ const intersectionObserver = new IntersectionObserver(this.#IntersectionObserverEventHandler, {
113
+ rootMargin: `${calcedRootMarginTop}px ${calcedRootMarginRight}px ${calcedRootMarginBottom}px ${calcedRootMarginLeft}px`,
114
+ root: rootContainer,
115
+ threshold,
116
+ });
117
+ intersectionObserver.observe(target);
118
+ this.#exposureEnabledElementsToIntersectionObserver.set(target, intersectionObserver);
119
+ const currentExposureId = target.getAttribute('exposure-id');
120
+ if (currentExposureId != null) {
121
+ this.#exposureEnabledElementsToOldExposureIdAttributeValue.set(target, currentExposureId);
122
+ }
123
+ }
124
+ #sendExposureEvent(target, isIntersecting, exposureId,
125
+ /**
126
+ * Whether to send the uiappear/uidisappear event
127
+ * If the exposure service is turned from off to on, we may not want to send the appear events for all currently exposed elements
128
+ */
129
+ sendAppearEvent) {
130
+ exposureId = exposureId ?? target.getAttribute('exposure-id');
131
+ const exposureScene = target.getAttribute('exposure-scene') ?? '';
132
+ const uniqueId = this.#lynxViewInstance.mainThreadGlobalThis
133
+ .__GetElementUniqueID(target);
134
+ const detail = {
135
+ 'unique-id': uniqueId,
136
+ exposureID: exposureId,
137
+ exposureScene,
138
+ 'exposure-id': exposureId,
139
+ 'exposure-scene': exposureScene,
140
+ };
141
+ if (sendAppearEvent) {
142
+ const appearEvent = new CustomEvent(isIntersecting ? 'uiappear' : 'uidisappear', {
143
+ bubbles: false,
144
+ composed: false,
145
+ cancelable: true,
146
+ detail,
147
+ });
148
+ target.dispatchEvent(appearEvent);
149
+ }
150
+ const serializedTargetInfo = this.#lynxViewInstance.mtsWasmBinding
151
+ .generateTargetObject(target, this.#lynxViewInstance.mainThreadGlobalThis.__GetDataset(target)
152
+ ?? {});
153
+ const globalEvent = {
154
+ dataset: serializedTargetInfo.dataset,
155
+ ...detail,
156
+ type: isIntersecting ? 'exposure' : 'disexposure',
157
+ target: serializedTargetInfo,
158
+ currentTarget: serializedTargetInfo,
159
+ detail: {
160
+ ...detail,
161
+ 'unique-id': 0,
162
+ },
163
+ timestamp: Date.now(),
164
+ };
165
+ if (isIntersecting) {
166
+ this.#globalExposureEventCache.push(globalEvent);
167
+ }
168
+ else {
169
+ this.#globalDisexposureEventCache.push(globalEvent);
170
+ }
171
+ if (!this.#globalExposureEventBatchTimer) {
172
+ this.#globalExposureEventBatchTimer = setTimeout(() => {
173
+ if (this.#globalExposureEventCache.length > 0
174
+ || this.#globalDisexposureEventCache.length > 0) {
175
+ const currentExposureEvents = this.#globalExposureEventCache;
176
+ const currentDisexposureEvents = this.#globalDisexposureEventCache;
177
+ this.#globalExposureEventCache = [];
178
+ this.#globalDisexposureEventCache = [];
179
+ if (currentExposureEvents.length > 0) {
180
+ this.#lynxViewInstance.backgroundThread?.sendGlobalEvent('exposure', [
181
+ currentExposureEvents,
182
+ ]);
183
+ }
184
+ if (currentDisexposureEvents.length > 0) {
185
+ this.#lynxViewInstance.backgroundThread?.sendGlobalEvent('disexposure', [
186
+ currentDisexposureEvents,
187
+ ]);
188
+ }
189
+ }
190
+ this.#globalExposureEventBatchTimer = null;
191
+ }, 1000 / 20);
192
+ }
193
+ }
194
+ switchExposureService(toEnable, sendEvent) {
195
+ if (toEnable && !this.#isExposureServiceOn) {
196
+ // send all onScreen info
197
+ this.#exposedElements.forEach((element) => {
198
+ this.#sendExposureEvent(element, true, element.getAttribute('exposure-id'), false);
199
+ });
200
+ }
201
+ else if (!toEnable && this.#isExposureServiceOn) {
202
+ if (sendEvent) {
203
+ this.#exposedElements.forEach((element) => {
204
+ this.#sendExposureEvent(element, false, element.getAttribute('exposure-id'), false);
205
+ });
206
+ }
207
+ }
208
+ this.#isExposureServiceOn = toEnable;
209
+ }
210
+ }
211
+ //# sourceMappingURL=ExposureServices.js.map
@@ -0,0 +1,9 @@
1
+ import type { I18nResourceTranslationOptions, InitI18nResources } from '../../types/index.js';
2
+ import type { BackgroundThread } from './Background.js';
3
+ export declare const getCacheI18nResourcesKey: (options: I18nResourceTranslationOptions) => string;
4
+ export declare class I18nManager {
5
+ #private;
6
+ constructor(background: BackgroundThread, rootDom: ShadowRoot, i18nResources?: InitI18nResources);
7
+ updateData(data: InitI18nResources, options: I18nResourceTranslationOptions): void;
8
+ _I18nResourceTranslation: (options: I18nResourceTranslationOptions) => unknown | undefined;
9
+ }
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright 2025 The Lynx Authors. All rights reserved.
3
+ * Licensed under the Apache License Version 2.0 that can be found in the
4
+ * LICENSE file in the root directory of this source tree.
5
+ */
6
+ import { i18nResourceMissedEventName } from '../../constants.js';
7
+ export const getCacheI18nResourcesKey = (options) => {
8
+ return `${options.locale}_${options.channel}_${options.fallback_url}`;
9
+ };
10
+ export class I18nManager {
11
+ #background;
12
+ #rootDom;
13
+ #i18nResources;
14
+ constructor(background, rootDom, i18nResources = []) {
15
+ this.#background = background;
16
+ this.#rootDom = rootDom;
17
+ this.#i18nResources = i18nResources;
18
+ }
19
+ updateData(data, options) {
20
+ this.#i18nResources = this.#i18nResources.concat(data);
21
+ const matchedInitI18nResources = data.find(i => getCacheI18nResourcesKey(i.options)
22
+ === getCacheI18nResourcesKey(options));
23
+ this.#background.dispatchI18nResource(matchedInitI18nResources?.resource);
24
+ }
25
+ _I18nResourceTranslation = (options) => {
26
+ const matchedInitI18nResources = this.#i18nResources?.find((i) => getCacheI18nResourcesKey(i.options)
27
+ === getCacheI18nResourcesKey(options));
28
+ this.#background.dispatchI18nResource(matchedInitI18nResources?.resource);
29
+ if (matchedInitI18nResources) {
30
+ return matchedInitI18nResources.resource;
31
+ }
32
+ this.#triggerI18nResourceFallback(options);
33
+ return undefined;
34
+ };
35
+ #triggerI18nResourceFallback(options) {
36
+ const event = new CustomEvent(i18nResourceMissedEventName, {
37
+ detail: options,
38
+ bubbles: true,
39
+ composed: true,
40
+ });
41
+ this.#rootDom.dispatchEvent(event);
42
+ }
43
+ }
44
+ //# sourceMappingURL=I18n.js.map
@@ -0,0 +1,170 @@
1
+ import type { Cloneable, I18nResourceTranslationOptions, InitI18nResources, NapiModulesCall, NapiModulesMap, NativeModulesCall, NativeModulesMap } from '../../types/index.js';
2
+ export type INapiModulesCall = (name: string, data: any, moduleName: string, lynxView: LynxViewElement, dispatchNapiModules: (data: Cloneable) => void) => Promise<{
3
+ data: unknown;
4
+ transfer?: Transferable[];
5
+ } | undefined> | {
6
+ data: unknown;
7
+ transfer?: Transferable[];
8
+ } | undefined | Promise<undefined>;
9
+ /**
10
+ * Based on our experiences, these elements are almost used in all lynx cards.
11
+ */
12
+ /**
13
+ * @property {string} url [required] (attribute: "url") The url of the entry of your Lynx card
14
+ * @property {Cloneable} globalProps [optional] (attribute: "global-props") The globalProps value of this Lynx card
15
+ * @property {Cloneable} initData [optional] (attribute: "init-data") The initial data of this Lynx card
16
+ * @property {Record<string,string>} overrideLynxTagToHTMLTagMap [optional] use this property/attribute to override the lynx tag -> html tag map
17
+ * @property {NativeModulesMap} nativeModulesMap [optional] use to customize NativeModules. key is module-name, value is esm url.
18
+ * @property {NativeModulesCall} onNativeModulesCall [optional] the NativeModules value handler. Arguments will be cached before this property is assigned.
19
+ * @property {"auto" | null} height [optional] (attribute: "height") set it to "auto" for height auto-sizing
20
+ * @property {"auto" | null} width [optional] (attribute: "width") set it to "auto" for width auto-sizing
21
+ * @property {NapiModulesMap} napiModulesMap [optional] the napiModule which is called in lynx-core. key is module-name, value is esm url.
22
+ * @property {INapiModulesCall} onNapiModulesCall [optional] the NapiModule value handler.
23
+ * @property {string[]} injectStyleRules [optional] the css rules which will be injected into shadowroot. Each items will be inserted by `insertRule` method. @see https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/insertRule
24
+ * @property {number} lynxGroupId [optional] (attribute: "lynx-group-id") the background shared context id, which is used to share webworker between different lynx cards
25
+ * @property {(string)=>Promise<LynxTemplate>} customTemplateLoader [optional] the custom template loader, which is used to load the template
26
+ * @property {InitI18nResources} initI18nResources [optional] (attribute: "init-i18n-resources") the complete set of i18nResources that on the container side, which can be obtained synchronously by _I18nResourceTranslation
27
+ *
28
+ * @event error lynx card fired an error
29
+ * @event i18nResourceMissed i18n resource cache miss
30
+ *
31
+ * @example
32
+ * HTML Example
33
+ *
34
+ * Note that you should declarae the size of lynx-view
35
+ *
36
+ * ```html
37
+ * <lynx-view url="https://path/to/main-thread.js" raw-data="{}" global-props="{}" style="height:300px;width:300px">
38
+ * </lynx-view>
39
+ * ```
40
+ *
41
+ * React 19 Example
42
+ * ```jsx
43
+ * <lynx-view url={myLynxCardUrl} rawData={{}} globalProps={{}} style={{height:'300px', width:'300px'}}>
44
+ * </lynx-view>
45
+ * ```
46
+ */
47
+ export declare class LynxViewElement extends HTMLElement {
48
+ #private;
49
+ static lynxViewCount: number;
50
+ static tag: "lynx-view";
51
+ static observedAttributeAsProperties: string[];
52
+ /**
53
+ * @private
54
+ */
55
+ static observedAttributes: string[];
56
+ /**
57
+ * @public
58
+ * @property nativeModulesMap
59
+ * @default {}
60
+ */
61
+ nativeModulesMap: NativeModulesMap | undefined;
62
+ /**
63
+ * @param
64
+ * @property napiModulesMap
65
+ * @default {}
66
+ */
67
+ napiModulesMap: NapiModulesMap | undefined;
68
+ /**
69
+ * @param
70
+ * @property
71
+ */
72
+ onNapiModulesCall: NapiModulesCall | undefined;
73
+ constructor();
74
+ /**
75
+ * @public
76
+ * @property the url of lynx view output entry file
77
+ */
78
+ get url(): string | undefined;
79
+ set url(val: string);
80
+ /**
81
+ * @public
82
+ * @property globalProps
83
+ * @default {}
84
+ */
85
+ get globalProps(): Cloneable;
86
+ set globalProps(val: string | Cloneable);
87
+ /**
88
+ * @public
89
+ * @property initData
90
+ * @default {}
91
+ */
92
+ get initData(): Cloneable;
93
+ set initData(val: string | Cloneable);
94
+ /**
95
+ * @public
96
+ * @property initI18nResources
97
+ * @default {}
98
+ */
99
+ get initI18nResources(): InitI18nResources;
100
+ set initI18nResources(val: string | InitI18nResources);
101
+ /**
102
+ * @public
103
+ * @method
104
+ * update the `__initData` and trigger essential flow
105
+ */
106
+ updateI18nResources(data: InitI18nResources, options: I18nResourceTranslationOptions): void;
107
+ /**
108
+ * @public
109
+ * @property
110
+ * @default {page: 'div'}
111
+ */
112
+ get overrideLynxTagToHTMLTagMap(): Record<string, string>;
113
+ set overrideLynxTagToHTMLTagMap(val: string | Record<string, string>);
114
+ /**
115
+ * @param
116
+ * @property
117
+ */
118
+ get onNativeModulesCall(): NativeModulesCall | undefined;
119
+ set onNativeModulesCall(handler: NativeModulesCall);
120
+ /**
121
+ * @param
122
+ * @property
123
+ */
124
+ get lynxGroupId(): number | undefined;
125
+ set lynxGroupId(val: number | undefined);
126
+ /**
127
+ * @public
128
+ * @method
129
+ * update the `__initData` and trigger essential flow
130
+ */
131
+ updateData(data: Cloneable, processorName?: string, callback?: () => void): void;
132
+ /**
133
+ * @public
134
+ * @method
135
+ * update the `__globalProps`
136
+ */
137
+ updateGlobalProps(data: Cloneable): void;
138
+ /**
139
+ * @public
140
+ * @method
141
+ * send global events, which can be listened to using the GlobalEventEmitter
142
+ */
143
+ sendGlobalEvent(eventName: string, params: Cloneable[]): void;
144
+ /**
145
+ * @public
146
+ * @method
147
+ * reload the current page
148
+ */
149
+ reload(): void;
150
+ /**
151
+ * @override
152
+ * "false" value will be omitted
153
+ *
154
+ * {@inheritdoc HTMLElement.setAttribute}
155
+ */
156
+ setAttribute(qualifiedName: string, value: string): void;
157
+ /**
158
+ * @private
159
+ */
160
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
161
+ injectStyleRules?: string[];
162
+ /**
163
+ * @private
164
+ */
165
+ disconnectedCallback(): void;
166
+ /**
167
+ * @private
168
+ */
169
+ connectedCallback(): void;
170
+ }