vxrn 1.17.11 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/plugins/reactNativeDevServer.mjs +5 -5
  2. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  3. package/dist/plugins/reactNativeDevServer.native.js +5 -5
  4. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  5. package/dist/rn-commands/bundle/buildBundle.mjs +2 -0
  6. package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
  7. package/dist/rn-commands/bundle/buildBundle.native.js +2 -0
  8. package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
  9. package/dist/runtime/native-prelude.mjs +1 -0
  10. package/dist/runtime/native-prelude.mjs.map +1 -1
  11. package/dist/runtime/native-prelude.native.js +1 -0
  12. package/dist/runtime/native-prelude.native.js.map +1 -1
  13. package/dist/user-interface/index.mjs +3 -2
  14. package/dist/user-interface/index.mjs.map +1 -1
  15. package/dist/user-interface/index.native.js +3 -2
  16. package/dist/user-interface/index.native.js.map +1 -1
  17. package/dist/utils/createNativeDevEngine.mjs +125 -179
  18. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  19. package/dist/utils/createNativeDevEngine.native.js +144 -217
  20. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  21. package/dist/utils/createNativeDevEngine.test.mjs +43 -0
  22. package/dist/utils/createNativeDevEngine.test.mjs.map +1 -0
  23. package/dist/utils/createNativeDevEngine.test.native.js +53 -0
  24. package/dist/utils/createNativeDevEngine.test.native.js.map +1 -0
  25. package/dist/utils/getBoundPort.mjs +9 -0
  26. package/dist/utils/getBoundPort.mjs.map +1 -0
  27. package/dist/utils/getBoundPort.native.js +16 -0
  28. package/dist/utils/getBoundPort.native.js.map +1 -0
  29. package/dist/utils/getBoundPort.test.mjs +71 -0
  30. package/dist/utils/getBoundPort.test.mjs.map +1 -0
  31. package/dist/utils/getBoundPort.test.native.js +82 -0
  32. package/dist/utils/getBoundPort.test.native.js.map +1 -0
  33. package/expo-plugin.cjs +34 -0
  34. package/package.json +12 -12
  35. package/src/plugins/reactNativeDevServer.ts +5 -4
  36. package/src/rn-commands/bundle/buildBundle.ts +3 -0
  37. package/src/runtime/native-prelude.ts +1 -0
  38. package/src/user-interface/index.ts +3 -2
  39. package/src/utils/createNativeDevEngine.test.ts +66 -0
  40. package/src/utils/createNativeDevEngine.ts +66 -3
  41. package/src/utils/getBoundPort.test.ts +59 -0
  42. package/src/utils/getBoundPort.ts +14 -0
  43. package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
  44. package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
  45. package/types/runtime/native-prelude.d.ts.map +1 -1
  46. package/types/user-interface/index.d.ts.map +1 -1
  47. package/types/utils/createNativeDevEngine.d.ts +35 -0
  48. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
  49. package/types/utils/createNativeDevEngine.test.d.ts +2 -0
  50. package/types/utils/createNativeDevEngine.test.d.ts.map +1 -0
  51. package/types/utils/getBoundPort.d.ts +3 -0
  52. package/types/utils/getBoundPort.d.ts.map +1 -0
  53. package/types/utils/getBoundPort.test.d.ts +2 -0
  54. package/types/utils/getBoundPort.test.d.ts.map +1 -0
@@ -0,0 +1,66 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import {
3
+ getNativeTransformConfig,
4
+ wrapNativeBundleModuleScope,
5
+ } from './createNativeDevEngine'
6
+
7
+ // use a root with no .env files so only the platform defines are present
8
+ const root = '/tmp/vxrn-native-env-define-test-nonexistent'
9
+
10
+ describe('getNativeTransformConfig platform env defines', () => {
11
+ for (const platform of ['ios', 'android'] as const) {
12
+ for (const dev of [true, false]) {
13
+ it(`injects TAMAGUI_TARGET=native for ${platform} (dev=${dev})`, () => {
14
+ const { define } = getNativeTransformConfig(platform, dev, root)
15
+
16
+ // regression: TAMAGUI_TARGET was missing from the rolldown native defines,
17
+ // so import.meta.env.TAMAGUI_TARGET resolved to '' in prod (metro had it, rolldown didn't)
18
+ expect(define['import.meta.env.TAMAGUI_TARGET']).toBe('"native"')
19
+ expect(define['process.env.TAMAGUI_TARGET']).toBe('"native"')
20
+ expect(define['import.meta.env.TAMAGUI_ENVIRONMENT']).toBe(JSON.stringify(platform))
21
+
22
+ // sibling platform vars that already worked — guard against accidental removal
23
+ expect(define['import.meta.env.VITE_ENVIRONMENT']).toBe(JSON.stringify(platform))
24
+ expect(define['import.meta.env.VITE_NATIVE']).toBe('"1"')
25
+ expect(define['import.meta.env.EXPO_OS']).toBe(JSON.stringify(platform))
26
+
27
+ // the whole import.meta.env object (used by JSON.stringify(import.meta.env)) must carry it too
28
+ const envObject = JSON.parse(define['import.meta.env'] as string)
29
+ expect(envObject.TAMAGUI_TARGET).toBe('native')
30
+ expect(envObject.TAMAGUI_ENVIRONMENT).toBe(platform)
31
+ })
32
+ }
33
+ }
34
+ })
35
+
36
+ describe('wrapNativeBundleModuleScope', () => {
37
+ // matches the marker rolldown dev() emits at the start of the runtime region
38
+ const RUNTIME_MARKER = '//#region \\0rolldown/runtime.js'
39
+
40
+ it('wraps module code after the prelude so top-level vars do not leak to global', () => {
41
+ const prelude = 'globalThis.global = globalThis;\nglobalThis.__DEV__ = true;\n'
42
+ // a top-level `var Headers` in a script becomes a non-configurable global,
43
+ // which is the exact leak that breaks RN's polyfillGlobal in dev
44
+ const body = `${RUNTIME_MARKER}\nvar fetch_hot, fetch$1, Headers, Request, Response$1;\nglobalThis.__rolldown_runtime__ = {};\n`
45
+ const sourcemap = '\n//# sourceMappingURL=x.js.map'
46
+
47
+ const out = wrapNativeBundleModuleScope(prelude + body + sourcemap)
48
+
49
+ const openIdx = out.indexOf(';(function() {')
50
+ expect(openIdx).toBeGreaterThan(-1)
51
+ // prelude (global setup) stays at script scope, before the wrap opens
52
+ expect(out.indexOf('globalThis.__DEV__')).toBeLessThan(openIdx)
53
+ // the leaking declaration is now inside the function scope
54
+ expect(out.indexOf('var fetch_hot')).toBeGreaterThan(openIdx)
55
+ // the wrap closes before the sourceMappingURL, which must remain the last line
56
+ expect(out.indexOf('})();')).toBeLessThan(out.indexOf('//# sourceMappingURL'))
57
+ expect(out.trimEnd().endsWith('//# sourceMappingURL=x.js.map')).toBe(true)
58
+ // and the result must still be syntactically valid (balanced wrap)
59
+ expect(() => new Function(out)).not.toThrow()
60
+ })
61
+
62
+ it('is a no-op when the runtime marker is absent (e.g. prod bundle)', () => {
63
+ const input = 'var x = 1;\nconsole.log(x);\n'
64
+ expect(wrapNativeBundleModuleScope(input)).toBe(input)
65
+ })
66
+ })
@@ -54,7 +54,7 @@ function getNativeResolveConfig(platform: 'ios' | 'android') {
54
54
  }
55
55
 
56
56
  // shared rolldown transform config for native builds
57
- function getNativeTransformConfig(
57
+ export function getNativeTransformConfig(
58
58
  platform: 'ios' | 'android',
59
59
  dev: boolean,
60
60
  root: string
@@ -124,6 +124,8 @@ function getNativeTransformConfig(
124
124
  VITE_ENVIRONMENT: platform,
125
125
  VITE_NATIVE: '1',
126
126
  EXPO_OS: platform,
127
+ TAMAGUI_TARGET: 'native',
128
+ TAMAGUI_ENVIRONMENT: platform,
127
129
  }
128
130
  // add VITE_* from .env files
129
131
  for (const [key, val] of Object.entries(envDefines)) {
@@ -149,6 +151,7 @@ function getNativeTransformConfig(
149
151
  'process.env.VITE_ENVIRONMENT': JSON.stringify(platform),
150
152
  'process.env.VITE_NATIVE': '"1"',
151
153
  'process.env.EXPO_OS': JSON.stringify(platform),
154
+ 'process.env.TAMAGUI_TARGET': '"native"',
152
155
  'process.env.TAMAGUI_ENVIRONMENT': JSON.stringify(platform),
153
156
  __DEV__: dev ? 'true' : 'false',
154
157
  // import.meta.env as a whole object (for JSON.stringify(import.meta.env) etc.)
@@ -161,6 +164,8 @@ function getNativeTransformConfig(
161
164
  'import.meta.env.VITE_ENVIRONMENT': JSON.stringify(platform),
162
165
  'import.meta.env.VITE_NATIVE': '"1"',
163
166
  'import.meta.env.EXPO_OS': JSON.stringify(platform),
167
+ 'import.meta.env.TAMAGUI_TARGET': '"native"',
168
+ 'import.meta.env.TAMAGUI_ENVIRONMENT': JSON.stringify(platform),
164
169
  ...envDefines,
165
170
  ...setupFileDefines,
166
171
  },
@@ -225,6 +230,7 @@ function postProcessNativeBundle(code: string): string {
225
230
  // rolldown devMode still emits ESM export statements that hermes can't parse.
226
231
  // this is a rolldown behavior we can't configure away yet.
227
232
  code = code.replace(/^\s*export\s*\{[^}]*\}\s*;?\s*$/gm, '')
233
+ code = code.replace(/^\s*export\s+default\s+([^;\n]+);?\s*$/gm, '$1;')
228
234
  // rolldown devMode runtime leaves some raw import.meta.hot references
229
235
  // that aren't compiled through the normal plugin pipeline.
230
236
  code = code.replace(/^if \(import\.meta\.hot\).*$/gm, '')
@@ -255,6 +261,48 @@ function postProcessNativeBundle(code: string): string {
255
261
  return code
256
262
  }
257
263
 
264
+ /**
265
+ * Wrap the dev bundle body in a function scope so module top-level
266
+ * `var`/`function` declarations don't leak onto the global object.
267
+ *
268
+ * rolldown's dev() emits the bundle as a *script*. A top-level `var` in a
269
+ * script creates a NON-configurable property on the global object. RN's
270
+ * `Libraries/Network/fetch.js` declares `var ... Headers, Request, ...`, so
271
+ * `global.Headers`/`global.Request` become non-configurable. RN's `setUpXHR`
272
+ * then calls `polyfillGlobal('Headers', ...)`, whose `polyfillObjectProperty`
273
+ * does `Object.defineProperty(global, 'Headers', { configurable: true, ... })`
274
+ * — which throws "Cannot redefine property" and RN converts to
275
+ * `console.error('Failed to set polyfill. Headers is not configurable.')`.
276
+ * In dev that console.error becomes a blocking LogBox redbox, so the app never
277
+ * mounts (every appium navigation then times out). The prod build is immune:
278
+ * its modules are wrapped in closures (no global leak) and it has no LogBox.
279
+ *
280
+ * Wrapping everything after the prelude in an IIFE makes those module vars
281
+ * function-scoped, matching prod, so `polyfillGlobal` succeeds. The prelude
282
+ * stays at script scope because it intentionally installs globals
283
+ * (`globalThis.global`/`__DEV__`/`process`/...). Intentional globals survive:
284
+ * the runtime is assigned via `globalThis.__rolldown_runtime__ = ...`, and HMR
285
+ * updates run through a *direct* `eval` inside this scope, so they still see
286
+ * the closure's `__esmMin`/`__toCommonJS`/module bindings.
287
+ */
288
+ export function wrapNativeBundleModuleScope(code: string): string {
289
+ // the prelude (intro) ends right before the rolldown runtime region
290
+ const marker = '//#region \\0rolldown/runtime.js'
291
+ const idx = code.indexOf(marker)
292
+ if (idx === -1) return code
293
+
294
+ const open = ';(function() {\n'
295
+ const close = '\n})();\n'
296
+
297
+ // keep the sourceMappingURL comment as the final line if present
298
+ const sm = code.match(/\n\/\/# sourceMappingURL=[^\n]*\s*$/)
299
+ if (sm) {
300
+ const smIdx = code.lastIndexOf(sm[0])
301
+ return code.slice(0, idx) + open + code.slice(idx, smIdx) + close + code.slice(smIdx)
302
+ }
303
+ return code.slice(0, idx) + open + code.slice(idx) + close
304
+ }
305
+
258
306
  /**
259
307
  * Downlevel class fields in the rolldown runtime for Hermes compatibility.
260
308
  * The runtime (\0rolldown/runtime.js) is injected directly into the output,
@@ -430,6 +478,11 @@ try {
430
478
  (match) => hmrClientStub + ',' + match
431
479
  )
432
480
 
481
+ // wrap module code in a function scope so top-level `var`s (e.g. RN
482
+ // fetch.js's `Headers`/`Request`) don't leak as non-configurable
483
+ // globals and break RN's polyfillGlobal (dev-only redbox). see fn doc.
484
+ code = wrapNativeBundleModuleScope(code)
485
+
433
486
  currentBundle = {
434
487
  code,
435
488
  map: chunk.map?.toString(),
@@ -512,6 +565,7 @@ interface NativeBuildOptions {
512
565
  platform: 'ios' | 'android'
513
566
  dev?: boolean
514
567
  serverUrl?: string
568
+ entryFile?: string
515
569
  assetsDest?: string
516
570
  plugins?: Plugin[]
517
571
  }
@@ -524,6 +578,7 @@ export async function buildNativeBundle(
524
578
  platform,
525
579
  dev = false,
526
580
  serverUrl,
581
+ entryFile,
527
582
  assetsDest,
528
583
  plugins: userPlugins = [],
529
584
  } = options
@@ -536,9 +591,12 @@ export async function buildNativeBundle(
536
591
  platform,
537
592
  serverUrl,
538
593
  })
594
+ const buildEntry = entryFile
595
+ ? normalizePath(resolve(root, entryFile))
596
+ : VIRTUAL_NATIVE_ENTRY
539
597
 
540
598
  const result = await build({
541
- input: VIRTUAL_NATIVE_ENTRY,
599
+ input: buildEntry,
542
600
  cwd: root,
543
601
  platform: 'neutral',
544
602
  resolve: getNativeResolveConfig(platform),
@@ -547,7 +605,7 @@ export async function buildNativeBundle(
547
605
  shimMissingExports: true,
548
606
  moduleTypes: { '.js': 'jsx' },
549
607
  plugins: [
550
- nativeVirtualEntryPlugin(root, { dev }),
608
+ ...(entryFile ? [] : [nativeVirtualEntryPlugin(root, { dev })]),
551
609
  ...getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest),
552
610
  ...userPlugins,
553
611
  ],
@@ -622,9 +680,14 @@ globalThis.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform;
622
680
 
623
681
  const entryCode = `
624
682
  ${refreshSetup}
683
+ import * as ReactNativeInitializeCore from 'react-native/Libraries/Core/InitializeCore';
684
+ import NativeWebSocket from 'react-native/Libraries/WebSocket/WebSocket';
625
685
  ${setupFileImport}
626
686
  import { createApp } from 'one';
627
687
 
688
+ void ReactNativeInitializeCore;
689
+ globalThis.WebSocket = NativeWebSocket;
690
+
628
691
  var _routes = import.meta.glob(${JSON.stringify(routeGlobs)}, { exhaustive: true });
629
692
  // fix route keys: One expects '/${routerRoot}/...' prefix but import.meta.glob returns './${routerRoot}/...'
630
693
  var routes = {};
@@ -0,0 +1,59 @@
1
+ import { createServer } from 'node:http'
2
+ import type { ViteDevServer } from 'vite'
3
+ import { describe, expect, it } from 'vitest'
4
+ import { getBoundPort } from './getBoundPort'
5
+
6
+ // minimal fake matching only the fields getBoundPort reads
7
+ function fakeServer(opts: {
8
+ address?: { port: number } | string | null
9
+ configPort?: number
10
+ }): ViteDevServer {
11
+ return {
12
+ httpServer:
13
+ opts.address === undefined ? undefined : { address: () => opts.address ?? null },
14
+ config: { server: { port: opts.configPort } },
15
+ } as unknown as ViteDevServer
16
+ }
17
+
18
+ describe('getBoundPort', () => {
19
+ it('returns the actually-bound port from httpServer.address(), ignoring a stale/undefined config port (the 8081 trap)', () => {
20
+ // dev server resolved to 8082 (8081 was taken) but config.server.port is undefined
21
+ expect(getBoundPort(fakeServer({ address: { port: 8082 }, configPort: undefined }))).toBe(
22
+ 8082
23
+ )
24
+ })
25
+
26
+ it('prefers the bound port even when config.server.port disagrees', () => {
27
+ expect(getBoundPort(fakeServer({ address: { port: 8082 }, configPort: 8081 }))).toBe(8082)
28
+ })
29
+
30
+ it('falls back to config.server.port when the server is not yet listening', () => {
31
+ expect(getBoundPort(fakeServer({ address: null, configPort: 8085 }))).toBe(8085)
32
+ })
33
+
34
+ it('falls back to 8081 when nothing is available', () => {
35
+ expect(getBoundPort(fakeServer({ address: null, configPort: undefined }))).toBe(8081)
36
+ })
37
+
38
+ it('ignores a unix-socket/pipe address (string) and falls back to config', () => {
39
+ expect(getBoundPort(fakeServer({ address: '/tmp/some.sock', configPort: 8090 }))).toBe(8090)
40
+ })
41
+
42
+ // real listening server: proves we read the true bound port, not the stale config value
43
+ it('reads the real bound port from a live http server, not the config value', async () => {
44
+ const real = createServer()
45
+ await new Promise<void>((res) => real.listen(0, '127.0.0.1', () => res()))
46
+ try {
47
+ const boundPort = (real.address() as { port: number }).port
48
+ // config claims 8081, but the server is actually listening on boundPort
49
+ const server = {
50
+ httpServer: real,
51
+ config: { server: { port: 8081 } },
52
+ } as unknown as ViteDevServer
53
+ expect(getBoundPort(server)).toBe(boundPort)
54
+ expect(getBoundPort(server)).not.toBe(8081)
55
+ } finally {
56
+ await new Promise<void>((res) => real.close(() => res()))
57
+ }
58
+ })
59
+ })
@@ -0,0 +1,14 @@
1
+ import type { ViteDevServer } from 'vite'
2
+
3
+ // the port vite actually bound to. server.config.server.port can be undefined or stale
4
+ // and silently fall back to 8081, which makes the native bundle's serverUrl (and the
5
+ // simulator open target) point at the wrong port when the dev server lands elsewhere
6
+ // (e.g. 8081 taken -> 8082). once the http server is listening, address().port is the
7
+ // real bound port resolved by getServerOptionsFilled.
8
+ export function getBoundPort(server: ViteDevServer): number {
9
+ const addr = server.httpServer?.address()
10
+ if (addr && typeof addr === 'object' && typeof addr.port === 'number') {
11
+ return addr.port
12
+ }
13
+ return server.config.server.port ?? 8081
14
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"reactNativeDevServer.d.ts","sourceRoot":"","sources":["../../src/plugins/reactNativeDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,MAAM,EAAiB,MAAM,MAAM,CAAA;AAM1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAWnE,wBAAgB,gCAAgC,CAC9C,OAAO,CAAC,EAAE,OAAO,CACf,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,aAAa,GAAG,kBAAkB,GAAG,SAAS,CAAC,CACrF,GACA,MAAM,CAyMR"}
1
+ {"version":3,"file":"reactNativeDevServer.d.ts","sourceRoot":"","sources":["../../src/plugins/reactNativeDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,MAAM,EAAiB,MAAM,MAAM,CAAA;AAM1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAYnE,wBAAgB,gCAAgC,CAC9C,OAAO,CAAC,EAAE,OAAO,CACf,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,aAAa,GAAG,kBAAkB,GAAG,SAAS,CAAC,CACrF,GACA,MAAM,CAyMR"}
@@ -1 +1 @@
1
- {"version":3,"file":"buildBundle.d.ts","sourceRoot":"","sources":["../../../src/rn-commands/bundle/buildBundle.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,OAAO,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,wBAAwB,EAAE,OAAO,CAAA;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,wBAAwB,EAAE,MAAM,CAAA;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAC/B,CAAA;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EACpB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,iBAAiB,EACvB,UAAU,GAAE,GAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAmEf"}
1
+ {"version":3,"file":"buildBundle.d.ts","sourceRoot":"","sources":["../../../src/rn-commands/bundle/buildBundle.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,OAAO,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,OAAO,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,wBAAwB,EAAE,OAAO,CAAA;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,wBAAwB,EAAE,MAAM,CAAA;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,cAAc,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAC/B,CAAA;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EACpB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,iBAAiB,EACvB,UAAU,GAAE,GAAU,GACrB,OAAO,CAAC,IAAI,CAAC,CAsEf"}
@@ -1 +1 @@
1
- {"version":3,"file":"native-prelude.d.ts","sourceRoot":"","sources":["../../src/runtime/native-prelude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,GAAG,EAAE,OAAO,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,MAAM,CA4GT"}
1
+ {"version":3,"file":"native-prelude.d.ts","sourceRoot":"","sources":["../../src/runtime/native-prelude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,GAAG,EAAE,OAAO,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,MAAM,CA6GT"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/user-interface/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAGzC,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,aAAa,CAAA;CACtB,CAAA;AAwHD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,iBAOxD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/user-interface/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAIzC,KAAK,OAAO,GAAG;IACb,MAAM,EAAE,aAAa,CAAA;CACtB,CAAA;AAwHD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,iBAOxD"}
@@ -26,12 +26,47 @@ interface NativeDevEngineResult {
26
26
  }>;
27
27
  close: () => Promise<void>;
28
28
  }
29
+ export declare function getNativeTransformConfig(platform: 'ios' | 'android', dev: boolean, root: string): {
30
+ jsx: {
31
+ runtime: "classic";
32
+ };
33
+ define: any;
34
+ inject: {
35
+ React: string;
36
+ };
37
+ };
38
+ /**
39
+ * Wrap the dev bundle body in a function scope so module top-level
40
+ * `var`/`function` declarations don't leak onto the global object.
41
+ *
42
+ * rolldown's dev() emits the bundle as a *script*. A top-level `var` in a
43
+ * script creates a NON-configurable property on the global object. RN's
44
+ * `Libraries/Network/fetch.js` declares `var ... Headers, Request, ...`, so
45
+ * `global.Headers`/`global.Request` become non-configurable. RN's `setUpXHR`
46
+ * then calls `polyfillGlobal('Headers', ...)`, whose `polyfillObjectProperty`
47
+ * does `Object.defineProperty(global, 'Headers', { configurable: true, ... })`
48
+ * — which throws "Cannot redefine property" and RN converts to
49
+ * `console.error('Failed to set polyfill. Headers is not configurable.')`.
50
+ * In dev that console.error becomes a blocking LogBox redbox, so the app never
51
+ * mounts (every appium navigation then times out). The prod build is immune:
52
+ * its modules are wrapped in closures (no global leak) and it has no LogBox.
53
+ *
54
+ * Wrapping everything after the prelude in an IIFE makes those module vars
55
+ * function-scoped, matching prod, so `polyfillGlobal` succeeds. The prelude
56
+ * stays at script scope because it intentionally installs globals
57
+ * (`globalThis.global`/`__DEV__`/`process`/...). Intentional globals survive:
58
+ * the runtime is assigned via `globalThis.__rolldown_runtime__ = ...`, and HMR
59
+ * updates run through a *direct* `eval` inside this scope, so they still see
60
+ * the closure's `__esmMin`/`__toCommonJS`/module bindings.
61
+ */
62
+ export declare function wrapNativeBundleModuleScope(code: string): string;
29
63
  export declare function createNativeDevEngine(options: NativeDevEngineOptions): Promise<NativeDevEngineResult>;
30
64
  interface NativeBuildOptions {
31
65
  root: string;
32
66
  platform: 'ios' | 'android';
33
67
  dev?: boolean;
34
68
  serverUrl?: string;
69
+ entryFile?: string;
35
70
  assetsDest?: string;
36
71
  plugins?: Plugin[];
37
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createNativeDevEngine.d.ts","sourceRoot":"","sources":["../../src/utils/createNativeDevEngine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAA+B,MAAM,EAAkB,MAAM,UAAU,CAAA;AAQnF,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAChE;AAED,UAAU,qBAAqB;IAC7B,MAAM,EAAE,GAAG,CAAA;IACX,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAsRD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAgMhC;AAID,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4CzC"}
1
+ {"version":3,"file":"createNativeDevEngine.d.ts","sourceRoot":"","sources":["../../src/utils/createNativeDevEngine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAA+B,MAAM,EAAkB,MAAM,UAAU,CAAA;AAQnF,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAChE;AAED,UAAU,qBAAqB;IAC7B,MAAM,EAAE,GAAG,CAAA;IACX,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAuBD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,KAAK,GAAG,SAAS,EAC3B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM;;;;;;;;EAqHb;AAuFD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBhE;AAwDD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAqMhC;AAID,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgDzC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createNativeDevEngine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createNativeDevEngine.test.d.ts","sourceRoot":"","sources":["../../src/utils/createNativeDevEngine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { ViteDevServer } from 'vite';
2
+ export declare function getBoundPort(server: ViteDevServer): number;
3
+ //# sourceMappingURL=getBoundPort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBoundPort.d.ts","sourceRoot":"","sources":["../../src/utils/getBoundPort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAOzC,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAM1D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getBoundPort.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getBoundPort.test.d.ts","sourceRoot":"","sources":["../../src/utils/getBoundPort.test.ts"],"names":[],"mappings":""}