one 1.1.345 → 1.1.347

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 (189) hide show
  1. package/dist/cjs/cli.cjs +5 -1
  2. package/dist/cjs/cli.js +5 -1
  3. package/dist/cjs/cli.js.map +1 -1
  4. package/dist/cjs/cli.native.js +5 -1
  5. package/dist/cjs/cli.native.js.map +2 -2
  6. package/dist/cjs/config.cjs +6 -6
  7. package/dist/cjs/config.js +3 -3
  8. package/dist/cjs/config.js.map +1 -1
  9. package/dist/cjs/config.native.js +3 -3
  10. package/dist/cjs/config.native.js.map +2 -2
  11. package/dist/cjs/createApp.cjs +2 -1
  12. package/dist/cjs/createApp.js +1 -1
  13. package/dist/cjs/createApp.js.map +1 -1
  14. package/dist/cjs/createApp.native.js +1 -1
  15. package/dist/cjs/createApp.native.js.map +1 -1
  16. package/dist/cjs/index.cjs +1 -2
  17. package/dist/cjs/index.js +1 -1
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/index.native.js +1 -1
  20. package/dist/cjs/index.native.js.map +1 -1
  21. package/dist/cjs/serve-worker.cjs +34 -0
  22. package/dist/cjs/serve-worker.js +26 -0
  23. package/dist/cjs/serve-worker.js.map +6 -0
  24. package/dist/cjs/serve-worker.native.js +31 -0
  25. package/dist/cjs/serve-worker.native.js.map +6 -0
  26. package/dist/cjs/serve.cjs +17 -142
  27. package/dist/cjs/serve.js +9 -139
  28. package/dist/cjs/serve.js.map +2 -2
  29. package/dist/cjs/serve.native.js +8 -148
  30. package/dist/cjs/serve.native.js.map +2 -2
  31. package/dist/cjs/server/oneServe.cjs +173 -0
  32. package/dist/cjs/server/oneServe.js +160 -0
  33. package/dist/cjs/server/oneServe.js.map +6 -0
  34. package/dist/cjs/server/oneServe.native.js +174 -0
  35. package/dist/cjs/server/oneServe.native.js.map +6 -0
  36. package/dist/cjs/server/setupBuildOptions.cjs +28 -0
  37. package/dist/cjs/server/setupBuildOptions.js +23 -0
  38. package/dist/cjs/server/setupBuildOptions.js.map +6 -0
  39. package/dist/cjs/server/setupBuildOptions.native.js +29 -0
  40. package/dist/cjs/server/setupBuildOptions.native.js.map +6 -0
  41. package/dist/cjs/setup.js.map +1 -1
  42. package/dist/cjs/utils/ensureExists.cjs +28 -0
  43. package/dist/cjs/utils/ensureExists.js +24 -0
  44. package/dist/cjs/utils/ensureExists.js.map +6 -0
  45. package/dist/cjs/utils/ensureExists.native.js +29 -0
  46. package/dist/cjs/utils/ensureExists.native.js.map +6 -0
  47. package/dist/cjs/vite/build.cjs +38 -18
  48. package/dist/cjs/vite/build.js +38 -14
  49. package/dist/cjs/vite/build.js.map +1 -1
  50. package/dist/cjs/vite/build.native.js +29 -15
  51. package/dist/cjs/vite/build.native.js.map +2 -2
  52. package/dist/cjs/vite/one.cjs +27 -10
  53. package/dist/cjs/vite/one.js +23 -3
  54. package/dist/cjs/vite/one.js.map +1 -1
  55. package/dist/cjs/vite/one.native.js +23 -5
  56. package/dist/cjs/vite/one.native.js.map +2 -2
  57. package/dist/cjs/vite/plugins/reactCompilerPlugin.cjs +101 -0
  58. package/dist/cjs/vite/plugins/reactCompilerPlugin.js +82 -0
  59. package/dist/cjs/vite/plugins/reactCompilerPlugin.js.map +6 -0
  60. package/dist/cjs/vite/plugins/reactCompilerPlugin.native.js +67 -0
  61. package/dist/cjs/vite/plugins/reactCompilerPlugin.native.js.map +6 -0
  62. package/dist/esm/cli.js +5 -1
  63. package/dist/esm/cli.js.map +1 -1
  64. package/dist/esm/cli.mjs +5 -1
  65. package/dist/esm/cli.mjs.map +1 -1
  66. package/dist/esm/cli.native.js +5 -1
  67. package/dist/esm/cli.native.js.map +2 -2
  68. package/dist/esm/config.js +3 -3
  69. package/dist/esm/config.js.map +1 -1
  70. package/dist/esm/config.mjs +6 -6
  71. package/dist/esm/config.mjs.map +1 -1
  72. package/dist/esm/config.native.js +3 -3
  73. package/dist/esm/config.native.js.map +2 -2
  74. package/dist/esm/createApp.js +1 -0
  75. package/dist/esm/createApp.js.map +1 -1
  76. package/dist/esm/createApp.mjs +1 -0
  77. package/dist/esm/createApp.mjs.map +1 -1
  78. package/dist/esm/createApp.native.js +2 -1
  79. package/dist/esm/createApp.native.js.map +2 -2
  80. package/dist/esm/index.js +1 -2
  81. package/dist/esm/index.js.map +1 -1
  82. package/dist/esm/index.mjs +1 -2
  83. package/dist/esm/index.mjs.map +1 -1
  84. package/dist/esm/index.native.js +1 -2
  85. package/dist/esm/index.native.js.map +2 -2
  86. package/dist/esm/serve-worker.js +13 -0
  87. package/dist/esm/serve-worker.js.map +6 -0
  88. package/dist/esm/serve-worker.mjs +11 -0
  89. package/dist/esm/serve-worker.mjs.map +1 -0
  90. package/dist/esm/serve-worker.native.js +13 -0
  91. package/dist/esm/serve-worker.native.js.map +6 -0
  92. package/dist/esm/serve.js +10 -140
  93. package/dist/esm/serve.js.map +2 -2
  94. package/dist/esm/serve.mjs +17 -142
  95. package/dist/esm/serve.mjs.map +1 -1
  96. package/dist/esm/serve.native.js +9 -149
  97. package/dist/esm/serve.native.js.map +2 -2
  98. package/dist/esm/server/oneServe.js +137 -0
  99. package/dist/esm/server/oneServe.js.map +6 -0
  100. package/dist/esm/server/oneServe.mjs +139 -0
  101. package/dist/esm/server/oneServe.mjs.map +1 -0
  102. package/dist/esm/server/oneServe.native.js +146 -0
  103. package/dist/esm/server/oneServe.native.js.map +6 -0
  104. package/dist/esm/server/setupBuildOptions.js +7 -0
  105. package/dist/esm/server/setupBuildOptions.js.map +6 -0
  106. package/dist/esm/server/setupBuildOptions.mjs +5 -0
  107. package/dist/esm/server/setupBuildOptions.mjs.map +1 -0
  108. package/dist/esm/server/setupBuildOptions.native.js +8 -0
  109. package/dist/esm/server/setupBuildOptions.native.js.map +6 -0
  110. package/dist/esm/setup.js.map +1 -1
  111. package/dist/esm/setup.mjs.map +1 -1
  112. package/dist/esm/utils/ensureExists.js +8 -0
  113. package/dist/esm/utils/ensureExists.js.map +6 -0
  114. package/dist/esm/utils/ensureExists.mjs +5 -0
  115. package/dist/esm/utils/ensureExists.mjs.map +1 -0
  116. package/dist/esm/utils/ensureExists.native.js +8 -0
  117. package/dist/esm/utils/ensureExists.native.js.map +6 -0
  118. package/dist/esm/vite/build.js +38 -14
  119. package/dist/esm/vite/build.js.map +1 -1
  120. package/dist/esm/vite/build.mjs +38 -18
  121. package/dist/esm/vite/build.mjs.map +1 -1
  122. package/dist/esm/vite/build.native.js +29 -15
  123. package/dist/esm/vite/build.native.js.map +2 -2
  124. package/dist/esm/vite/one.js +27 -6
  125. package/dist/esm/vite/one.js.map +1 -1
  126. package/dist/esm/vite/one.mjs +26 -9
  127. package/dist/esm/vite/one.mjs.map +1 -1
  128. package/dist/esm/vite/one.native.js +27 -8
  129. package/dist/esm/vite/one.native.js.map +2 -2
  130. package/dist/esm/vite/plugins/reactCompilerPlugin.js +59 -0
  131. package/dist/esm/vite/plugins/reactCompilerPlugin.js.map +6 -0
  132. package/dist/esm/vite/plugins/reactCompilerPlugin.mjs +67 -0
  133. package/dist/esm/vite/plugins/reactCompilerPlugin.mjs.map +1 -0
  134. package/dist/esm/vite/plugins/reactCompilerPlugin.native.js +40 -0
  135. package/dist/esm/vite/plugins/reactCompilerPlugin.native.js.map +6 -0
  136. package/package.json +26 -12
  137. package/src/cli.ts +4 -0
  138. package/src/config.ts +2 -3
  139. package/src/createApp.native.tsx +2 -1
  140. package/src/createApp.tsx +2 -0
  141. package/src/index.ts +1 -2
  142. package/src/serve-worker.ts +19 -0
  143. package/src/serve.ts +13 -218
  144. package/src/server/oneServe.ts +216 -0
  145. package/src/server/setupBuildOptions.ts +7 -0
  146. package/src/setup.ts +15 -0
  147. package/src/utils/ensureExists.ts +5 -0
  148. package/src/vite/build.ts +44 -23
  149. package/src/vite/one.ts +35 -8
  150. package/src/vite/plugins/reactCompilerPlugin.ts +70 -0
  151. package/src/vite/types.ts +21 -3
  152. package/types/config.d.ts.map +1 -1
  153. package/types/createApp.d.ts +1 -0
  154. package/types/createApp.d.ts.map +1 -1
  155. package/types/createApp.native.d.ts +1 -0
  156. package/types/createApp.native.d.ts.map +1 -1
  157. package/types/index.d.ts +1 -2
  158. package/types/index.d.ts.map +1 -1
  159. package/types/serve-worker.d.ts +3 -0
  160. package/types/serve-worker.d.ts.map +1 -0
  161. package/types/serve.d.ts +1 -1
  162. package/types/serve.d.ts.map +1 -1
  163. package/types/server/oneServe.d.ts +5 -0
  164. package/types/server/oneServe.d.ts.map +1 -0
  165. package/types/server/setupBuildOptions.d.ts +3 -0
  166. package/types/server/setupBuildOptions.d.ts.map +1 -0
  167. package/types/setup.d.ts.map +1 -1
  168. package/types/utils/ensureExists.d.ts +2 -0
  169. package/types/utils/ensureExists.d.ts.map +1 -0
  170. package/types/vite/build.d.ts.map +1 -1
  171. package/types/vite/one.d.ts.map +1 -1
  172. package/types/vite/plugins/reactCompilerPlugin.d.ts +3 -0
  173. package/types/vite/plugins/reactCompilerPlugin.d.ts.map +1 -0
  174. package/types/vite/types.d.ts +18 -2
  175. package/types/vite/types.d.ts.map +1 -1
  176. package/dist/cjs/vite/server.cjs +0 -13
  177. package/dist/cjs/vite/server.js +0 -16
  178. package/dist/cjs/vite/server.js.map +0 -6
  179. package/dist/cjs/vite/server.native.js +0 -18
  180. package/dist/cjs/vite/server.native.js.map +0 -6
  181. package/dist/esm/vite/server.js +0 -17
  182. package/dist/esm/vite/server.js.map +0 -6
  183. package/dist/esm/vite/server.mjs +0 -13
  184. package/dist/esm/vite/server.mjs.map +0 -1
  185. package/dist/esm/vite/server.native.js +0 -18
  186. package/dist/esm/vite/server.native.js.map +0 -6
  187. package/src/vite/server.ts +0 -19
  188. package/types/vite/server.d.ts +0 -2
  189. package/types/vite/server.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one",
3
- "version": "1.1.345",
3
+ "version": "1.1.347",
4
4
  "source": "src/index.ts",
5
5
  "types": "./types/index.d.ts",
6
6
  "sideEffects": [
@@ -51,6 +51,16 @@
51
51
  "import": "./dist/esm/serve.mjs",
52
52
  "require": "./dist/cjs/serve.js"
53
53
  },
54
+ "./serve-worker": {
55
+ "types": "./types/serve-worker.d.ts",
56
+ "import": "./dist/esm/serve-worker.mjs",
57
+ "require": "./dist/cjs/serve-worker.js"
58
+ },
59
+ "./setup": {
60
+ "types": "./types/setup.d.ts",
61
+ "import": "./dist/esm/setup.mjs",
62
+ "require": "./dist/cjs/setup.js"
63
+ },
54
64
  "./zero": {
55
65
  "types": "./types/zero.d.ts",
56
66
  "import": "./dist/esm/zero.mjs",
@@ -86,9 +96,11 @@
86
96
  },
87
97
  "dependencies": {
88
98
  "@azure/core-asynciterator-polyfill": "^1.0.2",
89
- "@babel/generator": "^7.25.4",
90
- "@babel/parser": "^7.25.4",
91
- "@babel/traverse": "^7.25.4",
99
+ "@babel/core": "^7.0.0",
100
+ "@babel/generator": "^7.26.3",
101
+ "@babel/parser": "^7.26.3",
102
+ "@babel/preset-typescript": "^7.26.0",
103
+ "@babel/traverse": "^7.26.4",
92
104
  "@radix-ui/react-slot": "^1.0.2",
93
105
  "@react-native-masked-view/masked-view": "^0.3.1",
94
106
  "@react-navigation/bottom-tabs": "~6.5.8",
@@ -100,14 +112,15 @@
100
112
  "@react-navigation/routers": "~6.1.9",
101
113
  "@swc/core": "^1.7.14",
102
114
  "@ungap/structured-clone": "^1.2.0",
103
- "@vxrn/resolve": "1.1.345",
104
- "@vxrn/tslib-lite": "1.1.345",
105
- "@vxrn/universal-color-scheme": "1.1.345",
106
- "@vxrn/use-isomorphic-layout-effect": "1.1.345",
115
+ "@vxrn/resolve": "1.1.347",
116
+ "@vxrn/tslib-lite": "1.1.347",
117
+ "@vxrn/universal-color-scheme": "1.1.347",
118
+ "@vxrn/use-isomorphic-layout-effect": "1.1.347",
107
119
  "babel-dead-code-elimination": "^1.0.6",
120
+ "babel-plugin-react-compiler": "^19.0.0-beta-201e55d-20241215",
108
121
  "citty": "^0.1.6",
109
122
  "core-js": "^3.38.1",
110
- "create-vxrn": "1.1.345",
123
+ "create-vxrn": "1.1.347",
111
124
  "escape-string-regexp": "^5.0.0",
112
125
  "expo-linking": "~6.3.1",
113
126
  "expo-modules-core": "^1.12.24",
@@ -125,11 +138,12 @@
125
138
  "react-native-gesture-handler": "^2.18.1",
126
139
  "react-native-safe-area-context": "4.10.5",
127
140
  "react-native-screens": "3.31.1",
141
+ "react-scan": "^0.0.48",
128
142
  "rollup-plugin-node-externals": "^7.1.2",
129
143
  "url-parse": "^1.5.10",
130
144
  "vite": "^6.0.3",
131
145
  "vite-tsconfig-paths": "^5.0.1",
132
- "vxrn": "1.1.345",
146
+ "vxrn": "1.1.347",
133
147
  "ws": "^8.18.0",
134
148
  "xxhashjs": "^0.2.2"
135
149
  },
@@ -137,7 +151,7 @@
137
151
  "react-native": "*"
138
152
  },
139
153
  "devDependencies": {
140
- "@tamagui/build": "^1.120.1",
154
+ "@tamagui/build": "^1.120.2",
141
155
  "@types/node": "^22.1.0",
142
156
  "@types/react-dom": "^18.2.25",
143
157
  "@types/url-parse": "^1.4.11",
@@ -146,7 +160,7 @@
146
160
  "get-port": "^7.1.0",
147
161
  "react-native": "0.74.5",
148
162
  "rollup": "^4.21.0",
149
- "vitest": "^2.1.1"
163
+ "vitest": "^2.1.8"
150
164
  },
151
165
  "publishConfig": {
152
166
  "access": "public"
package/src/cli.ts CHANGED
@@ -118,6 +118,9 @@ const serveCommand = defineCommand({
118
118
  cacheHeaders: {
119
119
  type: 'boolean',
120
120
  },
121
+ loadEnv: {
122
+ type: 'boolean',
123
+ },
121
124
  },
122
125
  async run({ args }) {
123
126
  const { serve } = await import('./serve')
@@ -127,6 +130,7 @@ const serveCommand = defineCommand({
127
130
  cacheHeaders: args.cacheHeaders === false ? 'off' : undefined,
128
131
  compress: args.compress,
129
132
  platform: args.platform === 'vercel' ? 'vercel' : 'node',
133
+ loadEnv: !!args.loadEnv,
130
134
  })
131
135
  },
132
136
  })
package/src/config.ts CHANGED
@@ -1,13 +1,12 @@
1
1
  import { isWebServer } from './constants'
2
2
  import type { One } from './vite/types'
3
3
 
4
- const CLIENT_RENDER_MODE = process.env.ONE_DEFAULT_RENDER_MODE as One.RouteRenderMode | undefined
5
-
6
4
  // works client or server
7
5
  export const getDefaultRenderMode = () => {
6
+ const CLIENT_RENDER_MODE = process.env.ONE_DEFAULT_RENDER_MODE as One.RouteRenderMode | undefined
8
7
  const serverConfig = globalThis['__vxrnPluginConfig__'] as One.PluginOptions | undefined
9
8
 
10
- if (isWebServer && !serverConfig) {
9
+ if (!CLIENT_RENDER_MODE && isWebServer && !serverConfig) {
11
10
  throw new Error(`Internal one error: should call setServerConfig before createManifest`)
12
11
  }
13
12
 
@@ -1,6 +1,7 @@
1
+ import { AppRegistry, LogBox } from 'react-native' // This should be the first import as it might set up global variables that are needed for the other imports
1
2
  import './polyfills-mobile'
3
+ import './setup'
2
4
  import { Root } from './Root'
3
- import { AppRegistry, LogBox } from 'react-native'
4
5
 
5
6
  export type CreateAppProps = { routes: Record<string, () => Promise<unknown>> }
6
7
 
package/src/createApp.tsx CHANGED
@@ -1,3 +1,5 @@
1
+ import './setup'
2
+
1
3
  import { Root } from './Root'
2
4
  import { resolveClientLoader } from './clientLoaderResolver'
3
5
  import { render } from './render'
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './setup'
1
+ export { createApp } from './createApp'
2
2
 
3
3
  export type { OneRouter, One } from './interfaces/router'
4
4
  import type { OneRouter } from './interfaces/router'
@@ -14,7 +14,6 @@ export { createRoute, route } from './createRoute'
14
14
  export { onClientLoaderResolve } from './clientLoaderResolver'
15
15
 
16
16
  // internals
17
- export { createApp } from './createApp'
18
17
  export { render } from './render'
19
18
  export { Root } from './Root'
20
19
  export * as routerStore from './router/router'
@@ -0,0 +1,19 @@
1
+ import { createProdServer } from 'vxrn/serve'
2
+ import { oneServe } from './server/oneServe'
3
+ import type { One } from './vite/types'
4
+ import { setupBuildInfo } from './server/setupBuildOptions'
5
+ import { ensureExists } from './utils/ensureExists'
6
+
7
+ export async function serve(buildInfo: One.BuildInfo) {
8
+ setupBuildInfo(buildInfo)
9
+ ensureExists(buildInfo.oneOptions)
10
+
11
+ // TODO make this better, this ensures we get react 19
12
+ process.env.VXRN_REACT_19 = '1'
13
+
14
+ const app = await createProdServer(buildInfo.oneOptions)
15
+
16
+ await oneServe(buildInfo.oneOptions, buildInfo.oneOptions, buildInfo, app, false)
17
+
18
+ return app
19
+ }
package/src/serve.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  import './polyfills-server'
2
2
 
3
3
  import FSExtra from 'fs-extra'
4
- import type { Hono } from 'hono'
5
- import { join } from 'node:path'
6
4
  import type { VXRNOptions } from 'vxrn'
7
- import { getServerEntry, loadEnv, serve as vxrnServe } from 'vxrn'
8
- import type { RenderAppProps } from './types'
9
-
5
+ import { setupBuildInfo } from './server/setupBuildOptions'
6
+ import { ensureExists } from './utils/ensureExists'
10
7
  import type { One } from './vite/types'
11
8
 
12
9
  process.on('uncaughtException', (err) => {
@@ -15,19 +12,22 @@ process.on('uncaughtException', (err) => {
15
12
 
16
13
  export async function serve(args: VXRNOptions['server'] = {}) {
17
14
  const buildInfo = (await FSExtra.readJSON(`dist/buildInfo.json`)) as One.BuildInfo
15
+ const { oneOptions } = buildInfo
18
16
 
19
- // ensure cache key matches build
20
- process.env.ONE_CACHE_KEY = buildInfo.constants.CACHE_KEY
17
+ setupBuildInfo(buildInfo)
18
+ ensureExists(oneOptions)
21
19
 
22
20
  // to avoid loading the CACHE_KEY before we set it use async imports:
23
21
  const { labelProcess } = await import('./cli/label-process')
24
22
  const { removeUndefined } = await import('./utils/removeUndefined')
25
- const { loadUserOneOptions } = await import('./vite/one')
23
+ const { loadEnv, serve: vxrnServe } = await import('vxrn/serve')
24
+ const { oneServe } = await import('./server/oneServe')
26
25
 
27
26
  labelProcess('serve')
28
- loadEnv('production')
29
27
 
30
- const oneOptions = await loadUserOneOptions('serve')
28
+ if (args.loadEnv) {
29
+ await loadEnv('production')
30
+ }
31
31
 
32
32
  // TODO make this better, this ensures we get react 19
33
33
  process.env.VXRN_REACT_19 = '1'
@@ -44,215 +44,10 @@ export async function serve(args: VXRNOptions['server'] = {}) {
44
44
  platform: args.platform,
45
45
  cacheHeaders: args.cacheHeaders,
46
46
  }),
47
-
48
- async beforeStart(options, app) {
49
- await oneOptions.server?.beforeStart?.(options, app)
50
- await oneServe(oneOptions, options, buildInfo, app)
51
- },
52
47
  },
53
- })
54
- }
55
-
56
- async function oneServe(
57
- options: One.PluginOptions,
58
- vxrnOptions: VXRNOptions,
59
- buildInfo: One.BuildInfo,
60
- app: Hono
61
- ) {
62
- const { createHandleRequest } = await import('./createHandleRequest')
63
- const { isResponse } = await import('./utils/isResponse')
64
- const { isStatusRedirect } = await import('./utils/isStatus')
65
- const { resolveAPIRequest } = await import('./vite/resolveAPIRequest')
66
-
67
- const isAPIRequest = new WeakMap<any, boolean>()
68
- const root = vxrnOptions.root || '.'
69
-
70
- // add redirects
71
- const redirects = options.web?.redirects
72
- if (redirects) {
73
- for (const redirect of redirects) {
74
- app.get(redirect.source, (context) => {
75
- const destinationUrl = redirect.destination.replace(/:\w+/g, (param) => {
76
- const paramName = param.substring(1)
77
- return context.req.param(paramName) || ''
78
- })
79
- return context.redirect(destinationUrl, redirect.permanent ? 301 : 302)
80
- })
81
- }
82
- }
83
-
84
- if (!buildInfo) {
85
- throw new Error(`No build info found, have you run build?`)
86
- }
87
-
88
- const { routeMap, builtRoutes } = buildInfo as One.BuildInfo
89
-
90
- const routeToBuildInfo: Record<string, One.RouteBuildInfo> = {}
91
- for (const route of builtRoutes) {
92
- routeToBuildInfo[route.cleanPath] = route
93
-
94
- // temp - make it back into brackets style
95
- const bracketRoutePath = route.cleanPath
96
- .split('/')
97
- .map((part) => {
98
- return part[0] === ':' ? `[${part.slice(1)}]` : part
99
- })
100
- .join('/')
101
- routeToBuildInfo[bracketRoutePath] = route
102
- }
103
-
104
- const serverOptions = {
105
- ...options,
106
- root,
107
- }
108
-
109
- const entryServer = getServerEntry(serverOptions)
110
- const entry = await import(entryServer)
111
-
112
- const render = entry.default.render as (props: RenderAppProps) => any
113
- const apiCJS = options.build?.api?.outputFormat === 'cjs'
114
-
115
- const handleRequest = createHandleRequest(
116
- {},
117
- {
118
- async handleAPI({ route, request, loaderProps }) {
119
- const apiFile = join(
120
- process.cwd(),
121
- 'dist',
122
- 'api',
123
- route.page.replace('[', '_').replace(']', '_') + (apiCJS ? '.cjs' : '.js')
124
- )
125
-
126
- isAPIRequest.set(request, true)
127
-
128
- return resolveAPIRequest(
129
- async () => {
130
- try {
131
- return await import(apiFile)
132
- } catch (err) {
133
- console.error(`\n [one] Error importing API route at ${apiFile}:
134
48
 
135
- ${err}
136
-
137
- If this is an import error, you can likely fix this by adding this dependency to
138
- the "optimizeDeps.include" array in your vite.config.ts.
139
-
140
- 🐞 For a better error message run "node" and enter:
141
-
142
- import('${apiFile}')\n\n`)
143
- return {}
144
- }
145
- },
146
- request,
147
- loaderProps?.params || {}
148
- )
149
- },
150
-
151
- async handleSSR({ route, url, loaderProps }) {
152
- if (route.type === 'ssr') {
153
- const buildInfo = routeToBuildInfo[route.page]
154
- if (!buildInfo) {
155
- throw new Error(
156
- `No buildinfo found for ${url}, route: ${route.page}, in keys: ${Object.keys(routeToBuildInfo)}`
157
- )
158
- }
159
-
160
- try {
161
- const exported = await import(buildInfo.serverJsPath)
162
- const loaderData = await exported.loader?.(loaderProps)
163
- const preloads = buildInfo.preloads
164
-
165
- const headers = new Headers()
166
- headers.set('content-type', 'text/html')
167
-
168
- return new Response(
169
- await render({
170
- loaderData,
171
- loaderProps,
172
- path: loaderProps?.path || '/',
173
- preloads,
174
- }),
175
- {
176
- headers,
177
- }
178
- )
179
- } catch (err) {
180
- console.error(`[one] Error rendering SSR route ${route.page}
181
-
182
- ${err?.['stack'] ?? err}
183
-
184
- url: ${url}`)
185
- }
186
- }
187
- },
188
- }
189
- )
190
-
191
- // preload reading in all the files, for prod performance:
192
- const htmlFiles: Record<string, string> = {}
193
- for (const key in routeMap) {
194
- const info = routeToBuildInfo[key]
195
-
196
- if (info?.type === 'ssr') {
197
- // we handle this on each request
198
- continue
199
- }
200
-
201
- htmlFiles[key] = await FSExtra.readFile(join('dist/client', routeMap[key]), 'utf-8')
202
- }
203
-
204
- app.use(async (context, next) => {
205
- // serve our generated html files
206
- const html = htmlFiles[context.req.path]
207
- if (html) {
208
- return context.html(html)
209
- }
210
-
211
- try {
212
- const request = context.req.raw
213
- const response = await handleRequest.handler(request)
214
-
215
- if (response) {
216
- if (isResponse(response)) {
217
- if (isStatusRedirect(response.status)) {
218
- const location = `${response.headers.get('location') || ''}`
219
- response.headers.forEach((value, key) => {
220
- context.header(key, value)
221
- })
222
- return context.redirect(location, response.status)
223
- }
224
-
225
- if (isAPIRequest.get(request)) {
226
- try {
227
- // don't cache api requests by default
228
- response.headers.set('Cache-Control', 'no-store')
229
- } catch (err) {
230
- console.info(
231
- `Error udpating cache header on api route "${
232
- context.req.path
233
- }" to no-store, it is ${response.headers.get('cache-control')}, continue`,
234
- err
235
- )
236
- }
237
- }
238
-
239
- return response as Response
240
- }
241
-
242
- return context.json(
243
- response,
244
- 200,
245
- isAPIRequest.get(request)
246
- ? {
247
- 'Cache-Control': 'no-store',
248
- }
249
- : undefined
250
- )
251
- }
252
- } catch (err) {
253
- console.error(` [one] Error handling request: ${(err as any)['stack']}`)
254
- }
255
-
256
- await next()
49
+ async beforeStart(options, app) {
50
+ await oneServe(oneOptions, options, buildInfo, app)
51
+ },
257
52
  })
258
53
  }
@@ -0,0 +1,216 @@
1
+ import type { Hono } from 'hono'
2
+ import { join } from 'node:path'
3
+ import type { VXRNOptions } from 'vxrn'
4
+ import { getServerEntry } from 'vxrn/serve'
5
+ import type { RenderAppProps } from '../types'
6
+ import type { One } from '../vite/types'
7
+
8
+ export async function oneServe(
9
+ oneOptions: One.PluginOptions,
10
+ vxrnOptions: VXRNOptions,
11
+ buildInfo: One.BuildInfo,
12
+ app: Hono,
13
+ serveStatic = true
14
+ ) {
15
+ const { createHandleRequest } = await import('../createHandleRequest')
16
+ const { isResponse } = await import('../utils/isResponse')
17
+ const { isStatusRedirect } = await import('../utils/isStatus')
18
+ const { resolveAPIRequest } = await import('../vite/resolveAPIRequest')
19
+
20
+ const isAPIRequest = new WeakMap<any, boolean>()
21
+ const root = vxrnOptions.root || '.'
22
+
23
+ // add redirects
24
+ const redirects = oneOptions.web?.redirects
25
+ if (redirects) {
26
+ for (const redirect of redirects) {
27
+ app.get(redirect.source, (context) => {
28
+ const destinationUrl = redirect.destination.replace(/:\w+/g, (param) => {
29
+ const paramName = param.substring(1)
30
+ return context.req.param(paramName) || ''
31
+ })
32
+ return context.redirect(destinationUrl, redirect.permanent ? 301 : 302)
33
+ })
34
+ }
35
+ }
36
+
37
+ if (!buildInfo) {
38
+ throw new Error(`No build info found, have you run build?`)
39
+ }
40
+
41
+ const { routeMap, builtRoutes } = buildInfo as One.BuildInfo
42
+
43
+ const routeToBuildInfo: Record<string, One.RouteBuildInfo> = {}
44
+ for (const route of builtRoutes) {
45
+ routeToBuildInfo[route.cleanPath] = route
46
+
47
+ // temp - make it back into brackets style
48
+ const bracketRoutePath = route.cleanPath
49
+ .split('/')
50
+ .map((part) => {
51
+ return part[0] === ':' ? `[${part.slice(1)}]` : part
52
+ })
53
+ .join('/')
54
+ routeToBuildInfo[bracketRoutePath] = route
55
+ }
56
+
57
+ const serverOptions = {
58
+ ...oneOptions,
59
+ root,
60
+ }
61
+
62
+ const entryServer = getServerEntry(serverOptions)
63
+ const entry = await import(entryServer)
64
+
65
+ const render = entry.default.render as (props: RenderAppProps) => any
66
+ const apiCJS = oneOptions.build?.api?.outputFormat === 'cjs'
67
+
68
+ const handleRequest = createHandleRequest(
69
+ {},
70
+ {
71
+ async handleAPI({ route, request, loaderProps }) {
72
+ const apiFile = join(
73
+ process.cwd(),
74
+ 'dist',
75
+ 'api',
76
+ route.page.replace('[', '_').replace(']', '_') + (apiCJS ? '.cjs' : '.js')
77
+ )
78
+
79
+ isAPIRequest.set(request, true)
80
+
81
+ return resolveAPIRequest(
82
+ async () => {
83
+ try {
84
+ return await import(apiFile)
85
+ } catch (err) {
86
+ console.error(`\n [one] Error importing API route at ${apiFile}:
87
+
88
+ ${err}
89
+
90
+ If this is an import error, you can likely fix this by adding this dependency to
91
+ the "optimizeDeps.include" array in your vite.config.ts.
92
+
93
+ 🐞 For a better error message run "node" and enter:
94
+
95
+ import('${apiFile}')\n\n`)
96
+ return {}
97
+ }
98
+ },
99
+ request,
100
+ loaderProps?.params || {}
101
+ )
102
+ },
103
+
104
+ async handleSSR({ route, url, loaderProps }) {
105
+ if (route.type === 'ssr') {
106
+ const buildInfo = routeToBuildInfo[route.page]
107
+ if (!buildInfo) {
108
+ throw new Error(
109
+ `No buildinfo found for ${url}, route: ${route.page}, in keys: ${Object.keys(routeToBuildInfo)}`
110
+ )
111
+ }
112
+
113
+ try {
114
+ const exported = await import(buildInfo.serverJsPath)
115
+ const loaderData = await exported.loader?.(loaderProps)
116
+ const preloads = buildInfo.preloads
117
+
118
+ const headers = new Headers()
119
+ headers.set('content-type', 'text/html')
120
+
121
+ return new Response(
122
+ await render({
123
+ loaderData,
124
+ loaderProps,
125
+ path: loaderProps?.path || '/',
126
+ preloads,
127
+ }),
128
+ {
129
+ headers,
130
+ }
131
+ )
132
+ } catch (err) {
133
+ console.error(`[one] Error rendering SSR route ${route.page}
134
+
135
+ ${err?.['stack'] ?? err}
136
+
137
+ url: ${url}`)
138
+ }
139
+ }
140
+ },
141
+ }
142
+ )
143
+
144
+ // preload reading in all the files, for prod performance:
145
+ const htmlFiles: Record<string, string> = {}
146
+
147
+ if (serveStatic) {
148
+ const { readFile } = await import('node:fs/promises')
149
+
150
+ for (const key in routeMap) {
151
+ const info = routeToBuildInfo[key]
152
+
153
+ if (info?.type === 'ssr') {
154
+ // we handle this on each request
155
+ continue
156
+ }
157
+
158
+ htmlFiles[key] = await readFile(join('dist/client', routeMap[key]), 'utf-8')
159
+ }
160
+ }
161
+
162
+ app.use(async (context, next) => {
163
+ // serve our generated html files
164
+ const html = htmlFiles[context.req.path]
165
+ if (html) {
166
+ return context.html(html)
167
+ }
168
+
169
+ try {
170
+ const request = context.req.raw
171
+ const response = await handleRequest.handler(request)
172
+
173
+ if (response) {
174
+ if (isResponse(response)) {
175
+ if (isStatusRedirect(response.status)) {
176
+ const location = `${response.headers.get('location') || ''}`
177
+ response.headers.forEach((value, key) => {
178
+ context.header(key, value)
179
+ })
180
+ return context.redirect(location, response.status)
181
+ }
182
+
183
+ if (isAPIRequest.get(request)) {
184
+ try {
185
+ // don't cache api requests by default
186
+ response.headers.set('Cache-Control', 'no-store')
187
+ } catch (err) {
188
+ console.info(
189
+ `Error udpating cache header on api route "${
190
+ context.req.path
191
+ }" to no-store, it is ${response.headers.get('cache-control')}, continue`,
192
+ err
193
+ )
194
+ }
195
+ }
196
+
197
+ return response as Response
198
+ }
199
+
200
+ return context.json(
201
+ response,
202
+ 200,
203
+ isAPIRequest.get(request)
204
+ ? {
205
+ 'Cache-Control': 'no-store',
206
+ }
207
+ : undefined
208
+ )
209
+ }
210
+ } catch (err) {
211
+ console.error(` [one] Error handling request: ${(err as any)['stack']}`)
212
+ }
213
+
214
+ await next()
215
+ })
216
+ }
@@ -0,0 +1,7 @@
1
+ import type { One } from '../vite/types'
2
+
3
+ export function setupBuildInfo(buildInfo: One.BuildInfo) {
4
+ // ensure cache key matches build
5
+ process.env.ONE_CACHE_KEY ||= buildInfo.constants.CACHE_KEY
6
+ process.env.ONE_DEFAULT_RENDER_MODE ||= buildInfo.oneOptions?.web?.defaultRenderMode || 'ssg'
7
+ }
package/src/setup.ts CHANGED
@@ -1,3 +1,18 @@
1
+ // FIXME: This will break the release build of the React Native app.
2
+ // import { scan } from 'react-scan'
3
+
4
+ // if (process.env.ONE_ENABLE_REACT_SCAN) {
5
+ // const val = JSON.parse(process.env.ONE_ENABLE_REACT_SCAN)
6
+ // scan(
7
+ // val === true
8
+ // ? {
9
+ // enabled: true,
10
+ // showToolbar: false,
11
+ // }
12
+ // : val
13
+ // )
14
+ // }
15
+
1
16
  // fixes bad import error in expo-modules-core
2
17
  // without this you run into error loading web immediately
3
18
  // where globalThis.expo is not defined
@@ -0,0 +1,5 @@
1
+ export function ensureExists<T>(value: T | undefined | null): asserts value is T {
2
+ if (value === undefined || value === null) {
3
+ throw new Error(`Missing value.`)
4
+ }
5
+ }