vxrn 1.25.8 → 1.25.9

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 (45) hide show
  1. package/dist/config/getViteServerConfig.mjs +6 -0
  2. package/dist/config/getViteServerConfig.mjs.map +1 -1
  3. package/dist/config/getViteServerConfig.native.js +6 -0
  4. package/dist/config/getViteServerConfig.native.js.map +1 -1
  5. package/dist/config/getViteServerConfig.test.mjs +26 -0
  6. package/dist/config/getViteServerConfig.test.mjs.map +1 -0
  7. package/dist/config/getViteServerConfig.test.native.js +26 -0
  8. package/dist/config/getViteServerConfig.test.native.js.map +1 -0
  9. package/dist/exports/dev.mjs +26 -1
  10. package/dist/exports/dev.mjs.map +1 -1
  11. package/dist/exports/dev.native.js +26 -1
  12. package/dist/exports/dev.native.js.map +1 -1
  13. package/dist/plugins/reactNativeDevServer.mjs +80 -7
  14. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  15. package/dist/plugins/reactNativeDevServer.native.js +80 -7
  16. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  17. package/dist/runtime/native-prelude.mjs +7 -0
  18. package/dist/runtime/native-prelude.mjs.map +1 -1
  19. package/dist/runtime/native-prelude.native.js +7 -0
  20. package/dist/runtime/native-prelude.native.js.map +1 -1
  21. package/dist/utils/createNativeDevEngine.mjs +302 -197
  22. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  23. package/dist/utils/createNativeDevEngine.native.js +410 -221
  24. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  25. package/dist/utils/createNativeDevEngine.test.mjs +536 -6
  26. package/dist/utils/createNativeDevEngine.test.mjs.map +1 -1
  27. package/dist/utils/createNativeDevEngine.test.native.js +559 -6
  28. package/dist/utils/createNativeDevEngine.test.native.js.map +1 -1
  29. package/package.json +11 -11
  30. package/src/config/getViteServerConfig.test.ts +29 -0
  31. package/src/config/getViteServerConfig.ts +11 -0
  32. package/src/exports/dev.ts +34 -3
  33. package/src/plugins/reactNativeDevServer.ts +89 -12
  34. package/src/runtime/native-prelude.ts +7 -0
  35. package/src/utils/createNativeDevEngine.test.ts +682 -5
  36. package/src/utils/createNativeDevEngine.ts +516 -229
  37. package/types/config/getViteServerConfig.d.ts.map +1 -1
  38. package/types/config/getViteServerConfig.test.d.ts +2 -0
  39. package/types/config/getViteServerConfig.test.d.ts.map +1 -0
  40. package/types/exports/dev.d.ts.map +1 -1
  41. package/types/plugins/reactNativeDevServer.d.ts +1 -0
  42. package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
  43. package/types/runtime/native-prelude.d.ts.map +1 -1
  44. package/types/utils/createNativeDevEngine.d.ts +40 -2
  45. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
@@ -1,10 +1,13 @@
1
- import { mkdtemp, rm, writeFile } from "fs/promises";
1
+ import { existsSync } from "fs";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "fs/promises";
2
3
  import { tmpdir } from "os";
3
4
  import { join } from "path";
5
+ import { runInNewContext } from "vm";
4
6
  import { rolldown } from "rolldown";
5
7
  import { dev } from "rolldown/experimental";
6
8
  import { describe, expect, it } from "vitest";
7
- import { getHermesSWCIncludes, getHmrRuntimeSource, getNativeTransformConfig, hermesCompatSWCPlugin, hmrClientNoopPlugin, vxrnCompilerPlugin, wrapNativeBundleModuleScope } from "./createNativeDevEngine.native.js";
9
+ import { getNativePrelude } from "../runtime/native-prelude.native.js";
10
+ import { buildNativeBundle, createNativeDevAssetRegistry, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatSWCPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, vxrnCompilerPlugin, wrapNativeBundleModuleScope } from "./createNativeDevEngine.native.js";
8
11
  function _instanceof(left, right) {
9
12
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) return !!right[Symbol.hasInstance](left);else return left instanceof right;
10
13
  }
@@ -13,6 +16,58 @@ function _type_of(obj) {
13
16
 
14
17
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
15
18
  }
19
+ var nativeTransformProbe = `
20
+ export const transformProbe = () => {
21
+ 'worklet'
22
+ return 'transformed'
23
+ }
24
+ `;
25
+ async function createWorkletsProject() {
26
+ var throwOnTransform = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
27
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-transform-failure-"));
28
+ var packageRoot = join(testRoot, "node_modules/react-native-worklets");
29
+ await mkdir(packageRoot, {
30
+ recursive: true
31
+ });
32
+ await writeFile(join(packageRoot, "package.json"), JSON.stringify({
33
+ name: "react-native-worklets"
34
+ }));
35
+ await writeFile(join(packageRoot, "plugin.js"), throwOnTransform ? `module.exports = () => ({
36
+ visitor: {
37
+ Program() {
38
+ throw new Error('NATIVE_TRANSFORM_NEGATIVE_CONTROL')
39
+ }
40
+ }
41
+ })` : `module.exports = () => ({ visitor: {} })`);
42
+ await writeFile(join(testRoot, "entry.ts"), nativeTransformProbe);
43
+ return testRoot;
44
+ }
45
+ describe("native prelude", function () {
46
+ it("does not advertise a host event API that cannot remove listeners", function () {
47
+ var context = {
48
+ addEventListener() {}
49
+ };
50
+ runInNewContext(getNativePrelude({
51
+ dev: false,
52
+ platform: "ios"
53
+ }), context);
54
+ expect(Reflect.get(context, "addEventListener")).toBeUndefined();
55
+ });
56
+ it("preserves a complete host event API", function () {
57
+ var addEventListener = function () {};
58
+ var removeEventListener = function () {};
59
+ var context = {
60
+ addEventListener,
61
+ removeEventListener
62
+ };
63
+ runInNewContext(getNativePrelude({
64
+ dev: false,
65
+ platform: "ios"
66
+ }), context);
67
+ expect(context.addEventListener).toBe(addEventListener);
68
+ expect(context.removeEventListener).toBe(removeEventListener);
69
+ });
70
+ });
16
71
  describe("native Rolldown HMR runtime", function () {
17
72
  it("registers a Rolldown 1.2 client and applies a self-accepted patch", {
18
73
  timeout: 3e4
@@ -84,7 +139,8 @@ if (import.meta.hot) {
84
139
  return item.clientId === runtime.clientId && item.update.type === "Patch";
85
140
  })) === null || _result_updates_find === void 0 ? void 0 : _result_updates_find.update;
86
141
  expect(patch).toBeTruthy();
87
- expect(runtime.applyHmrUpdate(patch.code, patch.changedIds, patch.seq)).toBe(true);
142
+ var applyHmrUpdate = Reflect.get(runtime, "applyHmrUpdate");
143
+ expect(Reflect.apply(applyHmrUpdate, runtime, [patch.code, patch.changedIds, patch.seq])).toBe(true);
88
144
  expect(globalThis.__vxrnHmrBody).toBe("v2");
89
145
  expect(globalThis.__vxrnHmrAccepted).toBe("v2");
90
146
  } finally {
@@ -98,6 +154,141 @@ if (import.meta.hot) {
98
154
  delete globalThis.__vxrnHmrAccepted;
99
155
  }
100
156
  });
157
+ it("propagates a non-component update to a React Refresh boundary", {
158
+ timeout: 3e4
159
+ }, async function () {
160
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-refresh-boundary-"));
161
+ var entry = join(testRoot, "entry.js");
162
+ var leaf = join(testRoot, "leaf.js");
163
+ await writeFile(entry, `
164
+ import { value } from './leaf.js'
165
+ globalThis.__vxrnRefreshBoundaryValue = value
166
+ export function App() {}
167
+ if (import.meta.hot) {
168
+ import.meta.hot.acceptReactRefresh(() => {
169
+ globalThis.__vxrnRefreshBoundaryAccepted = true
170
+ })
171
+ }
172
+ `);
173
+ await writeFile(leaf, `export const value = 'v1'`);
174
+ var resolveInitialOutput;
175
+ var initialOutput = new Promise(function (resolve) {
176
+ resolveInitialOutput = resolve;
177
+ });
178
+ var resolveHmrUpdate;
179
+ var hmrUpdate = new Promise(function (resolve) {
180
+ resolveHmrUpdate = resolve;
181
+ });
182
+ var registeredClientId;
183
+ var engine = await dev({
184
+ cwd: testRoot,
185
+ input: entry,
186
+ experimental: {
187
+ devMode: {
188
+ implement: getHmrRuntimeSource()
189
+ }
190
+ }
191
+ }, {
192
+ format: "esm"
193
+ }, {
194
+ onOutput(result2) {
195
+ resolveInitialOutput(result2);
196
+ },
197
+ onHmrUpdates(result2) {
198
+ if (!_instanceof(result2, Error) && result2.updates.some(function (item) {
199
+ return item.clientId === registeredClientId && item.update.type === "Patch";
200
+ })) resolveHmrUpdate(result2);
201
+ }
202
+ });
203
+ var previousRefreshRuntime = Reflect.get(globalThis, "__ReactRefresh");
204
+ Reflect.set(globalThis, "__ReactRefresh", {
205
+ isLikelyComponentType(value) {
206
+ return typeof value === "function";
207
+ }
208
+ });
209
+ try {
210
+ var _result_updates_find;
211
+ await engine.run();
212
+ var initial = await initialOutput;
213
+ if (_instanceof(initial, Error)) throw initial;
214
+ var chunk = initial.output.find(function (item) {
215
+ return item.type === "chunk" && item.isEntry;
216
+ });
217
+ expect(chunk).toBeTruthy();
218
+ Reflect.deleteProperty(globalThis, "__rolldown_runtime__");
219
+ await import(`data:text/javascript;base64,${Buffer.from(chunk.code).toString("base64")}`);
220
+ var runtime = Reflect.get(globalThis, "__rolldown_runtime__");
221
+ registeredClientId = runtime.clientId;
222
+ await engine.registerClient(runtime.clientId);
223
+ await writeFile(leaf, `export const value = 'v2'`);
224
+ var patch = (_result_updates_find = (await Promise.race([hmrUpdate, new Promise(function (_, reject) {
225
+ return setTimeout(function () {
226
+ return reject(/* @__PURE__ */new Error("timed out waiting for HMR patch"));
227
+ }, 1e4);
228
+ })])).updates.find(function (item) {
229
+ return item.clientId === runtime.clientId && item.update.type === "Patch";
230
+ })) === null || _result_updates_find === void 0 ? void 0 : _result_updates_find.update;
231
+ expect(patch).toBeTruthy();
232
+ var applyHmrUpdate = Reflect.get(runtime, "applyHmrUpdate");
233
+ expect(Reflect.apply(applyHmrUpdate, runtime, [patch.code, patch.changedIds, patch.seq])).toBe(true);
234
+ expect(Reflect.get(globalThis, "__vxrnRefreshBoundaryValue")).toBe("v2");
235
+ expect(Reflect.get(globalThis, "__vxrnRefreshBoundaryAccepted")).toBe(true);
236
+ } finally {
237
+ await engine.close();
238
+ await rm(testRoot, {
239
+ recursive: true,
240
+ force: true
241
+ });
242
+ Reflect.deleteProperty(globalThis, "__rolldown_runtime__");
243
+ Reflect.deleteProperty(globalThis, "__vxrnRefreshBoundaryValue");
244
+ Reflect.deleteProperty(globalThis, "__vxrnRefreshBoundaryAccepted");
245
+ if (previousRefreshRuntime === void 0) Reflect.deleteProperty(globalThis, "__ReactRefresh");else Reflect.set(globalThis, "__ReactRefresh", previousRefreshRuntime);
246
+ }
247
+ });
248
+ });
249
+ describe("native production import.meta lowering", function () {
250
+ it("emits a Hermes-compatible bundle for guarded import.meta.env reads", async function () {
251
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-import-meta-"));
252
+ await writeFile(join(testRoot, "entry.js"), `globalThis.__vxrnNativeImportMetaProbe = typeof import.meta !== 'undefined' && import.meta.env.DEV`);
253
+ try {
254
+ var result = await buildNativeBundle({
255
+ root: testRoot,
256
+ platform: "ios",
257
+ entryFile: "entry.js"
258
+ });
259
+ expect(result.code).not.toContain("typeof import.meta");
260
+ var context = {
261
+ globalThis: {},
262
+ process: {
263
+ env: {}
264
+ }
265
+ };
266
+ runInNewContext(result.code, context);
267
+ expect(Reflect.get(context.globalThis, "__vxrnNativeImportMetaProbe")).toBe(false);
268
+ } finally {
269
+ await rm(testRoot, {
270
+ recursive: true,
271
+ force: true
272
+ });
273
+ }
274
+ });
275
+ });
276
+ describe("native animated guard transform", function () {
277
+ it("preserves line count and returns a composable source map", async function () {
278
+ var plugin = nativeAnimatedGuardPlugin();
279
+ if (typeof plugin.transform !== "function") throw new Error("native animated guard transform hook is not callable");
280
+ var source = ["function call(methodName) {", " const method = nullthrows(NativeAnimatedModule)[methodName];", " method();", "}"].join("\n");
281
+ var result = await Reflect.apply(plugin.transform, void 0, [source, "/project/node_modules/react-native/src/private/animated/NativeAnimatedHelper.js"]);
282
+ expect(result.code.split("\n")).toHaveLength(source.split("\n").length);
283
+ expect(result.code).toContain("if (typeof method !== 'function') return");
284
+ expect(result.map).toEqual({
285
+ version: 3,
286
+ sources: ["/project/node_modules/react-native/src/private/animated/NativeAnimatedHelper.js"],
287
+ sourcesContent: [source],
288
+ names: [],
289
+ mappings: "AAAA;AACA;AACA;AACA"
290
+ });
291
+ });
101
292
  });
102
293
  var root = "/tmp/vxrn-native-env-define-test-nonexistent";
103
294
  describe("getNativeTransformConfig platform env defines", function () {
@@ -123,6 +314,21 @@ describe("getNativeTransformConfig platform env defines", function () {
123
314
  for (var _i1 = 0, _iter1 = [true, false]; _i1 < _iter1.length; _i1++) _loop2(_i1, _iter1);
124
315
  };
125
316
  for (var _i = 0, _iter = ["ios", "android"]; _i < _iter.length; _i++) _loop(_i, _iter);
317
+ it("inlines EXPO_PUBLIC values supplied by the native build environment", function () {
318
+ var key = "EXPO_PUBLIC_VXRN_NATIVE_ENV_PROBE";
319
+ var previous = process.env[key];
320
+ process.env[key] = "native-env-value";
321
+ try {
322
+ var {
323
+ define
324
+ } = getNativeTransformConfig("ios", false, root);
325
+ expect(define[`process.env.${key}`]).toBe("\"native-env-value\"");
326
+ expect(define[`import.meta.env.${key}`]).toBe("\"native-env-value\"");
327
+ expect(JSON.parse(define["import.meta.env"])[key]).toBe("native-env-value");
328
+ } finally {
329
+ if (previous === void 0) delete process.env[key];else process.env[key] = previous;
330
+ }
331
+ });
126
332
  });
127
333
  describe("wrapNativeBundleModuleScope", function () {
128
334
  var RUNTIME_MARKER = "//#region \\0rolldown/runtime.js";
@@ -147,15 +353,51 @@ globalThis.__rolldown_runtime__ = {};
147
353
  });
148
354
  });
149
355
  describe("getHermesSWCIncludes", function () {
150
- var CLASS_SET = ["transform-classes", "transform-parameters", "transform-class-properties", "transform-class-static-block", "transform-private-methods", "transform-private-property-in-object"];
356
+ var CLASS_SET = ["transform-classes", "transform-parameters", "transform-block-scoping", "transform-class-properties", "transform-class-static-block", "transform-private-methods", "transform-private-property-in-object"];
151
357
  it("always includes the full Hermes class-transform set (dev and prod)", function () {
152
358
  expect(getHermesSWCIncludes(true)).toEqual(expect.arrayContaining(CLASS_SET));
153
359
  expect(getHermesSWCIncludes(false)).toEqual(expect.arrayContaining(CLASS_SET));
154
360
  });
155
- it("adds transform-async-to-generator only in production", function () {
156
- expect(getHermesSWCIncludes(true)).not.toContain("transform-async-to-generator");
361
+ it("adds transform-async-to-generator in development and production", function () {
362
+ expect(getHermesSWCIncludes(true)).toContain("transform-async-to-generator");
157
363
  expect(getHermesSWCIncludes(false)).toContain("transform-async-to-generator");
158
364
  });
365
+ it("lowers async generators for the Hermes development interpreter", async function () {
366
+ var plugin = hermesCompatSWCPlugin(true);
367
+ if (typeof plugin.transform !== "function") throw new Error("Hermes compatibility transform hook is not callable");
368
+ var result = await Reflect.apply(plugin.transform, void 0, ["export async function* values() { yield await Promise.resolve(1) }", "/project/async-generator.ts"]);
369
+ expect(result.code).not.toContain("async function*");
370
+ expect(result.code).not.toContain("async function *");
371
+ });
372
+ it("preserves per-iteration bindings used by lazy method getters", async function () {
373
+ var plugin = hermesCompatSWCPlugin(true);
374
+ if (typeof plugin.transform !== "function") throw new Error("Hermes compatibility transform hook is not callable");
375
+ var result = await Reflect.apply(plugin.transform, void 0, [`
376
+ const installedGroups = new WeakMap()
377
+ function install(inst, methods) {
378
+ const proto = Object.getPrototypeOf(inst)
379
+ for (const key in methods) {
380
+ const fn = methods[key]
381
+ Object.defineProperty(proto, key, {
382
+ get() { return fn.bind(this) }
383
+ })
384
+ }
385
+ }
386
+ function Schema() {
387
+ install(this, {
388
+ nullish() { return 'nullish' },
389
+ apply(fn) { return fn(this) }
390
+ })
391
+ }
392
+ globalThis.__vxrnBlockScopeProbe = new Schema().nullish()
393
+ `, "/project/block-scope-loop.ts"]);
394
+ try {
395
+ new Function(result.code)();
396
+ expect(Reflect.get(globalThis, "__vxrnBlockScopeProbe")).toBe("nullish");
397
+ } finally {
398
+ Reflect.deleteProperty(globalThis, "__vxrnBlockScopeProbe");
399
+ }
400
+ });
159
401
  it("bundles lowered classes whose constructors use default and rest parameters", async function () {
160
402
  var testRoot = await mkdtemp(join(tmpdir(), "vxrn-hermes-parameters-"));
161
403
  var entry = join(testRoot, "entry.js");
@@ -232,9 +474,320 @@ describe("vxrnCompilerPlugin React Refresh registration", function () {
232
474
  expect(code).toContain("var __vxrnRefreshReg = globalThis.$RefreshReg$");
233
475
  expect(code).toContain("__vxrnRefreshReg(");
234
476
  expect(code).toContain("\"$RefreshReg$(\"");
477
+ expect(code).toContain("import.meta.hot.acceptReactRefresh(");
235
478
  } finally {
236
479
  process.env.NODE_ENV = previousNodeEnv;
237
480
  }
238
481
  });
239
482
  });
483
+ describe("native required transform failures", function () {
484
+ it.each([true, false])("rejects valid worklet source when its required compiler transform fails (dev=%s)", async function (dev2) {
485
+ var testRoot = await createWorkletsProject();
486
+ var compiler = await import("@vxrn/compiler");
487
+ compiler.configureVXRNCompilerPlugin({
488
+ enableReanimated: true
489
+ });
490
+ try {
491
+ var plugin = vxrnCompilerPlugin("ios", dev2, testRoot);
492
+ if (typeof plugin.transform !== "function") throw new Error("vxrn compiler transform hook is not callable");
493
+ await expect(Reflect.apply(plugin.transform, void 0, [nativeTransformProbe, join(testRoot, "entry.ts")])).rejects.toThrow("NATIVE_TRANSFORM_NEGATIVE_CONTROL");
494
+ } finally {
495
+ compiler.configureVXRNCompilerPlugin({
496
+ enableReanimated: false
497
+ });
498
+ await rm(testRoot, {
499
+ recursive: true,
500
+ force: true
501
+ });
502
+ }
503
+ });
504
+ it("returns a dev build error and no output when the required compiler transform fails", async function () {
505
+ var testRoot = await createWorkletsProject();
506
+ var compiler = await import("@vxrn/compiler");
507
+ compiler.configureVXRNCompilerPlugin({
508
+ enableReanimated: true
509
+ });
510
+ var resolveOutput;
511
+ var output = new Promise(function (resolve) {
512
+ resolveOutput = resolve;
513
+ });
514
+ var engine = await dev({
515
+ cwd: testRoot,
516
+ input: join(testRoot, "entry.ts"),
517
+ plugins: [vxrnCompilerPlugin("ios", true, testRoot)]
518
+ }, {
519
+ format: "esm"
520
+ }, {
521
+ onOutput: resolveOutput
522
+ });
523
+ try {
524
+ await engine.run();
525
+ var result = await output;
526
+ expect(result).toBeInstanceOf(Error);
527
+ expect(String(result)).toContain("NATIVE_TRANSFORM_NEGATIVE_CONTROL");
528
+ } finally {
529
+ await engine.close();
530
+ compiler.configureVXRNCompilerPlugin({
531
+ enableReanimated: false
532
+ });
533
+ await rm(testRoot, {
534
+ recursive: true,
535
+ force: true
536
+ });
537
+ }
538
+ });
539
+ it("emits no production bundle when the required compiler transform fails", async function () {
540
+ var testRoot = await createWorkletsProject();
541
+ var compiler = await import("@vxrn/compiler");
542
+ compiler.configureVXRNCompilerPlugin({
543
+ enableReanimated: true
544
+ });
545
+ try {
546
+ await expect(buildNativeBundle({
547
+ root: testRoot,
548
+ platform: "ios",
549
+ entryFile: "entry.ts"
550
+ })).rejects.toThrow("NATIVE_TRANSFORM_NEGATIVE_CONTROL");
551
+ } finally {
552
+ compiler.configureVXRNCompilerPlugin({
553
+ enableReanimated: false
554
+ });
555
+ await rm(testRoot, {
556
+ recursive: true,
557
+ force: true
558
+ });
559
+ }
560
+ });
561
+ it("rejects Hermes compatibility transform errors instead of returning source", async function () {
562
+ var plugin = hermesCompatSWCPlugin(true);
563
+ if (typeof plugin.transform !== "function") throw new Error("Hermes compatibility transform hook is not callable");
564
+ await expect(Reflect.apply(plugin.transform, void 0, ["class TransformProbe { value = ; }", "/project/TransformProbe.ts"])).rejects.toBeTruthy();
565
+ });
566
+ it("returns maps for every required production transform", async function () {
567
+ var testRoot = await createWorkletsProject(false);
568
+ var compiler = await import("@vxrn/compiler");
569
+ compiler.configureVXRNCompilerPlugin({
570
+ enableReanimated: true
571
+ });
572
+ try {
573
+ var compilerPlugin = vxrnCompilerPlugin("ios", false, testRoot, true);
574
+ if (typeof compilerPlugin.transform !== "function") throw new Error("vxrn compiler transform hook is not callable");
575
+ expect((await Reflect.apply(compilerPlugin.transform, void 0, [nativeTransformProbe, join(testRoot, "entry.ts")])).map).toBeTruthy();
576
+ var hermesPlugin = hermesCompatSWCPlugin(false, true);
577
+ if (typeof hermesPlugin.transform !== "function") throw new Error("Hermes compatibility transform hook is not callable");
578
+ expect((await Reflect.apply(hermesPlugin.transform, void 0, ["export class TransformProbe { value = 1 }", join(testRoot, "TransformProbe.ts")])).map).toBeTruthy();
579
+ } finally {
580
+ compiler.configureVXRNCompilerPlugin({
581
+ enableReanimated: false
582
+ });
583
+ await rm(testRoot, {
584
+ recursive: true,
585
+ force: true
586
+ });
587
+ }
588
+ });
589
+ });
590
+ describe("native production assets", function () {
591
+ it("registers scale siblings and keeps monorepo assets inside assetsDest", async function () {
592
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-assets-"));
593
+ var appRoot = join(testRoot, "workspace/apps/native-app");
594
+ var appAssets = join(appRoot, "assets");
595
+ var packageAssets = join(testRoot, "workspace/node_modules/example/assets");
596
+ var assetsDest = join(testRoot, "output");
597
+ await mkdir(appAssets, {
598
+ recursive: true
599
+ });
600
+ await mkdir(packageAssets, {
601
+ recursive: true
602
+ });
603
+ await writeFile(join(appAssets, "icon.png"), "icon-1x");
604
+ await writeFile(join(appAssets, "icon@2x.png"), "icon-2x");
605
+ await writeFile(join(appAssets, "icon@3x.png"), "icon-3x");
606
+ await writeFile(join(packageAssets, "back.png"), "back-1x");
607
+ await writeFile(join(packageAssets, "back@2x.png"), "back-2x");
608
+ await writeFile(join(appRoot, "entry.js"), `
609
+ import icon from './assets/icon.png'
610
+ import back from '../../node_modules/example/assets/back.png'
611
+ globalThis.__nativeAssetProbe = [icon, back]
612
+ `);
613
+ try {
614
+ var _registry_resolve;
615
+ var assetData = await getNativeAssetData(join(appAssets, "icon.png"), appRoot, "ios");
616
+ expect(assetData.scales).toEqual([1, 2, 3]);
617
+ expect(assetData.files.map(function (file2) {
618
+ return file2.slice(appAssets.length + 1);
619
+ })).toEqual(["icon.png", "icon@2x.png", "icon@3x.png"]);
620
+ expect(assetData.hash).not.toBe("");
621
+ var registry = createNativeDevAssetRegistry();
622
+ registry.register(assetData);
623
+ expect((_registry_resolve = registry.resolve("/assets/assets/icon@2x.png", assetData.hash)) === null || _registry_resolve === void 0 ? void 0 : _registry_resolve.filePath).toBe(join(appAssets, "icon@2x.png"));
624
+ expect(registry.resolve("/assets/assets/icon.png", "stale-content-hash")).toBeUndefined();
625
+ expect(registry.resolve("/assets/../../package.json", assetData.hash)).toBeUndefined();
626
+ expect((await buildNativeBundle({
627
+ root: appRoot,
628
+ platform: "ios",
629
+ entryFile: "entry.js",
630
+ assetsDest
631
+ })).code).toMatch(/"scales":\s*\[\s*1,\s*2,\s*3\s*\]/);
632
+ for (var _i = 0, _iter = ["icon.png", "icon@2x.png", "icon@3x.png"]; _i < _iter.length; _i++) {
633
+ var file = _iter[_i];
634
+ expect(existsSync(join(assetsDest, "assets/assets", file))).toBe(true);
635
+ }
636
+ for (var _i1 = 0, _iter1 = ["back.png", "back@2x.png"]; _i1 < _iter1.length; _i1++) {
637
+ var file1 = _iter1[_i1];
638
+ expect(existsSync(join(assetsDest, "assets/_/_/node_modules/example/assets", file1))).toBe(true);
639
+ }
640
+ expect(existsSync(join(testRoot, "node_modules/example/assets/back.png"))).toBe(false);
641
+ } finally {
642
+ await rm(testRoot, {
643
+ recursive: true,
644
+ force: true
645
+ });
646
+ }
647
+ });
648
+ });
649
+ describe("native conditional exports", function () {
650
+ it("uses the require condition for CommonJS calls", async function () {
651
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-conditions-"));
652
+ var packageRoot = join(testRoot, "node_modules/conditional-helper");
653
+ await mkdir(packageRoot, {
654
+ recursive: true
655
+ });
656
+ await writeFile(join(packageRoot, "package.json"), JSON.stringify({
657
+ name: "conditional-helper",
658
+ exports: {
659
+ ".": {
660
+ import: "./esm.js",
661
+ require: "./cjs.cjs"
662
+ }
663
+ },
664
+ type: "module"
665
+ }));
666
+ await writeFile(join(packageRoot, "esm.js"), `export default function helper() { return 'import' }`);
667
+ await writeFile(join(packageRoot, "cjs.cjs"), `module.exports = function helper() { return 'require' }`);
668
+ await writeFile(join(testRoot, "entry.cjs"), `
669
+ const helper = require('conditional-helper')
670
+ globalThis.__vxrnConditionalExportProbe = helper()
671
+ `);
672
+ try {
673
+ var result = await buildNativeBundle({
674
+ root: testRoot,
675
+ platform: "ios",
676
+ entryFile: "entry.cjs",
677
+ dev: true
678
+ });
679
+ var context = {
680
+ clearTimeout,
681
+ console,
682
+ process: {
683
+ env: {}
684
+ },
685
+ setTimeout
686
+ };
687
+ runInNewContext(result.code, context);
688
+ expect(Reflect.get(context, "__vxrnConditionalExportProbe")).toBe("require");
689
+ } finally {
690
+ await rm(testRoot, {
691
+ recursive: true,
692
+ force: true
693
+ });
694
+ }
695
+ });
696
+ it("unwraps the default export of Babel CommonJS modules in dev output", {
697
+ timeout: 3e4
698
+ }, async function () {
699
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-cjs-default-"));
700
+ var packageRoot = join(testRoot, "node_modules/default-export-helper");
701
+ await mkdir(packageRoot, {
702
+ recursive: true
703
+ });
704
+ await writeFile(join(packageRoot, "package.json"), JSON.stringify({
705
+ name: "default-export-helper",
706
+ main: "./index.js"
707
+ }));
708
+ await writeFile(join(packageRoot, "index.js"), `Object.defineProperty(exports, '__esModule', { value: true }); exports.default = function Component() {}`);
709
+ await writeFile(join(testRoot, "entry.js"), `import Component from 'default-export-helper'; globalThis.__vxrnCjsDefaultProbe = typeof Component`);
710
+ var resolveOutput;
711
+ var output = new Promise(function (resolve) {
712
+ resolveOutput = resolve;
713
+ });
714
+ var engine = await dev({
715
+ cwd: testRoot,
716
+ input: join(testRoot, "entry.js"),
717
+ experimental: {
718
+ devMode: {
719
+ implement: getHmrRuntimeSource()
720
+ }
721
+ }
722
+ }, {
723
+ format: "esm",
724
+ codeSplitting: false,
725
+ strictExecutionOrder: true
726
+ }, {
727
+ onOutput: resolveOutput
728
+ });
729
+ try {
730
+ await engine.run();
731
+ var result = await output;
732
+ if (_instanceof(result, Error)) throw result;
733
+ var chunk = result.output.find(function (item) {
734
+ return item.type === "chunk" && item.isEntry;
735
+ });
736
+ if (!chunk || chunk.type !== "chunk") throw new Error("Rolldown did not emit a native dev entry chunk");
737
+ var nodeModeCode = chunk.code.replace(/(\b__toESM(?:\$\d+)?\(\s*require[\w$]*\(\)\s*)\)/, "$1, 1)");
738
+ expect(nodeModeCode).not.toBe(chunk.code);
739
+ Reflect.deleteProperty(globalThis, "__rolldown_runtime__");
740
+ await import(`data:text/javascript;base64,${Buffer.from(nodeModeCode).toString("base64")}`);
741
+ expect(Reflect.get(globalThis, "__vxrnCjsDefaultProbe")).toBe("object");
742
+ Reflect.deleteProperty(globalThis, "__rolldown_runtime__");
743
+ Reflect.deleteProperty(globalThis, "__vxrnCjsDefaultProbe");
744
+ var normalized = normalizeNativeCommonJSInterop(nodeModeCode);
745
+ await import(`data:text/javascript;base64,${Buffer.from(normalized).toString("base64")}`);
746
+ expect(Reflect.get(globalThis, "__vxrnCjsDefaultProbe")).toBe("function");
747
+ } finally {
748
+ await engine.close();
749
+ Reflect.deleteProperty(globalThis, "__rolldown_runtime__");
750
+ Reflect.deleteProperty(globalThis, "__vxrnCjsDefaultProbe");
751
+ await rm(testRoot, {
752
+ recursive: true,
753
+ force: true
754
+ });
755
+ }
756
+ });
757
+ it("unwraps the default export of Babel CommonJS modules in production output", async function () {
758
+ var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-prod-cjs-default-"));
759
+ var packageRoot = join(testRoot, "node_modules/default-export-helper");
760
+ await mkdir(packageRoot, {
761
+ recursive: true
762
+ });
763
+ await writeFile(join(packageRoot, "package.json"), JSON.stringify({
764
+ name: "default-export-helper",
765
+ main: "./index.js"
766
+ }));
767
+ await writeFile(join(packageRoot, "index.js"), `Object.defineProperty(exports, '__esModule', { value: true }); exports.default = function Component() {}`);
768
+ await writeFile(join(testRoot, "entry.js"), `import Component from 'default-export-helper'; globalThis.__vxrnProdCjsDefaultProbe = typeof Component`);
769
+ try {
770
+ var result = await buildNativeBundle({
771
+ root: testRoot,
772
+ platform: "ios",
773
+ entryFile: "entry.js"
774
+ });
775
+ var context = {
776
+ clearTimeout,
777
+ console,
778
+ process: {
779
+ env: {}
780
+ },
781
+ setTimeout
782
+ };
783
+ runInNewContext(result.code, context);
784
+ expect(Reflect.get(context, "__vxrnProdCjsDefaultProbe")).toBe("function");
785
+ } finally {
786
+ await rm(testRoot, {
787
+ recursive: true,
788
+ force: true
789
+ });
790
+ }
791
+ });
792
+ });
240
793
  //# sourceMappingURL=createNativeDevEngine.test.native.js.map