@vxrn/vite-plugin-metro 2.0.0-beta.168.1 → 2.0.0-beta.362.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 (31) hide show
  1. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.cjs +10 -2
  2. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.native.cjs +12 -2
  3. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.native.js +12 -2
  4. package/dist/cjs/metro-config/getMetroConfigFromViteConfig.native.js.map +1 -1
  5. package/dist/cjs/transformer/babel-transformer.cjs +2 -2
  6. package/dist/cjs/transformer/babel-transformer.native.cjs +2 -2
  7. package/dist/cjs/transformer/babel-transformer.native.js +2 -2
  8. package/dist/cjs/transformer/babel-transformer.native.js.map +1 -1
  9. package/dist/cjs/transformer/metroNativeWorker.cjs +2 -2
  10. package/dist/cjs/transformer/metroNativeWorker.native.cjs +2 -2
  11. package/dist/cjs/transformer/metroNativeWorker.native.js +2 -2
  12. package/dist/cjs/transformer/metroNativeWorker.native.js.map +1 -1
  13. package/dist/esm/metro-config/getMetroConfigFromViteConfig.mjs +10 -2
  14. package/dist/esm/metro-config/getMetroConfigFromViteConfig.mjs.map +1 -1
  15. package/dist/esm/metro-config/getMetroConfigFromViteConfig.native.js +12 -2
  16. package/dist/esm/metro-config/getMetroConfigFromViteConfig.native.js.map +1 -1
  17. package/dist/esm/transformer/babel-transformer.mjs +2 -2
  18. package/dist/esm/transformer/babel-transformer.mjs.map +1 -1
  19. package/dist/esm/transformer/babel-transformer.native.js +2 -2
  20. package/dist/esm/transformer/babel-transformer.native.js.map +1 -1
  21. package/dist/esm/transformer/metroNativeWorker.mjs +2 -2
  22. package/dist/esm/transformer/metroNativeWorker.mjs.map +1 -1
  23. package/dist/esm/transformer/metroNativeWorker.native.js +2 -2
  24. package/dist/esm/transformer/metroNativeWorker.native.js.map +1 -1
  25. package/package.json +5 -4
  26. package/src/metro-config/getMetroConfigFromViteConfig.ts +9 -2
  27. package/src/metro-config/glbAssets.test.ts +57 -0
  28. package/src/transformer/babel-transformer.ts +3 -3
  29. package/src/transformer/metroNativeWorker.ts +3 -3
  30. package/src/transformer/swiftPackageTransform.test.ts +67 -20
  31. package/types/metro-config/getMetroConfigFromViteConfig.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxrn/vite-plugin-metro",
3
- "version": "2.0.0-beta.168.1",
3
+ "version": "2.0.0-beta.362.1",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "main": "dist/cjs",
@@ -74,9 +74,9 @@
74
74
  "@oxc-project/runtime": "^0.112.0",
75
75
  "@react-native/babel-preset": "^0.87.1",
76
76
  "@react-native/metro-config": "^0.87.1",
77
- "@vxrn/compiler": "2.0.0-beta.168.1",
78
- "@vxrn/debug": "2.0.0-beta.168.1",
79
- "@vxrn/utils": "2.0.0-beta.168.1",
77
+ "@vxrn/compiler": "2.0.0-beta.362.1",
78
+ "@vxrn/debug": "2.0.0-beta.362.1",
79
+ "@vxrn/utils": "2.0.0-beta.362.1",
80
80
  "esbuild": "^0.25.12",
81
81
  "flow-parser": "^0.331.0",
82
82
  "launch-editor": "^2.10.0",
@@ -102,6 +102,7 @@
102
102
  "publishConfig": {
103
103
  "access": "public"
104
104
  },
105
+ "releaseSourceCommit": "6b489d521782af129132654d2baeb318f4bc2fdc",
105
106
  "repository": {
106
107
  "type": "git",
107
108
  "url": "git+https://github.com/onejs/one.git",
@@ -19,7 +19,7 @@ type MetroInputConfig = NonNullable<Parameters<typeof loadConfigT>[1]>
19
19
  const WATCHMAN_PROBE_TIMEOUT_MS = 2000
20
20
  const expoEnvAdditionalExts = ['env', 'local', 'development']
21
21
  // keep js before mjs so platform-aware .native.js wins for one dist.
22
- const metroSourceExts = ['js', 'jsx', 'json', 'ts', 'tsx', 'mjs', 'cjs', 'swift']
22
+ const metroSourceExts = ['js', 'jsx', 'json', 'ts', 'tsx', 'mjs', 'cjs', 'swift', 'kt']
23
23
  const watchmanResponsivePromises = new Map<string, Promise<boolean>>()
24
24
  let didWarnAboutWatchmanFallback = false
25
25
  const rootIndexBundleRequestPattern = /^(https?:\/\/[^/]+)?\/index\.bundle(?=$|[?#])/
@@ -67,10 +67,17 @@ function enforceWorkspaceVisibility(
67
67
  }
68
68
 
69
69
  function getReactNativeDefaultConfig(projectRoot: string): MetroInputConfig {
70
- return enforceWorkspaceVisibility(
70
+ const config = enforceWorkspaceVisibility(
71
71
  getDefaultConfig(projectRoot) as MetroInputConfig,
72
72
  projectRoot
73
73
  )
74
+ return {
75
+ ...config,
76
+ resolver: {
77
+ ...config.resolver,
78
+ assetExts: [...new Set([...(config.resolver?.assetExts ?? []), 'glb'])],
79
+ },
80
+ }
74
81
  }
75
82
 
76
83
  function getPlatformFromBundleUrl(url: string): 'ios' | 'android' {
@@ -0,0 +1,57 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
2
+ import { join } from 'node:path'
3
+ import { runInNewContext } from 'node:vm'
4
+ import type { ResolvedConfig } from 'vite'
5
+ import { expect, it } from 'vitest'
6
+ import { buildMetroConfigInputFromViteConfig } from './getMetroConfigFromViteConfig'
7
+ import { transform } from '../transformer/metroNativeWorker'
8
+
9
+ it('classifies a binary GLB with stock Metro config and registers its identity', async () => {
10
+ const root = await mkdtemp(join(import.meta.dirname, '.glb-metro-'))
11
+ const bytes = Buffer.from([0x67, 0x6c, 0x54, 0x46, 2, 0, 0, 0, 0xff, 0x80, 0, 1])
12
+ await writeFile(join(root, 'sofa.glb'), bytes)
13
+ try {
14
+ const { defaultConfig } = await buildMetroConfigInputFromViteConfig(
15
+ { root } as ResolvedConfig,
16
+ { watchman: false }
17
+ )
18
+ const type = defaultConfig.resolver.assetExts.includes('glb') ? 'asset' : 'module'
19
+ const result = await transform(
20
+ { assetRegistryPath: 'react-native/asset-registry', publicPath: '/assets' },
21
+ root,
22
+ 'sofa.glb',
23
+ bytes,
24
+ { dev: true, platform: 'ios', type }
25
+ )
26
+ expect(result.output[0].type).toBe('js/module/asset')
27
+ let descriptor: any
28
+ runInNewContext(result.output[0].data.code, {
29
+ __d: (factory: Function) =>
30
+ factory(
31
+ {},
32
+ () => ({
33
+ registerAsset: (asset: any) => {
34
+ descriptor = asset
35
+ },
36
+ }),
37
+ {},
38
+ {},
39
+ { exports: {} },
40
+ {},
41
+ [0]
42
+ ),
43
+ })
44
+ expect(descriptor).toMatchObject({
45
+ name: 'sofa',
46
+ type: 'glb',
47
+ scales: [1],
48
+ httpServerLocation: '/assets',
49
+ })
50
+ expect(descriptor.hash).not.toBe('')
51
+ expect(descriptor.width).toBeUndefined()
52
+ expect(descriptor.height).toBeUndefined()
53
+ expect(await readFile(join(root, 'sofa.glb'))).toEqual(bytes)
54
+ } finally {
55
+ await rm(root, { recursive: true, force: true })
56
+ }
57
+ })
@@ -159,20 +159,20 @@ const transform: BabelTransformer['transform'] = ({
159
159
  // `plugins` is used for `functionMapBabelPlugin` from `metro-source-map`.
160
160
  plugins,
161
161
  }: BabelTransformerArgs): ReturnType<BabelTransformer['transform']> => {
162
- if (filename.endsWith('.swift')) {
162
+ if (/\.(swift|kt)$/.test(filename)) {
163
163
  const requireFromProject = createRequire(
164
164
  path.resolve(options.projectRoot, 'package.json')
165
165
  )
166
166
  const oneTransforms = requireFromProject(
167
167
  'one/native-transforms'
168
168
  ) as typeof import('one/native-transforms') & {
169
- renderSwiftPackageModule: (
169
+ renderNativeSourceModule: (
170
170
  id: string,
171
171
  platform: string,
172
172
  root: string
173
173
  ) => { code: string; watchFiles: string[] }
174
174
  }
175
- originalSrc = oneTransforms.renderSwiftPackageModule(
175
+ originalSrc = oneTransforms.renderNativeSourceModule(
176
176
  path.isAbsolute(filename) ? filename : path.resolve(options.projectRoot, filename),
177
177
  options.platform ?? '',
178
178
  options.projectRoot
@@ -1845,7 +1845,7 @@ let workletsConfigured = false
1845
1845
  * process when the project actually depends on reanimated.
1846
1846
  */
1847
1847
  type OneNativeTransforms = typeof import('one/native-transforms') & {
1848
- renderSwiftPackageModule: (
1848
+ renderNativeSourceModule: (
1849
1849
  id: string,
1850
1850
  platform: string,
1851
1851
  root: string
@@ -1903,11 +1903,11 @@ export async function transform(
1903
1903
  assertNoUnportedBabelPlugins(options)
1904
1904
 
1905
1905
  let sourceCode = typeof data === 'string' ? data : data.toString('utf8')
1906
- if (filename.endsWith('.swift')) {
1906
+ if (/\.(swift|kt)$/.test(filename)) {
1907
1907
  const oneTransforms = loadOneNativeTransforms(projectRoot)
1908
1908
  if (!oneTransforms)
1909
1909
  throw new Error(`[vxrn/metro] ${filename} requires One native transforms`)
1910
- sourceCode = oneTransforms.renderSwiftPackageModule(
1910
+ sourceCode = oneTransforms.renderNativeSourceModule(
1911
1911
  path.isAbsolute(filename) ? filename : path.resolve(projectRoot, filename),
1912
1912
  options.platform ?? '',
1913
1913
  projectRoot
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs'
2
2
  import { resolve } from 'node:path'
3
- import { describe, expect, it } from 'vitest'
3
+ import { beforeAll, describe, expect, it } from 'vitest'
4
4
  // @ts-expect-error: module.exports supplies the transformer at runtime.
5
5
  import babelTransformer from './babel-transformer'
6
6
  import { transform as transformNative } from './metroNativeWorker'
@@ -8,6 +8,40 @@ import { transform as transformNative } from './metroNativeWorker'
8
8
  const projectRoot = resolve(__dirname, '../../../../tests/native-features')
9
9
  const filename = resolve(projectRoot, 'native-source/Audio.swift')
10
10
 
11
+ function babelTransform(fixture: string, src: string, platform: string) {
12
+ return babelTransformer.transform({
13
+ filename: fixture,
14
+ src,
15
+ options: {
16
+ projectRoot,
17
+ dev: true,
18
+ platform,
19
+ customTransformOptions: {
20
+ environment: 'client',
21
+ vite: {
22
+ oneViteMetroBabelConfig: true,
23
+ babelConfig: { babelrc: false, configFile: false, presets: [], plugins: [] },
24
+ },
25
+ },
26
+ },
27
+ plugins: [],
28
+ })
29
+ }
30
+
31
+ beforeAll(async () => {
32
+ // cold-start the one-time transformer init (babel preset, native pipeline)
33
+ // in setup: under CI load it exceeds the per-test budget, while the timed
34
+ // assertions below only exercise warm transforms
35
+ const source = readFileSync(filename)
36
+ await transformNative({}, projectRoot, filename, source, {
37
+ dev: true,
38
+ minify: false,
39
+ platform: 'ios',
40
+ type: 'module',
41
+ })
42
+ babelTransform(filename, source.toString('utf8'), 'ios')
43
+ })
44
+
11
45
  describe('metro swift source import', () => {
12
46
  it('transforms the fixture through both Metro transformer implementations', async () => {
13
47
  const source = readFileSync(filename)
@@ -20,29 +54,42 @@ describe('metro swift source import', () => {
20
54
  expect(native.output[0].data.code).toContain('AudioMath')
21
55
  expect(native.output[0].data.code).toContain('callNativeSource')
22
56
 
23
- const babel = babelTransformer.transform({
24
- filename,
25
- src: source.toString('utf8'),
26
- options: {
27
- projectRoot,
28
- dev: true,
29
- platform: 'ios',
30
- customTransformOptions: {
31
- environment: 'client',
32
- vite: {
33
- oneViteMetroBabelConfig: true,
34
- babelConfig: { babelrc: false, configFile: false, presets: [], plugins: [] },
35
- },
36
- },
37
- },
38
- plugins: [],
39
- })
57
+ const babel = babelTransform(filename, source.toString('utf8'), 'ios')
40
58
  expect(JSON.stringify(babel.ast)).toContain('AudioMath')
41
59
  expect(JSON.stringify(babel.ast)).toContain('callNativeSource')
42
- await expect(transformNative({}, projectRoot, filename, source, {
60
+ await expect(
61
+ transformNative({}, projectRoot, filename, source, {
62
+ dev: true,
63
+ platform: 'android',
64
+ type: 'module',
65
+ })
66
+ ).rejects.toThrow('Android build')
67
+ })
68
+ })
69
+
70
+ describe('metro kotlin source import', () => {
71
+ const kotlin = resolve(projectRoot, 'native-source/Audio.kt')
72
+
73
+ it('transforms the fixture through both Metro transformer implementations', async () => {
74
+ const source = readFileSync(kotlin)
75
+ const native = await transformNative({}, projectRoot, kotlin, source, {
43
76
  dev: true,
77
+ minify: false,
44
78
  platform: 'android',
45
79
  type: 'module',
46
- })).rejects.toThrow('Android build')
80
+ })
81
+ expect(native.output[0].data.code).toContain('AudioMath')
82
+ expect(native.output[0].data.code).toContain('callNativeSource')
83
+
84
+ const babel = babelTransform(kotlin, source.toString('utf8'), 'android')
85
+ expect(JSON.stringify(babel.ast)).toContain('AudioMath')
86
+ expect(JSON.stringify(babel.ast)).toContain('callNativeSource')
87
+ await expect(
88
+ transformNative({}, projectRoot, kotlin, source, {
89
+ dev: true,
90
+ platform: 'ios',
91
+ type: 'module',
92
+ })
93
+ ).rejects.toThrow('iOS build')
47
94
  })
48
95
  })
@@ -1 +1 @@
1
- {"version":3,"file":"getMetroConfigFromViteConfig.d.ts","sourceRoot":"","sources":["../../src/metro-config/getMetroConfigFromViteConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,MAAM,CAAA;AAalE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAiO/D;;;;;;;GAOG;AACH,wBAAsB,mCAAmC,CACvD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC;IAAE,aAAa,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC,CAuIhF;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC,mBAAmB,CAAC,CA6J9B"}
1
+ {"version":3,"file":"getMetroConfigFromViteConfig.d.ts","sourceRoot":"","sources":["../../src/metro-config/getMetroConfigFromViteConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,MAAM,CAAA;AAalE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAwO/D;;;;;;;GAOG;AACH,wBAAsB,mCAAmC,CACvD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC;IAAE,aAAa,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC,CAuIhF;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,cAAc,EACtB,kBAAkB,EAAE,kBAAkB,GACrC,OAAO,CAAC,mBAAmB,CAAC,CA6J9B"}