vxrn 0.1.45 → 0.1.47

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 (84) hide show
  1. package/dist/cjs/cli.js +7 -2
  2. package/dist/cjs/cli.js.map +1 -1
  3. package/dist/cjs/cli.native.js +7 -2
  4. package/dist/cjs/cli.native.js.map +2 -2
  5. package/dist/cjs/constants.js +5 -4
  6. package/dist/cjs/constants.js.map +1 -1
  7. package/dist/cjs/constants.native.js +8 -5
  8. package/dist/cjs/constants.native.js.map +1 -1
  9. package/dist/cjs/exports/build.js +21 -40
  10. package/dist/cjs/exports/build.js.map +1 -1
  11. package/dist/cjs/exports/build.native.js +44 -98
  12. package/dist/cjs/exports/build.native.js.map +2 -2
  13. package/dist/cjs/exports/dev.js +18 -7
  14. package/dist/cjs/exports/dev.js.map +1 -1
  15. package/dist/cjs/exports/dev.native.js +19 -23
  16. package/dist/cjs/exports/dev.native.js.map +2 -2
  17. package/dist/cjs/utils/getHtml.js +14 -5
  18. package/dist/cjs/utils/getHtml.js.map +1 -1
  19. package/dist/cjs/utils/getHtml.native.js +13 -4
  20. package/dist/cjs/utils/getHtml.native.js.map +2 -2
  21. package/dist/cjs/utils/getOptionsFilled.js +1 -1
  22. package/dist/cjs/utils/getOptionsFilled.js.map +1 -1
  23. package/dist/cjs/utils/getOptionsFilled.native.js +1 -1
  24. package/dist/cjs/utils/getOptionsFilled.native.js.map +1 -1
  25. package/dist/cjs/utils/getVitePath.js +3 -1
  26. package/dist/cjs/utils/getVitePath.js.map +1 -1
  27. package/dist/cjs/utils/getVitePath.native.js +1 -1
  28. package/dist/cjs/utils/getVitePath.native.js.map +1 -1
  29. package/dist/cjs/utils/readVXRNConfig.js +15 -4
  30. package/dist/cjs/utils/readVXRNConfig.js.map +1 -1
  31. package/dist/cjs/utils/readVXRNConfig.native.js +44 -9
  32. package/dist/cjs/utils/readVXRNConfig.native.js.map +2 -2
  33. package/dist/esm/cli.js +7 -2
  34. package/dist/esm/cli.js.map +1 -1
  35. package/dist/esm/cli.mjs +7 -2
  36. package/dist/esm/cli.native.js +7 -2
  37. package/dist/esm/cli.native.js.map +2 -2
  38. package/dist/esm/constants.js +5 -4
  39. package/dist/esm/constants.js.map +1 -1
  40. package/dist/esm/constants.mjs +3 -3
  41. package/dist/esm/constants.native.js +8 -5
  42. package/dist/esm/constants.native.js.map +1 -1
  43. package/dist/esm/exports/build.js +22 -41
  44. package/dist/esm/exports/build.js.map +1 -1
  45. package/dist/esm/exports/build.mjs +29 -39
  46. package/dist/esm/exports/build.native.js +45 -99
  47. package/dist/esm/exports/build.native.js.map +2 -2
  48. package/dist/esm/exports/dev.js +18 -7
  49. package/dist/esm/exports/dev.js.map +1 -1
  50. package/dist/esm/exports/dev.mjs +13 -11
  51. package/dist/esm/exports/dev.native.js +19 -23
  52. package/dist/esm/exports/dev.native.js.map +2 -2
  53. package/dist/esm/utils/getHtml.js +14 -5
  54. package/dist/esm/utils/getHtml.js.map +1 -1
  55. package/dist/esm/utils/getHtml.mjs +14 -5
  56. package/dist/esm/utils/getHtml.native.js +13 -4
  57. package/dist/esm/utils/getHtml.native.js.map +2 -2
  58. package/dist/esm/utils/getOptionsFilled.js +1 -1
  59. package/dist/esm/utils/getOptionsFilled.js.map +1 -1
  60. package/dist/esm/utils/getOptionsFilled.mjs +1 -1
  61. package/dist/esm/utils/getOptionsFilled.native.js +1 -1
  62. package/dist/esm/utils/getOptionsFilled.native.js.map +1 -1
  63. package/dist/esm/utils/getVitePath.js +3 -1
  64. package/dist/esm/utils/getVitePath.js.map +1 -1
  65. package/dist/esm/utils/getVitePath.mjs +1 -1
  66. package/dist/esm/utils/getVitePath.native.js +1 -1
  67. package/dist/esm/utils/getVitePath.native.js.map +1 -1
  68. package/dist/esm/utils/readVXRNConfig.js +15 -4
  69. package/dist/esm/utils/readVXRNConfig.js.map +1 -1
  70. package/dist/esm/utils/readVXRNConfig.mjs +15 -4
  71. package/dist/esm/utils/readVXRNConfig.native.js +44 -9
  72. package/dist/esm/utils/readVXRNConfig.native.js.map +2 -2
  73. package/package.json +8 -9
  74. package/src/cli.ts +7 -2
  75. package/src/constants.ts +5 -4
  76. package/src/exports/build.ts +36 -54
  77. package/src/exports/dev.ts +21 -18
  78. package/src/utils/getHtml.ts +28 -5
  79. package/src/utils/getOptionsFilled.ts +1 -1
  80. package/src/utils/getVitePath.ts +3 -1
  81. package/src/utils/readVXRNConfig.ts +25 -11
  82. package/types/constants.d.ts +1 -1
  83. package/types/exports/build.d.ts +3 -1
  84. package/types/utils/getHtml.d.ts +3 -2
package/src/constants.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { SSROptions, UserConfig } from 'vite'
1
+ import type { UserConfig } from 'vite'
2
2
 
3
3
  export const DEFAULT_PORT = 8081
4
4
 
@@ -46,17 +46,18 @@ const needsInterop = [
46
46
  'react-is',
47
47
  'fast-deep-equal',
48
48
  '@react-navigation/native',
49
- 'tamagui/linear-gradient',
50
49
  'react-native-svg',
51
50
  '@supabase/auth-helpers-react',
52
51
  'parse-numeric-range',
53
52
  'use-sync-external-store',
54
53
  'use-sync-external-store/shim',
55
- 'swr',
56
54
  ]
57
55
 
58
56
  export const depsToOptimize = [
59
57
  ...needsInterop,
58
+ 'swr',
59
+ 'tamagui/linear-gradient',
60
+ '@tamagui/linear-gradient',
60
61
  '@react-native/normalize-color',
61
62
  '@vxrn/router',
62
63
  'expo-modules-core',
@@ -93,8 +94,8 @@ export const depsToOptimize = [
93
94
 
94
95
  export const optimizeDeps = {
95
96
  include: depsToOptimize,
97
+ exclude: ['util', '@swc/wasm', '@swc/core-darwin-arm64'],
96
98
  needsInterop,
97
- exclude: ['util'],
98
99
  esbuildOptions: {
99
100
  resolveExtensions: webExtensions,
100
101
  },
@@ -2,16 +2,16 @@ import { build as esbuild } from 'esbuild'
2
2
  import { resolve as importMetaResolve } from 'import-meta-resolve'
3
3
  import fs from 'node:fs'
4
4
  import { tmpdir } from 'node:os'
5
- import path, { dirname, resolve } from 'node:path'
5
+ import path from 'node:path'
6
6
  import { mergeConfig, build as viteBuild, type UserConfig } from 'vite'
7
7
 
8
8
  import FSExtra from 'fs-extra'
9
9
  import type { OutputAsset, OutputChunk, RollupOutput } from 'rollup'
10
+ import { optimizeDeps } from '../constants'
10
11
  import type { VXRNConfig } from '../types'
11
12
  import { getBaseViteConfig } from '../utils/getBaseViteConfig'
12
13
  import { getHtml } from '../utils/getHtml'
13
14
  import { getOptionsFilled, type VXRNConfigFilled } from '../utils/getOptionsFilled'
14
- import { optimizeDeps } from '../constants'
15
15
 
16
16
  export const resolveFile = (path: string) => {
17
17
  try {
@@ -25,7 +25,12 @@ const { ensureDir, existsSync, readFile, pathExists } = FSExtra
25
25
 
26
26
  // web only for now
27
27
 
28
- export const build = async (optionsIn: VXRNConfig) => {
28
+ // TODO:
29
+ // - make this only build native or web bundles
30
+ // - move router stuff into router package
31
+ // - generateStaticPages becomes a vite 'post' postbuild callback in router plugin
32
+
33
+ export const build = async (optionsIn: VXRNConfig, { step }: { step?: string } = {}) => {
29
34
  const options = await getOptionsFilled(optionsIn)
30
35
 
31
36
  // TODO?
@@ -46,56 +51,31 @@ export const build = async (optionsIn: VXRNConfig) => {
46
51
  webBuildConfig = mergeConfig(webBuildConfig, options.webConfig) as any
47
52
  }
48
53
 
49
- console.info(`build client`)
50
- await viteBuild(
51
- mergeConfig(webBuildConfig, {
52
- build: {
53
- ssrManifest: true,
54
- outDir: 'dist/client',
55
- },
56
- } satisfies UserConfig)
57
- )
54
+ if (step !== 'generate') {
55
+ console.info(`build client`)
56
+ await viteBuild(
57
+ mergeConfig(webBuildConfig, {
58
+ build: {
59
+ ssrManifest: true,
60
+ outDir: 'dist/client',
61
+ },
62
+ } satisfies UserConfig)
63
+ )
64
+ }
58
65
 
59
66
  console.info(`build server`)
60
67
  const { output } = (await viteBuild(
61
68
  mergeConfig(webBuildConfig, {
62
- plugins: [
63
- {
64
- name: 'test',
65
- enforce: 'pre',
66
- async resolveId(id, importer = '') {
67
- if (id[0] === '.') {
68
- const absolutePath = resolve(dirname(importer), id)
69
- const webPath = absolutePath.replace(/(.m?js)/, '') + '.web.js'
70
- if (webPath === id) return
71
- try {
72
- const directoryPath = absolutePath + '/index.web.js'
73
- if (await pathExists(directoryPath)) {
74
- console.info(`temp fix found ${directoryPath}`)
75
- return directoryPath
76
- }
77
- if (await pathExists(webPath)) {
78
- console.info(`temp fix found ${webPath}`)
79
- return webPath
80
- }
81
- } catch (err) {
82
- console.warn(`error probably fine`, err)
83
- }
84
- }
85
- },
86
- },
87
- ],
69
+ // optimizeDeps: {
70
+ // esbuildOptions: {
71
+ // format: 'cjs',
72
+ // },
73
+ // },
88
74
 
89
- optimizeDeps: {
90
- esbuildOptions: {
91
- format: 'cjs',
92
- },
93
- },
94
-
95
- ssr: {
96
- noExternal: true,
97
- optimizeDeps,
98
- },
75
+ // ssr: {
76
+ // noExternal: true,
77
+ // optimizeDeps,
78
+ // },
99
79
 
100
80
  build: {
101
81
  // we want one big file of css
@@ -159,9 +139,8 @@ async function generateStaticPages(
159
139
  return await Promise.all(
160
140
  paramsList.map(async (params) => {
161
141
  const path = getUrl(params)
162
- const props =
163
- (await exported.generateStaticProps?.({ path: getUrl(params), params })) ?? {}
164
- return { path, props }
142
+ const loaderData = (await exported.loader?.({ path, params })) ?? {}
143
+ return { path, params, loaderData }
165
144
  })
166
145
  )
167
146
 
@@ -207,8 +186,10 @@ async function generateStaticPages(
207
186
  const cssString = await FSExtra.readFile(tmpCssFile, 'utf-8')
208
187
 
209
188
  // pre-render each route...
210
- for (const { path, props } of allRoutes) {
211
- const { appHtml, headHtml } = await render({ path, props })
189
+ for (const { path, loaderData, params } of allRoutes) {
190
+ const loaderProps = { params }
191
+ globalThis['__vxrnLoaderProps__'] = loaderProps
192
+ const { appHtml, headHtml } = await render({ path })
212
193
  const slashFileName = `${path === '/' ? '/index' : path}.html`
213
194
  const clientHtmlPath = toAbsolute(`dist/client${slashFileName}`)
214
195
  const clientHtml = existsSync(clientHtmlPath) ? await readFile(clientHtmlPath, 'utf-8') : null
@@ -216,7 +197,8 @@ async function generateStaticPages(
216
197
  template: clientHtml || template,
217
198
  appHtml,
218
199
  headHtml,
219
- props,
200
+ loaderData,
201
+ loaderProps,
220
202
  css: cssString,
221
203
  })
222
204
  const filePath = toAbsolute(`dist/static${slashFileName}`)
@@ -47,6 +47,8 @@ import { checkPatches } from '../utils/patches'
47
47
  let isBuildingNativeBundle: Promise<string> | null = null
48
48
  const hotUpdateCache = new Map<string, string>()
49
49
 
50
+ let connectedNativeClients = 0
51
+
50
52
  export const resolveFile = (path: string) => {
51
53
  try {
52
54
  return importMetaResolve(path, import.meta.url).replace('file://', '')
@@ -217,6 +219,7 @@ export const dev = async ({ clean, ...rest }: VXRNConfig & { clean?: boolean })
217
219
  websocket: {
218
220
  open(peer) {
219
221
  console.debug('[hmr] open', peer)
222
+ connectedNativeClients++
220
223
  },
221
224
 
222
225
  message(peer, message) {
@@ -228,6 +231,7 @@ export const dev = async ({ clean, ...rest }: VXRNConfig & { clean?: boolean })
228
231
 
229
232
  close(peer, event) {
230
233
  console.info('[hmr] close', peer, event)
234
+ connectedNativeClients--
231
235
  },
232
236
 
233
237
  error(peer, error) {
@@ -765,23 +769,8 @@ function isWithin(outer: string, inner: string) {
765
769
  // used for normalizing hot reloads
766
770
  let entryRoot = ''
767
771
 
768
- // function watchNodeModules(modules: string[]): PluginOption {
769
- // return {
770
- // name: 'watch-node-modules',
771
- // config() {
772
- // return {
773
- // server: {
774
- // watch: {
775
- // ignored: modules.map((m) => `!**/packages/${m}/**`),
776
- // },
777
- // },
778
- // }
779
- // },
780
- // }
781
- // }
782
-
783
772
  async function getViteServerConfig(config: VXRNConfigFilled) {
784
- const { root, host, webConfig, cacheDir } = config
773
+ const { root, host, webConfig } = config
785
774
 
786
775
  let serverConfig: UserConfig = mergeConfig(
787
776
  getBaseViteConfig({
@@ -792,7 +781,6 @@ async function getViteServerConfig(config: VXRNConfigFilled) {
792
781
  clearScreen: false,
793
782
  plugins: [
794
783
  reactNativeHMRPlugin(config),
795
- // watchNodeModules(['@tamagui/popper'])
796
784
 
797
785
  {
798
786
  name: 'process-env-ssr',
@@ -805,10 +793,22 @@ async function getViteServerConfig(config: VXRNConfigFilled) {
805
793
  },
806
794
  ],
807
795
  optimizeDeps,
796
+
808
797
  ssr: {
809
- noExternal: true,
798
+ // noExternal true causes many incompat issues because we need things on disk to work
799
+ // eg generally node uses .cjs extensions to "switch" back to cjs mode on import, but once bundled
800
+ // this wont happen, breaking many things
801
+ // but we need react related things always so they dont duplicate
802
+ noExternal: [
803
+ ...optimizeDeps.include,
804
+ 'react',
805
+ 'react-dom',
806
+ 'react-dom/server',
807
+ 'react-dom/client',
808
+ ],
810
809
  optimizeDeps,
811
810
  },
811
+
812
812
  server: {
813
813
  hmr: {
814
814
  path: '/__vxrnhmr',
@@ -850,6 +850,9 @@ function reactNativeHMRPlugin({ root }: VXRNConfigFilled) {
850
850
  if (!isWithin(root, file)) {
851
851
  return
852
852
  }
853
+ if (!connectedNativeClients) {
854
+ return
855
+ }
853
856
 
854
857
  const [module] = modules
855
858
  if (!module) return
@@ -1,12 +1,35 @@
1
+ // TODO merge with the other one
1
2
  export function getHtml({
2
3
  template,
3
- props,
4
+ loaderData,
5
+ loaderProps,
4
6
  appHtml,
5
7
  headHtml,
6
8
  css,
7
- }: { css?: string; template: string; props: Object; appHtml: string; headHtml: string }) {
8
- const propsHtml = `\n<script>globalThis['__vxrnProps']=${JSON.stringify(props)}</script>`
9
+ }: {
10
+ css?: string
11
+ template: string
12
+ loaderData: Object
13
+ loaderProps?: any
14
+ appHtml: string
15
+ headHtml: string
16
+ }) {
17
+ if (!template.includes(`<!--ssr-outlet-->`)) {
18
+ throw new Error(`No <!--ssr-outlet--> found in html to inject SSR contents`)
19
+ }
20
+ if (!template.includes(`<!--head-outlet-->`)) {
21
+ throw new Error(`No <!--head-outlet--> found in html to inject SSR contents`)
22
+ }
23
+
24
+ const loaderDataJS = `globalThis['__vxrnLoaderData__']=${JSON.stringify(loaderData)}`
25
+ const loaderPropsJS = `globalThis['__vxrnLoaderProps__']=${JSON.stringify(loaderProps || null)}`
26
+ const loaderDataString = `\n<script>
27
+ ${loaderDataJS};
28
+ ${loaderPropsJS};
29
+ </script>`
30
+
9
31
  return template
10
- .replace(`<!--ssr-outlet-->`, appHtml + propsHtml)
11
- .replace(`<!--head-outlet-->`, `${headHtml}\n${css ? `<style>${css}</style>` : ``}`)
32
+ .replace(/\s*<!--ssr-outlet-->\s*/, appHtml)
33
+ .replace(`<!--head-outlet-->`, `${headHtml}\n${css ? `<style>${css}</style>\n` : ``}`)
34
+ .replace('</body>', loaderDataString)
12
35
  }
@@ -20,7 +20,7 @@ export async function getOptionsFilled(options: VXRNConfig) {
20
20
 
21
21
  const packageRootDir = join(require.resolve('vxrn'), '../../..')
22
22
 
23
- const cacheDir = join(root, 'node_modules', '.cache', 'vxrn')
23
+ const cacheDir = join(root, 'node_modules', '.vxrn')
24
24
  const internalPatchesDir = join(packageRootDir, 'patches')
25
25
  const userPatchesDir = join(root, 'patches')
26
26
  const [state, packageJSON] = await Promise.all([
@@ -34,7 +34,9 @@ export async function getVitePath(
34
34
  const resolved = resolve(sourceFile)(moduleName)
35
35
  // figure out symlinks
36
36
  if (!resolved) {
37
- throw new Error(`❌ cant find`)
37
+ throw new Error(
38
+ ` ❌ Path not found ${sourceFile} (rootPath ${rootPath}, importer ${importer}, moduleName ${moduleName})`
39
+ )
38
40
  }
39
41
  const real = await FSExtra.realpath(resolved)
40
42
  let id = real
@@ -8,6 +8,14 @@ export async function readVXRNConfig(): Promise<VXRNConfig> {
8
8
  return {}
9
9
  }
10
10
 
11
+ if (process.env.VXRN_CJS) {
12
+ const requireFile = jiti(process.cwd(), {
13
+ esmResolve: true,
14
+ })
15
+ const userConfig = requireFile('./vxrn.config.ts')
16
+ return resolveOptionalAsyncFunction(userConfig?.default ?? {})
17
+ }
18
+
11
19
  // try esm load
12
20
  try {
13
21
  // somewhat hacky creating a server just to read config?
@@ -21,17 +29,23 @@ export async function readVXRNConfig(): Promise<VXRNConfig> {
21
29
  })
22
30
 
23
31
  await vite.close()
24
- return userConfig?.default ?? {}
25
- } catch (err) {
26
- console.info(`Error loading config via ESM, attempting CJS, DEBUG=1 to see logs`)
27
- if (process.env.DEBUG) {
28
- console.info(err)
29
- }
32
+ return resolveOptionalAsyncFunction(userConfig?.default ?? {})
33
+ } catch (err: any) {
34
+ console.info(` [vxrn] Error loading config via ESM:
30
35
 
31
- const requireFile = jiti(process.cwd(), {
32
- esmResolve: true,
33
- })
34
- const userConfig = requireFile('./vxrn.config.ts')
35
- return userConfig?.default ?? {}
36
+ ${err.stack}
37
+
38
+ To load as CommonJS, set VXRN_CJS=1`)
39
+ throw err
40
+ }
41
+ }
42
+
43
+ async function resolveOptionalAsyncFunction(value: any) {
44
+ if (typeof value === 'function') {
45
+ value = value()
46
+ }
47
+ if (value instanceof Promise) {
48
+ value = await value
36
49
  }
50
+ return value
37
51
  }
@@ -4,8 +4,8 @@ export declare const webExtensions: string[];
4
4
  export declare const depsToOptimize: string[];
5
5
  export declare const optimizeDeps: {
6
6
  include: string[];
7
- needsInterop: string[];
8
7
  exclude: string[];
8
+ needsInterop: string[];
9
9
  esbuildOptions: {
10
10
  resolveExtensions: string[];
11
11
  };
@@ -1,4 +1,6 @@
1
1
  import type { VXRNConfig } from '../types';
2
2
  export declare const resolveFile: (path: string) => string;
3
- export declare const build: (optionsIn: VXRNConfig) => Promise<void>;
3
+ export declare const build: (optionsIn: VXRNConfig, { step }?: {
4
+ step?: string;
5
+ }) => Promise<void>;
4
6
  //# sourceMappingURL=build.d.ts.map
@@ -1,7 +1,8 @@
1
- export declare function getHtml({ template, props, appHtml, headHtml, css, }: {
1
+ export declare function getHtml({ template, loaderData, loaderProps, appHtml, headHtml, css, }: {
2
2
  css?: string;
3
3
  template: string;
4
- props: Object;
4
+ loaderData: Object;
5
+ loaderProps?: any;
5
6
  appHtml: string;
6
7
  headHtml: string;
7
8
  }): string;