vxrn 1.26.0 → 1.26.1

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 (42) hide show
  1. package/dist/plugins/reactNativeDevServer.mjs +123 -42
  2. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  3. package/dist/plugins/reactNativeDevServer.native.js +209 -44
  4. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  5. package/dist/rn-commands/bundle/buildBundle.mjs +29 -10
  6. package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
  7. package/dist/rn-commands/bundle/buildBundle.native.js +29 -10
  8. package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
  9. package/dist/utils/createNativeDevEngine.mjs +220 -83
  10. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  11. package/dist/utils/createNativeDevEngine.native.js +257 -84
  12. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  13. package/dist/utils/createNativeDevEngine.test.mjs +285 -23
  14. package/dist/utils/createNativeDevEngine.test.mjs.map +1 -1
  15. package/dist/utils/createNativeDevEngine.test.native.js +319 -23
  16. package/dist/utils/createNativeDevEngine.test.native.js.map +1 -1
  17. package/dist/utils/patches.test.mjs.map +1 -1
  18. package/dist/utils/patches.test.native.js.map +1 -1
  19. package/dist/utils/symbolicateNativeStack.mjs +66 -0
  20. package/dist/utils/symbolicateNativeStack.mjs.map +1 -0
  21. package/dist/utils/symbolicateNativeStack.native.js +70 -0
  22. package/dist/utils/symbolicateNativeStack.native.js.map +1 -0
  23. package/dist/utils/symbolicateNativeStack.test.mjs +96 -0
  24. package/dist/utils/symbolicateNativeStack.test.mjs.map +1 -0
  25. package/dist/utils/symbolicateNativeStack.test.native.js +96 -0
  26. package/dist/utils/symbolicateNativeStack.test.native.js.map +1 -0
  27. package/package.json +12 -11
  28. package/src/plugins/reactNativeDevServer.ts +162 -50
  29. package/src/rn-commands/bundle/buildBundle.ts +28 -9
  30. package/src/utils/createNativeDevEngine.test.ts +581 -193
  31. package/src/utils/createNativeDevEngine.ts +434 -115
  32. package/src/utils/patches.test.ts +1 -4
  33. package/src/utils/symbolicateNativeStack.test.ts +78 -0
  34. package/src/utils/symbolicateNativeStack.ts +129 -0
  35. package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
  36. package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
  37. package/types/utils/createNativeDevEngine.d.ts +23 -4
  38. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
  39. package/types/utils/symbolicateNativeStack.d.ts +46 -0
  40. package/types/utils/symbolicateNativeStack.d.ts.map +1 -0
  41. package/types/utils/symbolicateNativeStack.test.d.ts +2 -0
  42. package/types/utils/symbolicateNativeStack.test.d.ts.map +1 -0
@@ -1,14 +1,16 @@
1
- import { existsSync } from "fs";
1
+ import { existsSync, realpathSync } from "fs";
2
2
  import { mkdir, mkdtemp, rm, writeFile } from "fs/promises";
3
3
  import { tmpdir } from "os";
4
4
  import { join } from "path";
5
5
  import { createContext, runInContext, runInNewContext } from "vm";
6
+ import { TraceMap, originalPositionFor } from "@jridgewell/trace-mapping";
6
7
  import { rolldown } from "rolldown";
7
8
  import { dev } from "rolldown/experimental";
9
+ import { normalizePath } from "vite";
8
10
  import { describe, expect, it, vi } from "vitest";
9
11
  import { getNativePrelude } from "../runtime/native-prelude.native.js";
10
12
  import { workletImportsPlugin } from "../plugins/workletImportsPlugin.native.js";
11
- import { buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatSWCPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, vxrnCompilerPlugin, wrapNativeBundleModuleScope } from "./createNativeDevEngine.native.js";
13
+ import { buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatSWCPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, postProcessNativeBundle, vxrnCompilerPlugin, wrapNativeBundleModuleScope } from "./createNativeDevEngine.native.js";
12
14
  function _instanceof(left, right) {
13
15
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) return !!right[Symbol.hasInstance](left);else return left instanceof right;
14
16
  }
@@ -17,6 +19,108 @@ function _type_of(obj) {
17
19
 
18
20
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
19
21
  }
22
+ describe.each(["ios", "android"])("native plugin adapters on %s", function (platform) {
23
+ it.each(["dev", "build"])("binds configured plugins to the %s bundle", async function (mode) {
24
+ var root2 = await mkdtemp(join(tmpdir(), "vxrn-native-plugin-adapter-"));
25
+ await writeFile(join(root2, "entry.js"), `globalThis.nativePluginResult = [__GLOBAL_PLUGIN__, __DIRECT_PLUGIN__, 'plain-plugin']`);
26
+ var factories = ["global", "direct"].map(function (name) {
27
+ return vi.fn(function (context2) {
28
+ return {
29
+ name: `${name}-native`,
30
+ transform(code2, id) {
31
+ if (id.endsWith("/entry.js")) return code2.replace(`__${name.toUpperCase()}_PLUGIN__`, JSON.stringify({
32
+ name,
33
+ ...context2
34
+ }));
35
+ }
36
+ };
37
+ });
38
+ });
39
+ var plugins = factories.map(function (vxrnNative, index) {
40
+ return {
41
+ name: `adapter-${index}`,
42
+ api: {
43
+ vxrnNative
44
+ }
45
+ };
46
+ });
47
+ var previousPlugins = globalThis.__vxrnAddNativePlugins;
48
+ globalThis.__vxrnAddNativePlugins = [plugins[0]];
49
+ var configuredPlugins = [plugins[1], {
50
+ name: "plain-native-plugin",
51
+ transform(code2, id) {
52
+ if (id.endsWith("/__virtual-native-entry.tsx")) return `import './entry.js'`;
53
+ if (id.endsWith("/entry.js")) return code2.replace("plain-plugin", "plain");
54
+ }
55
+ }];
56
+ var native;
57
+ try {
58
+ var code;
59
+ if (mode === "dev") {
60
+ native = await createNativeDevEngine({
61
+ root: root2,
62
+ platform,
63
+ port: 0,
64
+ plugins: configuredPlugins
65
+ });
66
+ code = (await native.getBundle()).code;
67
+ } else code = (await buildNativeBundle({
68
+ root: root2,
69
+ platform,
70
+ entryFile: "entry.js",
71
+ plugins: configuredPlugins
72
+ })).code;
73
+ var context = {
74
+ console,
75
+ setTimeout,
76
+ clearTimeout,
77
+ __GLOBAL_PLUGIN__: "unadapted",
78
+ __DIRECT_PLUGIN__: "unadapted"
79
+ };
80
+ runInNewContext(code, context);
81
+ expect(Reflect.get(context, "nativePluginResult")).toEqual([{
82
+ name: "global",
83
+ root: root2,
84
+ platform,
85
+ dev: mode === "dev"
86
+ }, {
87
+ name: "direct",
88
+ root: root2,
89
+ platform,
90
+ dev: mode === "dev"
91
+ }, "plain"]);
92
+ var _iteratorNormalCompletion = true,
93
+ _didIteratorError = false,
94
+ _iteratorError = void 0;
95
+ try {
96
+ for (var _iterator = factories[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
97
+ var factory = _step.value;
98
+ expect(factory).toHaveBeenCalledExactlyOnceWith({
99
+ root: root2,
100
+ platform,
101
+ dev: mode === "dev"
102
+ });
103
+ }
104
+ } catch (err) {
105
+ _didIteratorError = true;
106
+ _iteratorError = err;
107
+ } finally {
108
+ try {
109
+ if (!_iteratorNormalCompletion && _iterator.return != null) _iterator.return();
110
+ } finally {
111
+ if (_didIteratorError) throw _iteratorError;
112
+ }
113
+ }
114
+ } finally {
115
+ await (native === null || native === void 0 ? void 0 : native.close());
116
+ globalThis.__vxrnAddNativePlugins = previousPlugins;
117
+ await rm(root2, {
118
+ recursive: true,
119
+ force: true
120
+ });
121
+ }
122
+ });
123
+ });
20
124
  var nativeTransformProbe = `
21
125
  export const transformProbe = () => {
22
126
  'worklet'
@@ -97,14 +201,14 @@ globalThis.result = (function(parentArgument) {
97
201
  return value === "closed";
98
202
  })).toHaveLength(1);
99
203
  var {
100
- originalPositionFor,
101
- TraceMap
204
+ originalPositionFor: originalPositionFor2,
205
+ TraceMap: TraceMap2
102
206
  } = await import("@jridgewell/trace-mapping");
103
207
  var lines = output.code.split("\n");
104
208
  var line = lines.findIndex(function (value) {
105
209
  return value.includes("after-await");
106
210
  });
107
- var position = originalPositionFor(new TraceMap(output.map), {
211
+ var position = originalPositionFor2(new TraceMap2(output.map), {
108
212
  line: line + 1,
109
213
  column: lines[line].indexOf("events.push")
110
214
  });
@@ -126,8 +230,8 @@ describe.each(["shared", "rolldown", "metro"])("React Compiler worklets through
126
230
  default: MagicString
127
231
  } = await import("magic-string");
128
232
  var {
129
- TraceMap,
130
- originalPositionFor
233
+ TraceMap: TraceMap2,
234
+ originalPositionFor: originalPositionFor2
131
235
  } = await import("@jridgewell/trace-mapping");
132
236
  var projectRoot = await createWorkletsProject(false);
133
237
  var sourceMaps = process.env.VXRN_ENABLE_SOURCE_MAP;
@@ -262,7 +366,7 @@ return ${pipeline === "metro" ? "module.exports.useProbe" : "useProbe"}`)(memo,
262
366
  return text.includes("function useProbe(");
263
367
  });
264
368
  expect(line).toBeGreaterThanOrEqual(0);
265
- var position = originalPositionFor(new TraceMap(result.map), {
369
+ var position = originalPositionFor2(new TraceMap2(result.map), {
266
370
  line: line + 1,
267
371
  column: lines[line].indexOf("function")
268
372
  });
@@ -438,6 +542,7 @@ if (import.meta.hot) import.meta.hot.accept(() => {})
438
542
  "pure-math": ["default", "reads"]
439
543
  })]
440
544
  });
545
+ expect(production.code).not.toContain("__esmMin");
441
546
  var productionRN = {
442
547
  console
443
548
  };
@@ -446,6 +551,23 @@ if (import.meta.hot) import.meta.hot.accept(() => {})
446
551
  expect(reconstruct(productionRN.calculate)(10)).toBe(109);
447
552
  expect(reconstruct(productionRN.reads)()).toBe(3);
448
553
  expect(productionRN.reads()).toBe(1);
554
+ var unminifiedProduction = await buildNativeBundle({
555
+ root: root2,
556
+ platform: "android",
557
+ entryFile: "production.mjs",
558
+ minify: false,
559
+ plugins: [workletImportsPlugin({
560
+ "pure-math": ["default", "reads"]
561
+ })]
562
+ });
563
+ expect(unminifiedProduction.code).toContain("__esmMin");
564
+ var unminifiedRN = {
565
+ console
566
+ };
567
+ runInNewContext(unminifiedProduction.code, unminifiedRN);
568
+ expect(unminifiedRN.calculate(10)).toBe(109);
569
+ expect(reconstruct(unminifiedRN.calculate)(10)).toBe(109);
570
+ expect(reconstruct(unminifiedRN.reads)()).toBe(3);
449
571
  var sharedPlugin = workletImportsPlugin({
450
572
  "pure-math": ["default", "reads"]
451
573
  });
@@ -1148,8 +1270,8 @@ describe("native required transform failures", function () {
1148
1270
  });
1149
1271
  it("composes source maps across React Compiler, Fast Refresh, and module wrapper back to original source lines", async function () {
1150
1272
  var {
1151
- TraceMap,
1152
- originalPositionFor
1273
+ TraceMap: TraceMap2,
1274
+ originalPositionFor: originalPositionFor2
1153
1275
  } = await import("@jridgewell/trace-mapping");
1154
1276
  var compiler = await import("@vxrn/compiler");
1155
1277
  compiler.configureVXRNCompilerPlugin({
@@ -1169,12 +1291,12 @@ export function Counter() {
1169
1291
  var result = await Reflect.apply(plugin.transform, void 0, [inputCode, id]);
1170
1292
  expect(result).toBeDefined();
1171
1293
  expect(result.map).toBeDefined();
1172
- var tracer = new TraceMap(result.map);
1294
+ var tracer = new TraceMap2(result.map);
1173
1295
  var counterLineIndex = result.code.split("\n").findIndex(function (l) {
1174
1296
  return l.includes("function Counter");
1175
1297
  });
1176
1298
  expect(counterLineIndex).toBeGreaterThan(0);
1177
- var pos = originalPositionFor(tracer, {
1299
+ var pos = originalPositionFor2(tracer, {
1178
1300
  line: counterLineIndex + 1,
1179
1301
  column: 16
1180
1302
  });
@@ -1188,8 +1310,8 @@ export function Counter() {
1188
1310
  });
1189
1311
  it("composes source maps accurately across mixed path (React Compiler + Babel + Fast Refresh + module wrapper)", async function () {
1190
1312
  var {
1191
- TraceMap,
1192
- originalPositionFor
1313
+ TraceMap: TraceMap2,
1314
+ originalPositionFor: originalPositionFor2
1193
1315
  } = await import("@jridgewell/trace-mapping");
1194
1316
  var compiler = await import("@vxrn/compiler");
1195
1317
  var origEnv = process.env.VXRN_USE_BABEL_FOR_GENERATORS;
@@ -1216,14 +1338,14 @@ export async function* probe() { throw new Error("MARKER"); }
1216
1338
  expect(result).toBeDefined();
1217
1339
  expect(result.map).toBeDefined();
1218
1340
  expect(result.code.includes("_wrapAsyncGenerator") || result.code.includes("regeneratorRuntime")).toBe(true);
1219
- var tracer = new TraceMap(result.map);
1341
+ var tracer = new TraceMap2(result.map);
1220
1342
  var lines = result.code.split("\n");
1221
1343
  var markerLineIndex = lines.findIndex(function (l) {
1222
1344
  return l.includes("MARKER");
1223
1345
  });
1224
1346
  expect(markerLineIndex).toBeGreaterThan(0);
1225
1347
  var markerCol = lines[markerLineIndex].indexOf("throw");
1226
- var pos = originalPositionFor(tracer, {
1348
+ var pos = originalPositionFor2(tracer, {
1227
1349
  line: markerLineIndex + 1,
1228
1350
  column: markerCol
1229
1351
  });
@@ -1232,7 +1354,7 @@ export async function* probe() { throw new Error("MARKER"); }
1232
1354
  expect(pos.column).toBe(33);
1233
1355
  var compilerOut = await compiler.transformOxcReactCompiler(id, inputCode, "19", true);
1234
1356
  var remapping = (await import("@jridgewell/remapping")).default;
1235
- var badPos = originalPositionFor(new TraceMap(remapping([result.map, compilerOut.map], function () {
1357
+ var badPos = originalPositionFor2(new TraceMap2(remapping([result.map, compilerOut.map], function () {
1236
1358
  return null;
1237
1359
  })), {
1238
1360
  line: markerLineIndex + 1,
@@ -1249,8 +1371,8 @@ export async function* probe() { throw new Error("MARKER"); }
1249
1371
  });
1250
1372
  it("transforms worklets via native Rust/Wasm SWC with zero Babel execution and accurate sourcemaps", async function () {
1251
1373
  var {
1252
- TraceMap,
1253
- originalPositionFor
1374
+ TraceMap: TraceMap2,
1375
+ originalPositionFor: originalPositionFor2
1254
1376
  } = await import("@jridgewell/trace-mapping");
1255
1377
  var compiler = await import("@vxrn/compiler");
1256
1378
  var {
@@ -1282,12 +1404,12 @@ export function Box() {
1282
1404
  expect(result.code).toContain("__closure");
1283
1405
  expect(babelSpy).not.toHaveBeenCalled();
1284
1406
  expect(result.map).toBeDefined();
1285
- var tracer = new TraceMap(result.map);
1407
+ var tracer = new TraceMap2(result.map);
1286
1408
  var boxLineIndex = result.code.split("\n").findIndex(function (l) {
1287
1409
  return l.includes("export function Box");
1288
1410
  });
1289
1411
  expect(boxLineIndex).toBeGreaterThan(0);
1290
- var pos = originalPositionFor(tracer, {
1412
+ var pos = originalPositionFor2(tracer, {
1291
1413
  line: boxLineIndex + 1,
1292
1414
  column: 16
1293
1415
  });
@@ -1379,6 +1501,92 @@ export function Box() {
1379
1501
  }
1380
1502
  });
1381
1503
  });
1504
+ describe("native production minification", function () {
1505
+ async function writeMinifyFixture() {
1506
+ var root2 = await mkdtemp(join(tmpdir(), "vxrn-native-minify-"));
1507
+ var dep = join(root2, "node_modules", "legacy-color");
1508
+ await mkdir(dep, {
1509
+ recursive: true
1510
+ });
1511
+ await writeFile(join(dep, "package.json"), JSON.stringify({
1512
+ name: "legacy-color",
1513
+ main: "index.js"
1514
+ }));
1515
+ await writeFile(join(dep, "index.js"), `function LegacyColor(value) { this.value = value }
1516
+ LegacyColor.prototype.describe = function () { return 'legacy:' + this.value }
1517
+ module.exports = LegacyColor`);
1518
+ await writeFile(join(root2, "views.js"), `'use strict';
1519
+ import LegacyColor from 'legacy-color'
1520
+ import { level } from './entry.js'
1521
+ export const describeHeader = () => new LegacyColor(level()).describe()`);
1522
+ await writeFile(join(root2, "entry.js"), `import { describeHeader } from './views.js'
1523
+ export const level = () => 'header'
1524
+ globalThis.minifyProbe = describeHeader()`);
1525
+ return root2;
1526
+ }
1527
+ function runFixture(code) {
1528
+ var context = {
1529
+ console
1530
+ };
1531
+ runInNewContext(code, context);
1532
+ return Reflect.get(context, "minifyProbe");
1533
+ }
1534
+ it("minifies when asked, leaves the bundle alone when not, and both behave the same", async function () {
1535
+ var root2 = await writeMinifyFixture();
1536
+ try {
1537
+ var [plain, minified] = await Promise.all([false, true].map(function (minify) {
1538
+ return buildNativeBundle({
1539
+ root: root2,
1540
+ platform: "ios",
1541
+ entryFile: "entry.js",
1542
+ minify
1543
+ });
1544
+ }));
1545
+ expect(plain.code).toContain("__toESM");
1546
+ expect(plain.code).toContain("describeHeader");
1547
+ expect(plain.code.split("\n").length).toBeGreaterThan(40);
1548
+ expect(minified.code).not.toContain("describeHeader");
1549
+ expect(minified.code).not.toContain("//#region");
1550
+ expect(minified.code.length).toBeLessThan(plain.code.length * .7);
1551
+ expect(runFixture(minified.code)).toBe("legacy:header");
1552
+ expect(runFixture(plain.code)).toBe("legacy:header");
1553
+ } finally {
1554
+ await rm(root2, {
1555
+ recursive: true,
1556
+ force: true
1557
+ });
1558
+ }
1559
+ });
1560
+ it("defaults to react native's rule: minify a production bundle, never a dev one", async function () {
1561
+ var root2 = await writeMinifyFixture();
1562
+ try {
1563
+ var [prod, devBundle, explicitOff] = await Promise.all([buildNativeBundle({
1564
+ root: root2,
1565
+ platform: "ios",
1566
+ entryFile: "entry.js"
1567
+ }), buildNativeBundle({
1568
+ root: root2,
1569
+ platform: "ios",
1570
+ entryFile: "entry.js",
1571
+ dev: true
1572
+ }), buildNativeBundle({
1573
+ root: root2,
1574
+ platform: "ios",
1575
+ entryFile: "entry.js",
1576
+ minify: false
1577
+ })]);
1578
+ expect(prod.code).not.toContain("describeHeader");
1579
+ expect(devBundle.code).toContain("describeHeader");
1580
+ expect(explicitOff.code).toContain("describeHeader");
1581
+ expect(prod.code.length).toBeLessThan(explicitOff.code.length);
1582
+ } finally {
1583
+ await rm(root2, {
1584
+ recursive: true,
1585
+ force: true
1586
+ });
1587
+ }
1588
+ });
1589
+ });
1382
1590
  describe("native production assets", function () {
1383
1591
  it("registers scale siblings and keeps monorepo assets inside assetsDest", async function () {
1384
1592
  var testRoot = await mkdtemp(join(tmpdir(), "vxrn-native-assets-"));
@@ -1415,12 +1623,27 @@ globalThis.__nativeAssetProbe = [icon, back]
1415
1623
  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"));
1416
1624
  expect(registry.resolve("/assets/assets/icon.png", "stale-content-hash")).toBeUndefined();
1417
1625
  expect(registry.resolve("/assets/../../package.json", assetData.hash)).toBeUndefined();
1418
- expect((await buildNativeBundle({
1626
+ var result = await buildNativeBundle({
1419
1627
  root: appRoot,
1420
1628
  platform: "ios",
1421
1629
  entryFile: "entry.js",
1422
1630
  assetsDest
1423
- })).code).toMatch(/"scales":\s*\[\s*1,\s*2,\s*3\s*\]/);
1631
+ });
1632
+ var registered = [];
1633
+ runInNewContext(result.code, {
1634
+ console,
1635
+ require: function (id) {
1636
+ return id === "react-native/Libraries/Image/AssetRegistry" ? {
1637
+ registerAsset: function (asset) {
1638
+ registered.push(asset);
1639
+ return asset;
1640
+ }
1641
+ } : {};
1642
+ }
1643
+ });
1644
+ expect(registered.map(function (asset) {
1645
+ return [asset.name, asset.scales];
1646
+ })).toEqual([["icon", [1, 2, 3]], ["back", [1, 2]]]);
1424
1647
  for (var _i = 0, _iter = ["icon.png", "icon@2x.png", "icon@3x.png"]; _i < _iter.length; _i++) {
1425
1648
  var file = _iter[_i];
1426
1649
  expect(existsSync(join(assetsDest, "assets/assets", file))).toBe(true);
@@ -1643,4 +1866,77 @@ globalThis.__vxrnFlowProbe = new Flowy().measure({ value: 41 }) + 1
1643
1866
  }
1644
1867
  });
1645
1868
  });
1869
+ describe("native bundle source maps", function () {
1870
+ var generatedPositionOf = function (code, marker) {
1871
+ var _ref;
1872
+ var _before_match;
1873
+ var index = code.indexOf(marker);
1874
+ expect(index).toBeGreaterThan(-1);
1875
+ var before = code.slice(0, index);
1876
+ var lastNewline = before.lastIndexOf("\n");
1877
+ return {
1878
+ line: ((_ref = (_before_match = before.match(/\n/g)) === null || _before_match === void 0 ? void 0 : _before_match.length) !== null && _ref !== void 0 ? _ref : 0) + 1,
1879
+ column: index - lastNewline - 1
1880
+ };
1881
+ };
1882
+ it("resolves a frame to the authored file and line across an app file and a package file", {
1883
+ timeout: 6e4
1884
+ }, async function () {
1885
+ var testRoot = realpathSync(await mkdtemp(join(tmpdir(), "vxrn-native-sourcemap-")));
1886
+ var packageRoot = join(testRoot, "node_modules/probe-package");
1887
+ await mkdir(packageRoot, {
1888
+ recursive: true
1889
+ });
1890
+ await writeFile(join(packageRoot, "package.json"), JSON.stringify({
1891
+ name: "probe-package",
1892
+ main: "index.js",
1893
+ type: "module"
1894
+ }));
1895
+ await writeFile(join(packageRoot, "index.js"), [`function packageThrow() {`, ` throw new Error('__probe_package__')`, `}`, ``, `export default packageThrow`].join("\n"));
1896
+ await writeFile(join(testRoot, "entry.js"), [`import packageThrow from 'probe-package'`, ``, `function appThrow() {`, ` throw new Error('__probe_app__')`, `}`, ``, `globalThis.__probe = [appThrow, packageThrow]`].join("\n"));
1897
+ try {
1898
+ var _app_source, _pkg_source;
1899
+ var result = await buildNativeBundle({
1900
+ root: testRoot,
1901
+ platform: "ios",
1902
+ entryFile: "entry.js",
1903
+ dev: true,
1904
+ sourcemap: true
1905
+ });
1906
+ expect(result.map).toBeTruthy();
1907
+ var traced = new TraceMap(JSON.parse(result.map));
1908
+ var app = originalPositionFor(traced, generatedPositionOf(result.code, "__probe_app__"));
1909
+ var pkg = originalPositionFor(traced, generatedPositionOf(result.code, "__probe_package__"));
1910
+ expect((_app_source = app.source) === null || _app_source === void 0 ? void 0 : _app_source.endsWith("/entry.js")).toBe(true);
1911
+ expect(app.line).toBe(4);
1912
+ expect((_pkg_source = pkg.source) === null || _pkg_source === void 0 ? void 0 : _pkg_source.endsWith("/index.js")).toBe(true);
1913
+ expect(pkg.line).toBe(2);
1914
+ expect(app.source).toBe(normalizePath(join(testRoot, "entry.js")));
1915
+ expect(pkg.source).toBe(normalizePath(join(packageRoot, "index.js")));
1916
+ } finally {
1917
+ await rm(testRoot, {
1918
+ recursive: true,
1919
+ force: true
1920
+ });
1921
+ }
1922
+ });
1923
+ });
1924
+ describe("postProcessNativeBundle", function () {
1925
+ var lines = function (code) {
1926
+ return code.split("\n").length;
1927
+ };
1928
+ it("keeps the blank line above an export default", function () {
1929
+ var input = ["var a = 1;", "", "export default a;", "var b = 2;", ""].join("\n");
1930
+ var out = postProcessNativeBundle(input);
1931
+ expect(lines(out)).toBe(lines(input));
1932
+ expect(out.split("\n")[2]).toBe("a;");
1933
+ });
1934
+ it("keeps the lines of a multi-line export statement", function () {
1935
+ var input = ["var a = 1;", "export {", " a", "};", "var b = 2;", ""].join("\n");
1936
+ var out = postProcessNativeBundle(input);
1937
+ expect(lines(out)).toBe(lines(input));
1938
+ expect(out).not.toContain("export {");
1939
+ expect(out.split("\n")[4]).toBe("var b = 2;");
1940
+ });
1941
+ });
1646
1942
  //# sourceMappingURL=createNativeDevEngine.test.native.js.map