one 1.25.12 → 1.25.13

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 (210) hide show
  1. package/dist/cjs/cli/build.cjs +8 -161
  2. package/dist/cjs/cli/build.native.js +8 -204
  3. package/dist/cjs/cli/build.native.js.map +1 -1
  4. package/dist/cjs/createDevHandleRequest.cjs +151 -0
  5. package/dist/cjs/createDevHandleRequest.native.js +194 -0
  6. package/dist/cjs/createDevHandleRequest.native.js.map +1 -0
  7. package/dist/cjs/createHandleRequest.cjs +1 -123
  8. package/dist/cjs/createHandleRequest.native.js +1 -163
  9. package/dist/cjs/createHandleRequest.native.js.map +1 -1
  10. package/dist/cjs/createHandleRequest.test.cjs +25 -25
  11. package/dist/cjs/createHandleRequest.test.native.js +25 -25
  12. package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
  13. package/dist/cjs/layouts/Drawer.cjs +0 -2
  14. package/dist/cjs/layouts/Drawer.native.js.map +1 -1
  15. package/dist/cjs/layouts/Tabs.cjs +0 -2
  16. package/dist/cjs/layouts/Tabs.native.js.map +1 -1
  17. package/dist/cjs/router/web/WebStackView.cjs +0 -2
  18. package/dist/cjs/router/web/WebStackView.native.js +0 -2
  19. package/dist/cjs/router/web/WebStackView.native.js.map +1 -1
  20. package/dist/cjs/serve-worker.cjs +3 -2
  21. package/dist/cjs/serve-worker.native.js +3 -2
  22. package/dist/cjs/serve-worker.native.js.map +1 -1
  23. package/dist/cjs/server/workerHandler.cjs +12 -7
  24. package/dist/cjs/server/workerHandler.native.js +13 -8
  25. package/dist/cjs/server/workerHandler.native.js.map +1 -1
  26. package/dist/cjs/server/workerHandler.test.cjs +25 -0
  27. package/dist/cjs/server/workerHandler.test.native.js +25 -0
  28. package/dist/cjs/server/workerHandler.test.native.js.map +1 -1
  29. package/dist/cjs/vite/cloudflareWranglerConfig.cjs +247 -0
  30. package/dist/cjs/vite/cloudflareWranglerConfig.native.js +392 -0
  31. package/dist/cjs/vite/cloudflareWranglerConfig.native.js.map +1 -0
  32. package/dist/cjs/vite/cloudflareWranglerConfig.test.cjs +116 -0
  33. package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js +120 -0
  34. package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
  35. package/dist/cjs/vite/one.cjs +4 -2
  36. package/dist/cjs/vite/one.native.js +8 -6
  37. package/dist/cjs/vite/one.native.js.map +1 -1
  38. package/dist/cjs/vite/plugins/SSRCSSPlugin.cjs +10 -1
  39. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js +52 -3
  40. package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  41. package/dist/cjs/vite/plugins/environmentGuardPlugin.cjs +1 -1
  42. package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js +1 -1
  43. package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
  44. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.cjs +4 -0
  45. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
  46. package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
  47. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +14 -5
  48. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +15 -5
  49. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  50. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.cjs +47 -0
  51. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
  52. package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
  53. package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +2 -1
  54. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +2 -1
  55. package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  56. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.cjs +12 -0
  57. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
  58. package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
  59. package/dist/cjs/vite/plugins/workerdDevPlugin.cjs +377 -0
  60. package/dist/cjs/vite/plugins/workerdDevPlugin.native.js +493 -0
  61. package/dist/cjs/vite/plugins/workerdDevPlugin.native.js.map +1 -0
  62. package/dist/cjs/vite/plugins/workerdDevPlugin.test.cjs +42 -0
  63. package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js +45 -0
  64. package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
  65. package/dist/esm/cli/build.mjs +1 -154
  66. package/dist/esm/cli/build.mjs.map +1 -1
  67. package/dist/esm/cli/build.native.js +1 -197
  68. package/dist/esm/cli/build.native.js.map +1 -1
  69. package/dist/esm/createDevHandleRequest.mjs +126 -0
  70. package/dist/esm/createDevHandleRequest.mjs.map +1 -0
  71. package/dist/esm/createDevHandleRequest.native.js +166 -0
  72. package/dist/esm/createDevHandleRequest.native.js.map +1 -0
  73. package/dist/esm/createHandleRequest.mjs +1 -123
  74. package/dist/esm/createHandleRequest.mjs.map +1 -1
  75. package/dist/esm/createHandleRequest.native.js +1 -163
  76. package/dist/esm/createHandleRequest.native.js.map +1 -1
  77. package/dist/esm/createHandleRequest.test.mjs +1 -1
  78. package/dist/esm/createHandleRequest.test.native.js +1 -1
  79. package/dist/esm/fork/useLinking.native.test.mjs +1 -1
  80. package/dist/esm/getURL.native.test.mjs +1 -1
  81. package/dist/esm/layouts/Drawer.mjs +0 -2
  82. package/dist/esm/layouts/Drawer.mjs.map +1 -1
  83. package/dist/esm/layouts/Drawer.native.js.map +1 -1
  84. package/dist/esm/layouts/Tabs.mjs +0 -2
  85. package/dist/esm/layouts/Tabs.mjs.map +1 -1
  86. package/dist/esm/layouts/Tabs.native.js.map +1 -1
  87. package/dist/esm/router/hmrImport.native.test.mjs +1 -1
  88. package/dist/esm/router/routeHmr.native.test.mjs +1 -1
  89. package/dist/esm/router/routeHmr.native.test.mjs.map +1 -1
  90. package/dist/esm/router/web/WebStackView.mjs +0 -2
  91. package/dist/esm/router/web/WebStackView.mjs.map +1 -1
  92. package/dist/esm/router/web/WebStackView.native.js +0 -2
  93. package/dist/esm/router/web/WebStackView.native.js.map +1 -1
  94. package/dist/esm/serve-worker.mjs +3 -2
  95. package/dist/esm/serve-worker.mjs.map +1 -1
  96. package/dist/esm/serve-worker.native.js +3 -2
  97. package/dist/esm/serve-worker.native.js.map +1 -1
  98. package/dist/esm/server/workerHandler.mjs +12 -7
  99. package/dist/esm/server/workerHandler.mjs.map +1 -1
  100. package/dist/esm/server/workerHandler.native.js +13 -8
  101. package/dist/esm/server/workerHandler.native.js.map +1 -1
  102. package/dist/esm/server/workerHandler.test.mjs +25 -0
  103. package/dist/esm/server/workerHandler.test.mjs.map +1 -1
  104. package/dist/esm/server/workerHandler.test.native.js +25 -0
  105. package/dist/esm/server/workerHandler.test.native.js.map +1 -1
  106. package/dist/esm/vite/cloudflareWranglerConfig.mjs +202 -0
  107. package/dist/esm/vite/cloudflareWranglerConfig.mjs.map +1 -0
  108. package/dist/esm/vite/cloudflareWranglerConfig.native.js +344 -0
  109. package/dist/esm/vite/cloudflareWranglerConfig.native.js.map +1 -0
  110. package/dist/esm/vite/cloudflareWranglerConfig.test.mjs +117 -0
  111. package/dist/esm/vite/cloudflareWranglerConfig.test.mjs.map +1 -0
  112. package/dist/esm/vite/cloudflareWranglerConfig.test.native.js +118 -0
  113. package/dist/esm/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
  114. package/dist/esm/vite/one.mjs +4 -2
  115. package/dist/esm/vite/one.mjs.map +1 -1
  116. package/dist/esm/vite/one.native.js +8 -6
  117. package/dist/esm/vite/one.native.js.map +1 -1
  118. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs +10 -1
  119. package/dist/esm/vite/plugins/SSRCSSPlugin.mjs.map +1 -1
  120. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js +52 -3
  121. package/dist/esm/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
  122. package/dist/esm/vite/plugins/environmentGuardPlugin.mjs +1 -1
  123. package/dist/esm/vite/plugins/environmentGuardPlugin.mjs.map +1 -1
  124. package/dist/esm/vite/plugins/environmentGuardPlugin.native.js +1 -1
  125. package/dist/esm/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
  126. package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs +4 -0
  127. package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs.map +1 -1
  128. package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
  129. package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
  130. package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +13 -4
  131. package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
  132. package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +14 -4
  133. package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
  134. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs +47 -0
  135. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs.map +1 -1
  136. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
  137. package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
  138. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +2 -1
  139. package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
  140. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +2 -1
  141. package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
  142. package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs +12 -0
  143. package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs.map +1 -1
  144. package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
  145. package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
  146. package/dist/esm/vite/plugins/workerdDevPlugin.mjs +349 -0
  147. package/dist/esm/vite/plugins/workerdDevPlugin.mjs.map +1 -0
  148. package/dist/esm/vite/plugins/workerdDevPlugin.native.js +462 -0
  149. package/dist/esm/vite/plugins/workerdDevPlugin.native.js.map +1 -0
  150. package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs +43 -0
  151. package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs.map +1 -0
  152. package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js +43 -0
  153. package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
  154. package/package.json +9 -9
  155. package/src/cli/build.ts +7 -192
  156. package/src/createDevHandleRequest.ts +186 -0
  157. package/src/createHandleRequest.test.ts +1 -1
  158. package/src/createHandleRequest.ts +2 -172
  159. package/src/layouts/Drawer.web.tsx +0 -3
  160. package/src/layouts/Tabs.web.tsx +0 -2
  161. package/src/router/web/WebStackView.tsx +0 -3
  162. package/src/serve-worker.ts +6 -1
  163. package/src/server/workerHandler.test.ts +23 -0
  164. package/src/server/workerHandler.ts +15 -7
  165. package/src/vite/cloudflareWranglerConfig.test.ts +101 -0
  166. package/src/vite/cloudflareWranglerConfig.ts +248 -0
  167. package/src/vite/one.ts +11 -1
  168. package/src/vite/plugins/SSRCSSPlugin.ts +17 -2
  169. package/src/vite/plugins/environmentGuardPlugin.test.ts +5 -0
  170. package/src/vite/plugins/environmentGuardPlugin.ts +2 -2
  171. package/src/vite/plugins/fileSystemRouterPlugin.test.ts +44 -0
  172. package/src/vite/plugins/fileSystemRouterPlugin.tsx +20 -8
  173. package/src/vite/plugins/virtualEntryPlugin.test.ts +13 -0
  174. package/src/vite/plugins/virtualEntryPlugin.ts +3 -1
  175. package/src/vite/plugins/workerdDevPlugin.test.ts +44 -0
  176. package/src/vite/plugins/workerdDevPlugin.ts +408 -0
  177. package/types/cli/build.d.ts.map +1 -1
  178. package/types/createDevHandleRequest.d.ts +10 -0
  179. package/types/createDevHandleRequest.d.ts.map +1 -0
  180. package/types/createHandleRequest.d.ts +2 -9
  181. package/types/createHandleRequest.d.ts.map +1 -1
  182. package/types/layouts/Drawer.web.d.ts.map +1 -1
  183. package/types/layouts/Tabs.web.d.ts.map +1 -1
  184. package/types/router/web/WebStackView.d.ts.map +1 -1
  185. package/types/serve-worker.d.ts +3 -1
  186. package/types/serve-worker.d.ts.map +1 -1
  187. package/types/server/workerHandler.d.ts +1 -0
  188. package/types/server/workerHandler.d.ts.map +1 -1
  189. package/types/vite/cloudflareWranglerConfig.d.ts +21 -0
  190. package/types/vite/cloudflareWranglerConfig.d.ts.map +1 -0
  191. package/types/vite/cloudflareWranglerConfig.test.d.ts +2 -0
  192. package/types/vite/cloudflareWranglerConfig.test.d.ts.map +1 -0
  193. package/types/vite/one.d.ts.map +1 -1
  194. package/types/vite/plugins/SSRCSSPlugin.d.ts.map +1 -1
  195. package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
  196. package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
  197. package/types/vite/plugins/workerdDevPlugin.d.ts +15 -0
  198. package/types/vite/plugins/workerdDevPlugin.d.ts.map +1 -0
  199. package/types/vite/plugins/workerdDevPlugin.test.d.ts +2 -0
  200. package/types/vite/plugins/workerdDevPlugin.test.d.ts.map +1 -0
  201. package/dist/cjs/headless/devHeadlessNote.cjs +0 -34
  202. package/dist/cjs/headless/devHeadlessNote.native.js +0 -37
  203. package/dist/cjs/headless/devHeadlessNote.native.js.map +0 -1
  204. package/dist/esm/headless/devHeadlessNote.mjs +0 -9
  205. package/dist/esm/headless/devHeadlessNote.mjs.map +0 -1
  206. package/dist/esm/headless/devHeadlessNote.native.js +0 -9
  207. package/dist/esm/headless/devHeadlessNote.native.js.map +0 -1
  208. package/src/headless/devHeadlessNote.ts +0 -13
  209. package/types/headless/devHeadlessNote.d.ts +0 -2
  210. package/types/headless/devHeadlessNote.d.ts.map +0 -1
package/src/cli/build.ts CHANGED
@@ -29,6 +29,13 @@ import { getRouterRootFromOneOptions } from '../utils/getRouterRootFromOneOption
29
29
  import { isRolldown } from '../utils/isRolldown'
30
30
  import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
31
31
  import { buildVercelOutputDirectory } from '../vercel/build/buildVercelOutputDirectory'
32
+ import {
33
+ createCloudflareWranglerConfig,
34
+ getCloudflareProjectName,
35
+ isPlainObject,
36
+ loadUserWranglerConfig,
37
+ type JsonValue,
38
+ } from '../vite/cloudflareWranglerConfig'
32
39
  import { getManifest } from '../vite/getManifest'
33
40
  import { loadUserOneOptions } from '../vite/loadConfig'
34
41
  import { runWithAsyncLocalContext } from '../vite/one-server-only'
@@ -51,191 +58,10 @@ function normalizeDeploy(
51
58
  return deploy
52
59
  }
53
60
 
54
- type JsonPrimitive = string | number | boolean | null
55
- type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }
56
-
57
- const GENERATED_CLOUDFLARE_WRANGLER_RULES = [
58
- { type: 'ESModule', globs: ['./server/**/*.js'], fallthrough: true },
59
- { type: 'ESModule', globs: ['./api/**/*.js'], fallthrough: true },
60
- { type: 'ESModule', globs: ['./middlewares/**/*.js'], fallthrough: true },
61
- { type: 'ESModule', globs: ['./assets/**/*.js'], fallthrough: true },
62
- ]
63
-
64
61
  const CLOUDFLARE_DEPLOY_WRANGLER_RULES = [
65
62
  { type: 'ESModule', globs: ['assets/**/*.js', 'assets/**/*.mjs'] },
66
63
  ]
67
64
 
68
- function isPlainObject(value: unknown): value is Record<string, JsonValue> {
69
- return !!value && typeof value === 'object' && !Array.isArray(value)
70
- }
71
-
72
- function mergeJsonObjects(
73
- base: Record<string, JsonValue>,
74
- overrides: Record<string, JsonValue>
75
- ): Record<string, JsonValue> {
76
- const merged: Record<string, JsonValue> = { ...base }
77
-
78
- for (const [key, value] of Object.entries(overrides)) {
79
- const baseValue = merged[key]
80
- if (isPlainObject(baseValue) && isPlainObject(value)) {
81
- merged[key] = mergeJsonObjects(baseValue, value)
82
- } else {
83
- merged[key] = value
84
- }
85
- }
86
-
87
- return merged
88
- }
89
-
90
- function dedupeJsonValues<T extends JsonValue>(values: T[]): T[] {
91
- const seen = new Set<string>()
92
- return values.filter((value) => {
93
- const key = JSON.stringify(value)
94
- if (seen.has(key)) return false
95
- seen.add(key)
96
- return true
97
- })
98
- }
99
-
100
- function mergeCloudflareCompatibilityFlags(flags: unknown): string[] {
101
- const userFlags = Array.isArray(flags)
102
- ? flags.filter((flag): flag is string => typeof flag === 'string')
103
- : []
104
-
105
- return dedupeJsonValues<string>(['nodejs_compat', ...userFlags])
106
- }
107
-
108
- function mergeCloudflareRules(rules: unknown): JsonValue[] {
109
- const userRules = Array.isArray(rules)
110
- ? rules.filter((rule): rule is JsonValue => isPlainObject(rule))
111
- : []
112
-
113
- return dedupeJsonValues<JsonValue>([
114
- ...GENERATED_CLOUDFLARE_WRANGLER_RULES,
115
- ...userRules,
116
- ])
117
- }
118
-
119
- // minimal JSONC parser: strips line/block comments (string-aware) and trailing
120
- // commas, then runs JSON.parse. sufficient for small hand-written config files.
121
- function parseJsonc(text: string): unknown {
122
- let out = ''
123
- let i = 0
124
- let inString = false
125
- let quote = ''
126
- while (i < text.length) {
127
- const ch = text[i]
128
- const next = text[i + 1]
129
- if (inString) {
130
- if (ch === '\\') {
131
- out += ch + (next ?? '')
132
- i += 2
133
- continue
134
- }
135
- if (ch === quote) inString = false
136
- out += ch
137
- i++
138
- continue
139
- }
140
- if (ch === '"' || ch === "'") {
141
- inString = true
142
- quote = ch
143
- out += ch
144
- i++
145
- continue
146
- }
147
- if (ch === '/' && next === '/') {
148
- while (i < text.length && text[i] !== '\n') i++
149
- continue
150
- }
151
- if (ch === '/' && next === '*') {
152
- i += 2
153
- while (i < text.length - 1 && !(text[i] === '*' && text[i + 1] === '/')) i++
154
- i += 2
155
- continue
156
- }
157
- out += ch
158
- i++
159
- }
160
- return JSON.parse(out.replace(/,(\s*[}\]])/g, '$1'))
161
- }
162
-
163
- async function loadUserWranglerConfig(
164
- root: string
165
- ): Promise<{ path: string; config: Record<string, JsonValue> } | null> {
166
- const candidateRoots = [...new Set([root, process.cwd()])]
167
-
168
- for (const candidateRoot of candidateRoots) {
169
- for (const fileName of ['wrangler.jsonc', 'wrangler.json']) {
170
- const configPath = join(candidateRoot, fileName)
171
- if (!(await FSExtra.pathExists(configPath))) {
172
- continue
173
- }
174
-
175
- const contents = await FSExtra.readFile(configPath, 'utf-8')
176
- let parsed: unknown
177
- try {
178
- parsed = parseJsonc(contents)
179
- } catch (err) {
180
- throw new Error(
181
- `Failed to parse ${relative(process.cwd(), configPath)}: ${(err as Error).message}`
182
- )
183
- }
184
-
185
- if (!isPlainObject(parsed)) {
186
- throw new Error(
187
- `Expected ${relative(process.cwd(), configPath)} to contain a top-level JSON object`
188
- )
189
- }
190
-
191
- return {
192
- path: configPath,
193
- config: parsed,
194
- }
195
- }
196
- }
197
-
198
- return null
199
- }
200
-
201
- function createCloudflareWranglerConfig(
202
- projectName: string,
203
- userConfig?: Record<string, JsonValue>
204
- ): Record<string, JsonValue> {
205
- const generatedConfig: Record<string, JsonValue> = {
206
- name: projectName,
207
- main: 'worker.js',
208
- compatibility_date: '2024-12-05',
209
- compatibility_flags: ['nodejs_compat'],
210
- find_additional_modules: true,
211
- rules: GENERATED_CLOUDFLARE_WRANGLER_RULES,
212
- assets: {
213
- directory: 'client',
214
- binding: 'ASSETS',
215
- run_worker_first: true,
216
- },
217
- }
218
-
219
- const mergedConfig = userConfig
220
- ? mergeJsonObjects(generatedConfig, userConfig)
221
- : generatedConfig
222
-
223
- mergedConfig.main = 'worker.js'
224
- mergedConfig.find_additional_modules = true
225
- mergedConfig.compatibility_flags = mergeCloudflareCompatibilityFlags(
226
- mergedConfig.compatibility_flags
227
- )
228
- mergedConfig.rules = mergeCloudflareRules(mergedConfig.rules)
229
- mergedConfig.assets = {
230
- ...(isPlainObject(mergedConfig.assets) ? mergedConfig.assets : {}),
231
- directory: 'client',
232
- binding: 'ASSETS',
233
- run_worker_first: true,
234
- }
235
-
236
- return mergedConfig
237
- }
238
-
239
65
  function omitEmptyJsonValues(value: JsonValue): JsonValue | undefined {
240
66
  if (Array.isArray(value)) {
241
67
  const items = value
@@ -276,17 +102,6 @@ async function finalizeCloudflareWranglerDeployConfig(configPath: string) {
276
102
  await FSExtra.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`)
277
103
  }
278
104
 
279
- // reads package.json name, strips npm scope prefix for use as cloudflare worker name
280
- async function getCloudflareProjectName(root: string): Promise<string> {
281
- try {
282
- const pkg = JSON.parse(await FSExtra.readFile(join(root, 'package.json'), 'utf-8'))
283
- if (pkg.name) {
284
- return pkg.name.replace(/^@[^/]+\//, '')
285
- }
286
- } catch {}
287
- return 'one-app'
288
- }
289
-
290
105
  // ensure worker threads inherit the same CACHE_KEY as the main process
291
106
  process.env.ONE_CACHE_KEY = constants.CACHE_KEY
292
107
 
@@ -0,0 +1,186 @@
1
+ import { LOADER_JS_POSTFIX_UNCACHED } from './constants'
2
+ import {
3
+ compileManifest,
4
+ getURLfromRequestURL,
5
+ isPageRequestMethod,
6
+ isStaticAssetRequestPath,
7
+ resolveAPIRoute,
8
+ resolveLoaderRoute,
9
+ resolvePageRoute,
10
+ runMiddlewares,
11
+ type RequestHandlerResponse,
12
+ type RequestHandlers,
13
+ } from './createHandleRequest'
14
+ import { getPathFromLoaderPath } from './utils/cleanUrl'
15
+ import { getManifest } from './vite/getManifest'
16
+
17
+ const debugRouter = process.env.ONE_DEBUG_ROUTER
18
+
19
+ // node-dev request handler. kept out of createHandleRequest.ts so the worker
20
+ // graph (one/serve-worker) does not pull getManifest -> micromatch/fast-glob.
21
+ export function createHandleRequest(
22
+ handlers: RequestHandlers,
23
+ {
24
+ routerRoot,
25
+ ignoredRouteFiles,
26
+ routePaths,
27
+ }: { routerRoot: string; ignoredRouteFiles?: string[]; routePaths?: string[] }
28
+ ) {
29
+ const manifest = getManifest({ routerRoot, ignoredRouteFiles, routePaths })
30
+ if (!manifest) {
31
+ throw new Error(`No routes manifest`)
32
+ }
33
+ const compiledManifest = compileManifest(manifest)
34
+
35
+ return {
36
+ manifest,
37
+ handler: async function handleRequest(
38
+ request: Request
39
+ ): Promise<RequestHandlerResponse> {
40
+ const url = getURLfromRequestURL(request)
41
+ const { pathname } = url
42
+
43
+ // skip paths handled by vite internals or react native dev middleware
44
+ if (
45
+ pathname === '/__vxrnhmr' ||
46
+ pathname.startsWith('/@vite/') ||
47
+ pathname.startsWith('/@fs/') ||
48
+ pathname.startsWith('/@id/') ||
49
+ pathname.startsWith('/node_modules/') ||
50
+ pathname.startsWith('/debugger-frontend') ||
51
+ pathname.startsWith('/inspector')
52
+ ) {
53
+ return null
54
+ }
55
+
56
+ const looksLikeStaticFile = isStaticAssetRequestPath(pathname)
57
+
58
+ if (handlers.handleAPI) {
59
+ const apiRoute = compiledManifest.apiRoutes.find((route) => {
60
+ return route.compiledRegex.test(pathname)
61
+ })
62
+ if (apiRoute) {
63
+ if (debugRouter) {
64
+ console.info(`[one] ⚡ ${pathname} → matched API route: ${apiRoute.page}`)
65
+ }
66
+ return await resolveAPIRoute(handlers, request, url, apiRoute)
67
+ }
68
+ }
69
+
70
+ if (!isPageRequestMethod(request.method)) {
71
+ return null
72
+ }
73
+
74
+ if (handlers.handleLoader) {
75
+ const isClientRequestingNewRoute = pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)
76
+
77
+ if (isClientRequestingNewRoute) {
78
+ const platformParam = url.searchParams.get('platform')
79
+ const isNativePlatform =
80
+ platformParam === 'ios' ||
81
+ platformParam === 'android' ||
82
+ platformParam === 'native'
83
+
84
+ // for native requests, try serving the pre-built .native.js static file first
85
+ // (SSG/SPA routes generate standalone CJS loaders at build time)
86
+ if (isNativePlatform && handlers.handleStaticFile) {
87
+ const nativeLoaderPath = pathname.replace(/\.js$/, '.native.js')
88
+ const staticResponse = await handlers.handleStaticFile(nativeLoaderPath)
89
+ if (staticResponse) {
90
+ return staticResponse
91
+ }
92
+ }
93
+
94
+ const originalUrl = getPathFromLoaderPath(pathname)
95
+
96
+ for (const route of compiledManifest.pageRoutes) {
97
+ if (route.file === '') {
98
+ // ignore not found route
99
+ continue
100
+ }
101
+
102
+ const finalUrl = new URL(originalUrl, url.origin)
103
+ finalUrl.search = url.search
104
+
105
+ if (!route.compiledRegex.test(finalUrl.pathname)) {
106
+ continue
107
+ }
108
+
109
+ // route is known to export no loader → return empty module without
110
+ // importing the page bundle. on workerd/cloudflare, evaluating a
111
+ // no-loader SSG page's server bundle can crash when it pulls in
112
+ // RN/Tamagui modules that aren't compatible with the workers runtime.
113
+ if (route.hasLoader === false) {
114
+ const emptyBody = isNativePlatform
115
+ ? 'exports.loader=function(){return undefined}'
116
+ : 'export function loader() { return undefined }'
117
+ return new Response(emptyBody, {
118
+ headers: { 'Content-Type': 'text/javascript' },
119
+ })
120
+ }
121
+
122
+ const cleanedRequest = new Request(finalUrl, request)
123
+ return resolveLoaderRoute(handlers, cleanedRequest, finalUrl, route)
124
+ }
125
+
126
+ // no matching route - return empty module so client handles gracefully
127
+ const emptyBody = isNativePlatform
128
+ ? 'exports.loader=function(){return{}}'
129
+ : 'export {}'
130
+ return new Response(emptyBody, {
131
+ headers: { 'Content-Type': 'text/javascript' },
132
+ })
133
+ }
134
+ }
135
+
136
+ if (handlers.handlePage) {
137
+ for (const route of compiledManifest.pageRoutes) {
138
+ if (!route.compiledRegex.test(pathname)) {
139
+ continue
140
+ }
141
+
142
+ // static asset requests (sourcemaps, favicons, fonts, …) should not
143
+ // SSR the user's +not-found page or hijack a dynamic route. for
144
+ // +not-found we still run middleware so it can intercept, then
145
+ // short-circuit to a bare 404 instead of rendering the page tree.
146
+ const isDynamicRoute = Object.keys(route.routeKeys).length > 0
147
+ const isNotFoundRoute = route.page.endsWith('/+not-found')
148
+ if (looksLikeStaticFile && isNotFoundRoute) {
149
+ if (debugRouter) {
150
+ console.info(
151
+ `[one] ⚡ ${pathname} → bare 404 for static probe on ${route.page}`
152
+ )
153
+ }
154
+ if (!route.middlewares?.length) {
155
+ return null
156
+ }
157
+ return await runMiddlewares(handlers, request, route, async () => {
158
+ return new Response(null, {
159
+ status: 404,
160
+ headers: { 'Content-Type': 'text/plain' },
161
+ })
162
+ })
163
+ }
164
+ if (looksLikeStaticFile && isDynamicRoute) {
165
+ if (debugRouter) {
166
+ console.info(
167
+ `[one] ⚡ ${pathname} → skipping dynamic route ${route.page} for static asset`
168
+ )
169
+ }
170
+ continue
171
+ }
172
+
173
+ if (debugRouter) {
174
+ console.info(
175
+ `[one] ⚡ ${pathname} → matched page route: ${route.page} (${route.type})`
176
+ )
177
+ }
178
+
179
+ return resolvePageRoute(handlers, request, url, route)
180
+ }
181
+ }
182
+
183
+ return null
184
+ },
185
+ }
186
+ }
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it, vi, beforeEach } from 'vitest'
2
- import { createHandleRequest } from './createHandleRequest'
2
+ import { createHandleRequest } from './createDevHandleRequest'
3
3
 
4
4
  // Mock the manifest. Specific routes come before dynamic ones, matching how
5
5
  // the real manifest is ordered after matchers.sortRoutes().
@@ -3,9 +3,7 @@ import type { Middleware, MiddlewareContext } from './createMiddleware'
3
3
  import type { RouteNode } from './router/Route'
4
4
  import type { RouteInfoCompiled } from './server/createRoutesManifest'
5
5
  import type { LoaderProps } from './types'
6
- import { getPathFromLoaderPath } from './utils/cleanUrl'
7
6
  import { isResponse } from './utils/isResponse'
8
- import { getManifest } from './vite/getManifest'
9
7
  import { resolveAPIEndpoint, resolveResponse } from './vite/resolveResponse'
10
8
  import type { RouteInfo } from './vite/types'
11
9
 
@@ -24,12 +22,12 @@ type RequestHandlerProps<RouteExtraProps extends object = {}> = {
24
22
  loaderProps?: LoaderProps
25
23
  }
26
24
 
27
- type RequestHandlerResponse = null | string | Response
25
+ export type RequestHandlerResponse = null | string | Response
28
26
 
29
27
  const debugRouter = process.env.ONE_DEBUG_ROUTER
30
28
  const staticAssetPathRe = /\.(?:[a-z0-9]{2,4}|webmanifest|wasm|woff2)$/i
31
29
 
32
- function isStaticAssetRequestPath(pathname: string): boolean {
30
+ export function isStaticAssetRequestPath(pathname: string): boolean {
33
31
  return (
34
32
  !pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED) && staticAssetPathRe.test(pathname)
35
33
  )
@@ -382,174 +380,6 @@ export function compileManifest(manifest: {
382
380
  }
383
381
  }
384
382
 
385
- // in dev mode we do it more simply:
386
- export function createHandleRequest(
387
- handlers: RequestHandlers,
388
- {
389
- routerRoot,
390
- ignoredRouteFiles,
391
- routePaths,
392
- }: { routerRoot: string; ignoredRouteFiles?: string[]; routePaths?: string[] }
393
- ) {
394
- const manifest = getManifest({ routerRoot, ignoredRouteFiles, routePaths })
395
- if (!manifest) {
396
- throw new Error(`No routes manifest`)
397
- }
398
- const compiledManifest = compileManifest(manifest)
399
-
400
- return {
401
- manifest,
402
- handler: async function handleRequest(
403
- request: Request
404
- ): Promise<RequestHandlerResponse> {
405
- const url = getURLfromRequestURL(request)
406
- const { pathname, search } = url
407
-
408
- // skip paths handled by vite internals or react native dev middleware
409
- if (
410
- pathname === '/__vxrnhmr' ||
411
- pathname.startsWith('/@vite/') ||
412
- pathname.startsWith('/@fs/') ||
413
- pathname.startsWith('/@id/') ||
414
- pathname.startsWith('/node_modules/') ||
415
- pathname.startsWith('/debugger-frontend') ||
416
- pathname.startsWith('/inspector')
417
- ) {
418
- return null
419
- }
420
-
421
- const looksLikeStaticFile = isStaticAssetRequestPath(pathname)
422
-
423
- if (handlers.handleAPI) {
424
- const apiRoute = compiledManifest.apiRoutes.find((route) => {
425
- return route.compiledRegex.test(pathname)
426
- })
427
- if (apiRoute) {
428
- if (debugRouter) {
429
- console.info(`[one] ⚡ ${pathname} → matched API route: ${apiRoute.page}`)
430
- }
431
- return await resolveAPIRoute(handlers, request, url, apiRoute)
432
- }
433
- }
434
-
435
- if (!isPageRequestMethod(request.method)) {
436
- return null
437
- }
438
-
439
- if (handlers.handleLoader) {
440
- const isClientRequestingNewRoute = pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)
441
-
442
- if (isClientRequestingNewRoute) {
443
- const platformParam = url.searchParams.get('platform')
444
- const isNativePlatform =
445
- platformParam === 'ios' ||
446
- platformParam === 'android' ||
447
- platformParam === 'native'
448
-
449
- // for native requests, try serving the pre-built .native.js static file first
450
- // (SSG/SPA routes generate standalone CJS loaders at build time)
451
- if (isNativePlatform && handlers.handleStaticFile) {
452
- const nativeLoaderPath = pathname.replace(/\.js$/, '.native.js')
453
- const staticResponse = await handlers.handleStaticFile(nativeLoaderPath)
454
- if (staticResponse) {
455
- return staticResponse
456
- }
457
- }
458
-
459
- const originalUrl = getPathFromLoaderPath(pathname)
460
-
461
- for (const route of compiledManifest.pageRoutes) {
462
- if (route.file === '') {
463
- // ignore not found route
464
- continue
465
- }
466
-
467
- const finalUrl = new URL(originalUrl, url.origin)
468
- finalUrl.search = url.search
469
-
470
- if (!route.compiledRegex.test(finalUrl.pathname)) {
471
- continue
472
- }
473
-
474
- // route is known to export no loader → return empty module without
475
- // importing the page bundle. on workerd/cloudflare, evaluating a
476
- // no-loader SSG page's server bundle can crash when it pulls in
477
- // RN/Tamagui modules that aren't compatible with the workers runtime.
478
- if (route.hasLoader === false) {
479
- const emptyBody = isNativePlatform
480
- ? 'exports.loader=function(){return undefined}'
481
- : 'export function loader() { return undefined }'
482
- return new Response(emptyBody, {
483
- headers: { 'Content-Type': 'text/javascript' },
484
- })
485
- }
486
-
487
- const cleanedRequest = new Request(finalUrl, request)
488
- return resolveLoaderRoute(handlers, cleanedRequest, finalUrl, route)
489
- }
490
-
491
- // no matching route - return empty module so client handles gracefully
492
- const emptyBody = isNativePlatform
493
- ? 'exports.loader=function(){return{}}'
494
- : 'export {}'
495
- return new Response(emptyBody, {
496
- headers: { 'Content-Type': 'text/javascript' },
497
- })
498
- }
499
- }
500
-
501
- if (handlers.handlePage) {
502
- for (const route of compiledManifest.pageRoutes) {
503
- if (!route.compiledRegex.test(pathname)) {
504
- continue
505
- }
506
-
507
- // static asset requests (sourcemaps, favicons, fonts, …) should not
508
- // SSR the user's +not-found page or hijack a dynamic route. for
509
- // +not-found we still run middleware so it can intercept, then
510
- // short-circuit to a bare 404 instead of rendering the page tree.
511
- const isDynamicRoute = Object.keys(route.routeKeys).length > 0
512
- const isNotFoundRoute = route.page.endsWith('/+not-found')
513
- if (looksLikeStaticFile && isNotFoundRoute) {
514
- if (debugRouter) {
515
- console.info(
516
- `[one] ⚡ ${pathname} → bare 404 for static probe on ${route.page}`
517
- )
518
- }
519
- if (!route.middlewares?.length) {
520
- return null
521
- }
522
- return await runMiddlewares(handlers, request, route, async () => {
523
- return new Response(null, {
524
- status: 404,
525
- headers: { 'Content-Type': 'text/plain' },
526
- })
527
- })
528
- }
529
- if (looksLikeStaticFile && isDynamicRoute) {
530
- if (debugRouter) {
531
- console.info(
532
- `[one] ⚡ ${pathname} → skipping dynamic route ${route.page} for static asset`
533
- )
534
- }
535
- continue
536
- }
537
-
538
- if (debugRouter) {
539
- console.info(
540
- `[one] ⚡ ${pathname} → matched page route: ${route.page} (${route.type})`
541
- )
542
- }
543
-
544
- return resolvePageRoute(handlers, request, url, route)
545
- }
546
- }
547
-
548
- return null
549
- },
550
- }
551
- }
552
-
553
383
  export function getLoaderParams(
554
384
  url: URL,
555
385
  config: { compiledRegex: RegExp; routeKeys: Record<string, string> }
@@ -15,7 +15,6 @@ import {
15
15
  import { Children, type ComponentProps, forwardRef, type ReactNode } from 'react'
16
16
 
17
17
  import { getCustomNavigatorChildren, isNavigatorConfigChild } from '../headless/children'
18
- import { devHeadlessNote } from '../headless/devHeadlessNote'
19
18
  import { renderKeptMountedScreens, useVisitedScreens } from '../headless/keepMounted'
20
19
  import {
21
20
  DrawerStateProvider,
@@ -75,8 +74,6 @@ function HeadlessDrawerView({ customChildren }: { customChildren?: ReactNode[] }
75
74
  const { screens, focused } = useDrawer()
76
75
  const visited = useVisitedScreens(focused.key)
77
76
 
78
- devHeadlessNote('Drawer')
79
-
80
77
  if (customChildren?.length) {
81
78
  return <>{customChildren}</>
82
79
  }
@@ -11,7 +11,6 @@ import {
11
11
  import { Children, Fragment, forwardRef, type ReactNode, useMemo, useRef } from 'react'
12
12
  import { getPathFromState } from '../fork/getPathFromState'
13
13
  import { getCustomNavigatorChildren, isNavigatorConfigChild } from '../headless/children'
14
- import { devHeadlessNote } from '../headless/devHeadlessNote'
15
14
  import { renderKeptMountedScreens, useVisitedScreens } from '../headless/keepMounted'
16
15
  import { useTabs } from '../headless/useTabs'
17
16
  import { getResolvedLinking } from '../router/linkingConfig'
@@ -118,7 +117,6 @@ function WebTabsNavigator({
118
117
  function HeadlessTabsView({ customChildren }: { customChildren?: ReactNode[] }) {
119
118
  const { screens, focused } = useTabs()
120
119
  const visited = useVisitedScreens(focused.key)
121
- devHeadlessNote('Tabs')
122
120
 
123
121
  if (customChildren?.length) {
124
122
  return <Fragment>{customChildren}</Fragment>
@@ -21,7 +21,6 @@ import {
21
21
  } from 'react'
22
22
  import useLatestCallback from 'use-latest-callback'
23
23
 
24
- import { devHeadlessNote } from '../../headless/devHeadlessNote'
25
24
  import { useWebPresentations } from '../../headless/Presentations'
26
25
  import type {
27
26
  ModalPresentationOptions,
@@ -95,8 +94,6 @@ function HeadlessStackView({
95
94
  return <Fragment>{customChildren}</Fragment>
96
95
  }
97
96
 
98
- devHeadlessNote('Stack')
99
-
100
97
  const lastBaseIndex = findLastNonOverlayIndex(
101
98
  state,
102
99
  descriptors,
@@ -19,7 +19,11 @@ export type { LazyRoutes }
19
19
  * API route handler contexts as `{ env, executionCtx }`).
20
20
  * Call `updateRoutes(newBuildInfo, newLazyRoutes?)` to hot-swap the route table.
21
21
  */
22
- export async function serve(buildInfo: One.BuildInfo, lazyRoutes?: LazyRoutes) {
22
+ export async function serve(
23
+ buildInfo: One.BuildInfo,
24
+ lazyRoutes?: LazyRoutes,
25
+ serveOptions?: { disableModuleCache?: boolean }
26
+ ) {
23
27
  setupBuildInfo(buildInfo)
24
28
  ensureExists(buildInfo.oneOptions)
25
29
  setServerGlobals()
@@ -28,6 +32,7 @@ export async function serve(buildInfo: One.BuildInfo, lazyRoutes?: LazyRoutes) {
28
32
  oneOptions: buildInfo.oneOptions!,
29
33
  buildInfo,
30
34
  lazyRoutes: lazyRoutes!,
35
+ disableModuleCache: serveOptions?.disableModuleCache,
31
36
  })
32
37
 
33
38
  return {