@lynx-js/testing-environment 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, definition)=>{
14
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
+ enumerable: true,
16
+ get: definition[key]
17
+ });
18
+ };
19
+ })();
20
+ (()=>{
21
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
22
+ })();
23
+ (()=>{
24
+ __webpack_require__.r = (exports1)=>{
25
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
26
+ value: 'Module'
27
+ });
28
+ Object.defineProperty(exports1, '__esModule', {
29
+ value: true
30
+ });
31
+ };
32
+ })();
33
+ var __webpack_exports__ = {};
34
+ __webpack_require__.r(__webpack_exports__);
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ LynxTestingEnv: ()=>LynxTestingEnv,
37
+ initElementTree: ()=>ElementPAPI_cjs_namespaceObject.initElementTree
38
+ });
39
+ const external_events_namespaceObject = require("events");
40
+ var external_events_default = /*#__PURE__*/ __webpack_require__.n(external_events_namespaceObject);
41
+ const GlobalThis_cjs_namespaceObject = require("./lynx/GlobalThis.cjs");
42
+ const ElementPAPI_cjs_namespaceObject = require("./lynx/ElementPAPI.cjs");
43
+ function _define_property(obj, key, value) {
44
+ if (key in obj) Object.defineProperty(obj, key, {
45
+ value: value,
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true
49
+ });
50
+ else obj[key] = value;
51
+ return obj;
52
+ }
53
+ function __injectElementApi(target) {
54
+ const elementTree = (0, ElementPAPI_cjs_namespaceObject.initElementTree)();
55
+ target.elementTree = elementTree;
56
+ if (void 0 === target) target = globalThis;
57
+ for (const k of Object.getOwnPropertyNames(elementTree.constructor.prototype))if (k.startsWith('__')) target[k] = elementTree[k].bind(elementTree);
58
+ target.$kTemplateAssembler = {};
59
+ target.registerDataProcessor = ()=>{
60
+ console.error('registerDataProcessor is not implemented');
61
+ };
62
+ target.__OnLifecycleEvent = (...args)=>{
63
+ const isMainThread = __MAIN_THREAD__;
64
+ globalThis.lynxTestingEnv.switchToBackgroundThread();
65
+ globalThis.lynxCoreInject.tt.OnLifecycleEvent(...args);
66
+ if (isMainThread) globalThis.lynxTestingEnv.switchToMainThread();
67
+ };
68
+ target._ReportError = ()=>{};
69
+ }
70
+ function createPolyfills() {
71
+ const app = {
72
+ callLepusMethod: (...rLynxChange)=>{
73
+ const isBackground = !__MAIN_THREAD__;
74
+ globalThis.lynxTestingEnv.switchToMainThread();
75
+ globalThis[rLynxChange[0]](rLynxChange[1]);
76
+ globalThis.lynxTestingEnv.switchToBackgroundThread();
77
+ rLynxChange[2]();
78
+ globalThis.lynxTestingEnv.switchToMainThread();
79
+ if (isBackground) globalThis.lynxTestingEnv.switchToBackgroundThread();
80
+ },
81
+ markTiming: ()=>{},
82
+ createJSObjectDestructionObserver: ()=>({})
83
+ };
84
+ const performance = {
85
+ __functionCallHistory: [],
86
+ _generatePipelineOptions: ()=>{
87
+ performance.__functionCallHistory.push([
88
+ '_generatePipelineOptions'
89
+ ]);
90
+ return {
91
+ pipelineID: 'pipelineID',
92
+ needTimestamps: false
93
+ };
94
+ },
95
+ _onPipelineStart: (id)=>{
96
+ performance.__functionCallHistory.push([
97
+ '_onPipelineStart',
98
+ id
99
+ ]);
100
+ },
101
+ _markTiming: (id, key)=>{
102
+ performance.__functionCallHistory.push([
103
+ '_markTiming',
104
+ id,
105
+ key
106
+ ]);
107
+ },
108
+ _bindPipelineIdWithTimingFlag: (id, flag)=>{
109
+ performance.__functionCallHistory.push([
110
+ '_bindPipelineIdWithTimingFlag',
111
+ id,
112
+ flag
113
+ ]);
114
+ }
115
+ };
116
+ const ee = new (external_events_default())();
117
+ ee.dispatchEvent = ({ type, data })=>{
118
+ const isMainThread = __MAIN_THREAD__;
119
+ lynxTestingEnv.switchToBackgroundThread();
120
+ ee.emit(type, {
121
+ data: data
122
+ });
123
+ if (isMainThread) lynxTestingEnv.switchToMainThread();
124
+ };
125
+ ee.addEventListener = ee.addListener;
126
+ ee.removeEventListener = ee.removeListener;
127
+ const CoreContext = ee;
128
+ const JsContext = ee;
129
+ function __LoadLepusChunk(chunkName, options) {
130
+ const isBackground = !__MAIN_THREAD__;
131
+ globalThis.lynxTestingEnv.switchToMainThread();
132
+ if (process.env['DEBUG']) console.log('__LoadLepusChunk', chunkName, options);
133
+ let ans;
134
+ if ('worklet-runtime' === chunkName) {
135
+ var _globalThis_onInitWorkletRuntime, _globalThis;
136
+ ans = null == (_globalThis_onInitWorkletRuntime = (_globalThis = globalThis).onInitWorkletRuntime) ? void 0 : _globalThis_onInitWorkletRuntime.call(_globalThis);
137
+ } else throw new Error(`__LoadLepusChunk: Unknown chunk name: ${chunkName}`);
138
+ if (isBackground) globalThis.lynxTestingEnv.switchToBackgroundThread();
139
+ return ans;
140
+ }
141
+ return {
142
+ app,
143
+ performance,
144
+ CoreContext,
145
+ JsContext,
146
+ __LoadLepusChunk
147
+ };
148
+ }
149
+ function injectMainThreadGlobals(target, polyfills) {
150
+ var _globalThis_onInjectMainThreadGlobals, _globalThis;
151
+ __injectElementApi(target);
152
+ const { performance, JsContext, __LoadLepusChunk } = polyfills || {};
153
+ if (void 0 === target) target = globalThis;
154
+ target.__DEV__ = true;
155
+ target.__PROFILE__ = true;
156
+ target.__JS__ = false;
157
+ target.__LEPUS__ = true;
158
+ target.__BACKGROUND__ = false;
159
+ target.__MAIN_THREAD__ = true;
160
+ target.__REF_FIRE_IMMEDIATELY__ = false;
161
+ target.__FIRST_SCREEN_SYNC_TIMING__ = 'immediately';
162
+ target.__TESTING_FORCE_RENDER_TO_OPCODE__ = false;
163
+ target.__ENABLE_SSR__ = false;
164
+ target.globDynamicComponentEntry = '__Card__';
165
+ target.lynx = {
166
+ performance,
167
+ getJSContext: ()=>JsContext,
168
+ reportError: (e)=>{
169
+ throw e;
170
+ }
171
+ };
172
+ target.requestAnimationFrame = setTimeout;
173
+ target.cancelAnimationFrame = clearTimeout;
174
+ target.console.profile = ()=>{};
175
+ target.console.profileEnd = ()=>{};
176
+ target.__LoadLepusChunk = __LoadLepusChunk;
177
+ null == (_globalThis_onInjectMainThreadGlobals = (_globalThis = globalThis).onInjectMainThreadGlobals) || _globalThis_onInjectMainThreadGlobals.call(_globalThis, target);
178
+ }
179
+ const IGNORE_LIST_GLOBALS = [
180
+ 'globalThis',
181
+ 'global'
182
+ ];
183
+ class NodesRef {
184
+ invoke() {
185
+ throw new Error('not implemented');
186
+ }
187
+ path() {
188
+ throw new Error('not implemented');
189
+ }
190
+ fields() {
191
+ throw new Error('not implemented');
192
+ }
193
+ setNativeProps() {
194
+ throw new Error('not implemented');
195
+ }
196
+ constructor(selectorQuery, nodeSelectToken){
197
+ _define_property(this, "_nodeSelectToken", void 0);
198
+ _define_property(this, "_selectorQuery", void 0);
199
+ this._nodeSelectToken = nodeSelectToken;
200
+ this._selectorQuery = selectorQuery;
201
+ }
202
+ }
203
+ function injectBackgroundThreadGlobals(target, polyfills) {
204
+ var _globalThis_onInjectBackgroundThreadGlobals, _globalThis;
205
+ const { app, performance, CoreContext, __LoadLepusChunk } = polyfills || {};
206
+ if (void 0 === target) target = globalThis;
207
+ target.__DEV__ = true;
208
+ target.__PROFILE__ = true;
209
+ target.__JS__ = true;
210
+ target.__LEPUS__ = false;
211
+ target.__BACKGROUND__ = true;
212
+ target.__MAIN_THREAD__ = false;
213
+ target.__ENABLE_SSR__ = false;
214
+ target.globDynamicComponentEntry = '__Card__';
215
+ target.lynxCoreInject = {};
216
+ target.lynxCoreInject.tt = {
217
+ _params: {
218
+ initData: {},
219
+ updateData: {}
220
+ }
221
+ };
222
+ const globalEventEmitter = new (external_events_default())();
223
+ globalEventEmitter.trigger = globalEventEmitter.emit;
224
+ globalEventEmitter.toggle = globalEventEmitter.emit;
225
+ target.lynx = {
226
+ getNativeApp: ()=>app,
227
+ performance,
228
+ createSelectorQuery: ()=>({
229
+ selectUniqueID: function(uniqueId) {
230
+ return new NodesRef({}, {
231
+ type: 2,
232
+ identifier: uniqueId.toString()
233
+ });
234
+ }
235
+ }),
236
+ getCoreContext: ()=>CoreContext,
237
+ getJSModule: (moduleName)=>{
238
+ if ('GlobalEventEmitter' === moduleName) return globalEventEmitter;
239
+ throw new Error(`getJSModule(${moduleName}) not implemented`);
240
+ },
241
+ reportError: (e)=>{
242
+ throw e;
243
+ }
244
+ };
245
+ target.requestAnimationFrame = setTimeout;
246
+ target.cancelAnimationFrame = clearTimeout;
247
+ target.console.profile = ()=>{};
248
+ target.console.profileEnd = ()=>{};
249
+ target.SystemInfo = {
250
+ platform: 'iOS',
251
+ pixelRatio: 3,
252
+ pixelWidth: 1170,
253
+ pixelHeight: 2532,
254
+ osVersion: '17.0.2',
255
+ enableKrypton: true,
256
+ runtimeType: 'quickjs',
257
+ lynxSdkVersion: '3.0'
258
+ };
259
+ target.__LoadLepusChunk = __LoadLepusChunk;
260
+ null == (_globalThis_onInjectBackgroundThreadGlobals = (_globalThis = globalThis).onInjectBackgroundThreadGlobals) || _globalThis_onInjectBackgroundThreadGlobals.call(_globalThis, target);
261
+ }
262
+ class LynxTestingEnv {
263
+ injectGlobals() {
264
+ const polyfills = createPolyfills();
265
+ injectBackgroundThreadGlobals(this.backgroundThread.globalThis, polyfills);
266
+ injectMainThreadGlobals(this.mainThread.globalThis, polyfills);
267
+ }
268
+ switchToBackgroundThread() {
269
+ var _globalThis_onSwitchedToBackgroundThread, _globalThis;
270
+ this.originals = new Map();
271
+ Object.getOwnPropertyNames(this.backgroundThread.globalThis).forEach((key)=>{
272
+ if (IGNORE_LIST_GLOBALS.includes(key)) return;
273
+ this.originals.set(key, global[key]);
274
+ global[key] = this.backgroundThread.globalThis[key];
275
+ });
276
+ null == (_globalThis = globalThis) || null == (_globalThis_onSwitchedToBackgroundThread = _globalThis.onSwitchedToBackgroundThread) || _globalThis_onSwitchedToBackgroundThread.call(_globalThis);
277
+ }
278
+ switchToMainThread() {
279
+ var _globalThis_onSwitchedToMainThread, _globalThis;
280
+ this.originals = new Map();
281
+ Object.getOwnPropertyNames(this.mainThread.globalThis).forEach((key)=>{
282
+ if (IGNORE_LIST_GLOBALS.includes(key)) return;
283
+ this.originals.set(key, global[key]);
284
+ global[key] = this.mainThread.globalThis[key];
285
+ });
286
+ null == (_globalThis = globalThis) || null == (_globalThis_onSwitchedToMainThread = _globalThis.onSwitchedToMainThread) || _globalThis_onSwitchedToMainThread.call(_globalThis);
287
+ }
288
+ clearGlobal() {
289
+ var _this_originals, _this_originals1;
290
+ null == (_this_originals = this.originals) || _this_originals.forEach((v, k)=>{
291
+ global[k] = v;
292
+ });
293
+ null == (_this_originals1 = this.originals) || _this_originals1.clear();
294
+ }
295
+ reset() {
296
+ var _globalThis_onResetLynxTestingEnv, _globalThis;
297
+ this.injectGlobals();
298
+ this.switchToMainThread();
299
+ this.switchToBackgroundThread();
300
+ null == (_globalThis_onResetLynxTestingEnv = (_globalThis = globalThis).onResetLynxTestingEnv) || _globalThis_onResetLynxTestingEnv.call(_globalThis);
301
+ }
302
+ constructor(){
303
+ _define_property(this, "originals", new Map());
304
+ _define_property(this, "backgroundThread", void 0);
305
+ _define_property(this, "mainThread", void 0);
306
+ _define_property(this, "jsdom", global.jsdom);
307
+ this.backgroundThread = (0, GlobalThis_cjs_namespaceObject.createGlobalThis)();
308
+ this.mainThread = (0, GlobalThis_cjs_namespaceObject.createGlobalThis)();
309
+ const globalPolyfills = {
310
+ console: this.jsdom.window['console'],
311
+ Event: this.jsdom.window.Event,
312
+ window: this.jsdom.window,
313
+ document: this.jsdom.window.document
314
+ };
315
+ Object.assign(this.mainThread.globalThis, globalPolyfills);
316
+ Object.assign(this.backgroundThread.globalThis, globalPolyfills);
317
+ this.injectGlobals();
318
+ this.switchToBackgroundThread();
319
+ }
320
+ }
321
+ exports.LynxTestingEnv = __webpack_exports__.LynxTestingEnv;
322
+ exports.initElementTree = __webpack_exports__.initElementTree;
323
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
324
+ "LynxTestingEnv",
325
+ "initElementTree"
326
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
327
+ Object.defineProperty(exports, '__esModule', {
328
+ value: true
329
+ });
@@ -0,0 +1,114 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * A pure-JavaScript implementation of the {@link https://lynxjs.org/guide/spec.html | Lynx Spec},
5
+ * notably the {@link https://lynxjs.org/api/engine/element-api | Element PAPI} and {@link https://lynxjs.org/guide/spec#dual-threaded-model | Dual-threaded Model} for use with Node.js.
6
+ */
7
+ import { JSDOM } from 'jsdom';
8
+ import { LynxGlobalThis } from './lynx/GlobalThis.js';
9
+ import { initElementTree } from './lynx/ElementPAPI.js';
10
+ export { initElementTree } from './lynx/ElementPAPI.js';
11
+ export type { LynxElement } from './lynx/ElementPAPI.js';
12
+ export type { LynxGlobalThis } from './lynx/GlobalThis.js';
13
+ /**
14
+ * @public
15
+ * The lynx element tree
16
+ */
17
+ export type ElementTree = ReturnType<typeof initElementTree>;
18
+ /**
19
+ * @public
20
+ */
21
+ export type FilterUnderscoreKeys<T> = {
22
+ [K in keyof T]: K extends `__${string}` ? K : never;
23
+ }[keyof T];
24
+ /**
25
+ * @public
26
+ */
27
+ export type PickUnderscoreKeys<T> = Pick<T, FilterUnderscoreKeys<T>>;
28
+ /**
29
+ * The Element PAPI Types
30
+ * @public
31
+ */
32
+ export type ElementTreeGlobals = PickUnderscoreKeys<ElementTree>;
33
+ declare global {
34
+ var lynxTestingEnv: LynxTestingEnv;
35
+ var elementTree: ElementTree;
36
+ var __JS__: boolean;
37
+ var __LEPUS__: boolean;
38
+ var __BACKGROUND__: boolean;
39
+ var __MAIN_THREAD__: boolean;
40
+ namespace lynxCoreInject {
41
+ var tt: any;
42
+ }
43
+ function onInjectBackgroundThreadGlobals(globals: any): void;
44
+ function onInjectMainThreadGlobals(globals: any): void;
45
+ function onSwitchedToBackgroundThread(): void;
46
+ function onSwitchedToMainThread(): void;
47
+ function onResetLynxTestingEnv(): void;
48
+ function onInitWorkletRuntime(): void;
49
+ }
50
+ /**
51
+ * A pure-JavaScript implementation of the {@link https://lynxjs.org/guide/spec.html | Lynx Spec},
52
+ * notably the {@link https://lynxjs.org/api/engine/element-api | Element PAPI} and {@link https://lynxjs.org/guide/spec#dual-threaded-model | Dual-threaded Model} for use with Node.js.
53
+ *
54
+ * @example
55
+ *
56
+ * ```ts
57
+ * import { LynxTestingEnv } from '@lynx-js/testing-environment';
58
+ *
59
+ * const lynxTestingEnv = new LynxTestingEnv();
60
+ *
61
+ * lynxTestingEnv.switchToMainThread();
62
+ * // use the main thread Element PAPI
63
+ * const page = __CreatePage('0', 0);
64
+ * const view = __CreateView(0);
65
+ * __AppendElement(page, view);
66
+ *
67
+ * ```
68
+ *
69
+ * @public
70
+ */
71
+ export declare class LynxTestingEnv {
72
+ private originals;
73
+ /**
74
+ * The global object for the background thread.
75
+ *
76
+ * @example
77
+ *
78
+ * ```ts
79
+ * import { LynxTestingEnv } from '@lynx-js/testing-environment';
80
+ *
81
+ * const lynxTestingEnv = new LynxTestingEnv();
82
+ *
83
+ * lynxTestingEnv.switchToBackgroundThread();
84
+ * // use the background thread global object
85
+ * globalThis.lynxCoreInject.tt.OnLifecycleEvent(...args);
86
+ * ```
87
+ */
88
+ backgroundThread: LynxGlobalThis;
89
+ /**
90
+ * The global object for the main thread.
91
+ *
92
+ * @example
93
+ *
94
+ * ```ts
95
+ * import { LynxTestingEnv } from '@lynx-js/testing-environment';
96
+ *
97
+ * const lynxTestingEnv = new LynxTestingEnv();
98
+ *
99
+ * lynxTestingEnv.switchToMainThread();
100
+ * // use the main thread global object
101
+ * const page = globalThis.__CreatePage('0', 0);
102
+ * const view = globalThis.__CreateView(0);
103
+ * globalThis.__AppendElement(page, view);
104
+ * ```
105
+ */
106
+ mainThread: LynxGlobalThis & ElementTreeGlobals;
107
+ jsdom: JSDOM;
108
+ constructor();
109
+ injectGlobals(): void;
110
+ switchToBackgroundThread(): void;
111
+ switchToMainThread(): void;
112
+ clearGlobal(): void;
113
+ reset(): void;
114
+ }