one 1.15.10 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/dist/cjs/cli/build.cjs +98 -58
  2. package/dist/cjs/cli/build.native.js +106 -63
  3. package/dist/cjs/cli/build.native.js.map +1 -1
  4. package/dist/cjs/cli/buildPage.cjs +3 -3
  5. package/dist/cjs/cli/buildPage.native.js +3 -3
  6. package/dist/cjs/cli/buildPage.native.js.map +1 -1
  7. package/dist/cjs/constants.cjs +2 -0
  8. package/dist/cjs/constants.native.js +2 -0
  9. package/dist/cjs/constants.native.js.map +1 -1
  10. package/dist/cjs/createAPIRoute.native.js.map +1 -1
  11. package/dist/cjs/createApp.cjs +2 -6
  12. package/dist/cjs/createHandleRequest.cjs +2 -2
  13. package/dist/cjs/createHandleRequest.native.js +2 -2
  14. package/dist/cjs/createHandleRequest.native.js.map +1 -1
  15. package/dist/cjs/hooks.cjs +5 -1
  16. package/dist/cjs/hooks.native.js +7 -1
  17. package/dist/cjs/hooks.native.js.map +1 -1
  18. package/dist/cjs/index.native.js.map +1 -1
  19. package/dist/cjs/metro-config/getViteMetroPluginOptions.cjs +10 -7
  20. package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js +13 -10
  21. package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js.map +1 -1
  22. package/dist/cjs/metro-config/getViteMetroPluginOptions.test.cjs +23 -0
  23. package/dist/cjs/metro-config/getViteMetroPluginOptions.test.native.js +26 -0
  24. package/dist/cjs/metro-config/getViteMetroPluginOptions.test.native.js.map +1 -0
  25. package/dist/cjs/router/Route.cjs +21 -1
  26. package/dist/cjs/router/Route.native.js +22 -1
  27. package/dist/cjs/router/Route.native.js.map +1 -1
  28. package/dist/cjs/router/interceptRoutes.cjs +6 -6
  29. package/dist/cjs/router/interceptRoutes.native.js +6 -6
  30. package/dist/cjs/router/interceptRoutes.native.js.map +1 -1
  31. package/dist/cjs/router/params.cjs +46 -0
  32. package/dist/cjs/router/params.native.js +70 -0
  33. package/dist/cjs/router/params.native.js.map +1 -0
  34. package/dist/cjs/router/useScreens.cjs +3 -0
  35. package/dist/cjs/router/useScreens.native.js +2 -0
  36. package/dist/cjs/router/useScreens.native.js.map +1 -1
  37. package/dist/cjs/serve-worker.native.js.map +1 -1
  38. package/dist/cjs/server/getServerManifest.cjs +6 -6
  39. package/dist/cjs/server/getServerManifest.native.js +6 -6
  40. package/dist/cjs/server/getServerManifest.native.js.map +1 -1
  41. package/dist/cjs/server/oneServe.cjs +9 -5
  42. package/dist/cjs/server/oneServe.native.js +9 -5
  43. package/dist/cjs/server/oneServe.native.js.map +1 -1
  44. package/dist/cjs/server/workerHandler.cjs +2 -2
  45. package/dist/cjs/server/workerHandler.native.js +2 -2
  46. package/dist/cjs/server/workerHandler.native.js.map +1 -1
  47. package/dist/cjs/skewProtection.cjs +48 -7
  48. package/dist/cjs/skewProtection.native.js +48 -7
  49. package/dist/cjs/skewProtection.native.js.map +1 -1
  50. package/dist/cjs/useLoader.cjs +67 -69
  51. package/dist/cjs/useLoader.native.js +113 -117
  52. package/dist/cjs/useLoader.native.js.map +1 -1
  53. package/dist/cjs/utils/dynamicImport.cjs +3 -1
  54. package/dist/cjs/utils/dynamicImport.native.js +22 -1
  55. package/dist/cjs/utils/dynamicImport.native.js.map +1 -1
  56. package/dist/cjs/utils/toAbsolute.cjs +5 -2
  57. package/dist/cjs/utils/toAbsolute.native.js +6 -1
  58. package/dist/cjs/utils/toAbsolute.native.js.map +1 -1
  59. package/dist/cjs/utils/workerImport.cjs +1 -1
  60. package/dist/cjs/utils/workerImport.native.js +1 -1
  61. package/dist/cjs/utils/workerImport.native.js.map +1 -1
  62. package/dist/cjs/views/RootErrorBoundary.cjs +114 -117
  63. package/dist/cjs/views/RootErrorBoundary.native.js +126 -146
  64. package/dist/cjs/views/RootErrorBoundary.native.js.map +1 -1
  65. package/dist/cjs/views/Try.cjs +17 -18
  66. package/dist/cjs/views/Try.native.js +28 -42
  67. package/dist/cjs/views/Try.native.js.map +1 -1
  68. package/dist/cjs/vite/plugins/criticalCSSPlugin.cjs +2 -1
  69. package/dist/cjs/vite/plugins/criticalCSSPlugin.native.js +2 -1
  70. package/dist/cjs/vite/plugins/criticalCSSPlugin.native.js.map +1 -1
  71. package/dist/cjs/vite/plugins/criticalCSSPlugin.test.cjs +26 -20
  72. package/dist/cjs/vite/plugins/criticalCSSPlugin.test.native.js +28 -20
  73. package/dist/cjs/vite/plugins/criticalCSSPlugin.test.native.js.map +1 -1
  74. package/dist/cjs/vite/plugins/imageDataPlugin.cjs +3 -2
  75. package/dist/cjs/vite/plugins/imageDataPlugin.native.js +3 -2
  76. package/dist/cjs/vite/plugins/imageDataPlugin.native.js.map +1 -1
  77. package/dist/cjs/vite/plugins/imageDataPlugin.test.cjs +34 -69
  78. package/dist/cjs/vite/plugins/imageDataPlugin.test.native.js +34 -69
  79. package/dist/cjs/vite/plugins/imageDataPlugin.test.native.js.map +1 -1
  80. package/dist/cjs/vite/plugins/sourceInspectorPlugin.cjs +20 -2
  81. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js +23 -2
  82. package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
  83. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.cjs +21 -0
  84. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js +28 -0
  85. package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -0
  86. package/dist/cjs/vite/resolveResponse.cjs +7 -2
  87. package/dist/cjs/vite/resolveResponse.native.js +7 -2
  88. package/dist/cjs/vite/resolveResponse.native.js.map +1 -1
  89. package/dist/esm/cli/build.mjs +100 -60
  90. package/dist/esm/cli/build.mjs.map +1 -1
  91. package/dist/esm/cli/build.native.js +108 -65
  92. package/dist/esm/cli/build.native.js.map +1 -1
  93. package/dist/esm/cli/buildPage.mjs +4 -4
  94. package/dist/esm/cli/buildPage.mjs.map +1 -1
  95. package/dist/esm/cli/buildPage.native.js +4 -4
  96. package/dist/esm/cli/buildPage.native.js.map +1 -1
  97. package/dist/esm/constants.mjs +2 -1
  98. package/dist/esm/constants.mjs.map +1 -1
  99. package/dist/esm/constants.native.js +2 -1
  100. package/dist/esm/constants.native.js.map +1 -1
  101. package/dist/esm/createAPIRoute.mjs.map +1 -1
  102. package/dist/esm/createAPIRoute.native.js.map +1 -1
  103. package/dist/esm/createApp.mjs +2 -6
  104. package/dist/esm/createApp.mjs.map +1 -1
  105. package/dist/esm/createHandleRequest.mjs +2 -2
  106. package/dist/esm/createHandleRequest.mjs.map +1 -1
  107. package/dist/esm/createHandleRequest.native.js +2 -2
  108. package/dist/esm/createHandleRequest.native.js.map +1 -1
  109. package/dist/esm/hooks.mjs +5 -1
  110. package/dist/esm/hooks.mjs.map +1 -1
  111. package/dist/esm/hooks.native.js +7 -1
  112. package/dist/esm/hooks.native.js.map +1 -1
  113. package/dist/esm/index.js.map +1 -1
  114. package/dist/esm/index.mjs.map +1 -1
  115. package/dist/esm/index.native.js.map +1 -1
  116. package/dist/esm/metro-config/getViteMetroPluginOptions.mjs +9 -7
  117. package/dist/esm/metro-config/getViteMetroPluginOptions.mjs.map +1 -1
  118. package/dist/esm/metro-config/getViteMetroPluginOptions.native.js +12 -10
  119. package/dist/esm/metro-config/getViteMetroPluginOptions.native.js.map +1 -1
  120. package/dist/esm/metro-config/getViteMetroPluginOptions.test.mjs +24 -0
  121. package/dist/esm/metro-config/getViteMetroPluginOptions.test.mjs.map +1 -0
  122. package/dist/esm/metro-config/getViteMetroPluginOptions.test.native.js +24 -0
  123. package/dist/esm/metro-config/getViteMetroPluginOptions.test.native.js.map +1 -0
  124. package/dist/esm/router/Route.mjs +21 -1
  125. package/dist/esm/router/Route.mjs.map +1 -1
  126. package/dist/esm/router/Route.native.js +22 -1
  127. package/dist/esm/router/Route.native.js.map +1 -1
  128. package/dist/esm/router/interceptRoutes.mjs +7 -7
  129. package/dist/esm/router/interceptRoutes.mjs.map +1 -1
  130. package/dist/esm/router/interceptRoutes.native.js +7 -7
  131. package/dist/esm/router/interceptRoutes.native.js.map +1 -1
  132. package/dist/esm/router/params.mjs +21 -0
  133. package/dist/esm/router/params.mjs.map +1 -0
  134. package/dist/esm/router/params.native.js +42 -0
  135. package/dist/esm/router/params.native.js.map +1 -0
  136. package/dist/esm/router/useScreens.mjs +3 -0
  137. package/dist/esm/router/useScreens.mjs.map +1 -1
  138. package/dist/esm/router/useScreens.native.js +2 -0
  139. package/dist/esm/router/useScreens.native.js.map +1 -1
  140. package/dist/esm/serve-worker.mjs.map +1 -1
  141. package/dist/esm/serve-worker.native.js.map +1 -1
  142. package/dist/esm/server/getServerManifest.mjs +6 -6
  143. package/dist/esm/server/getServerManifest.mjs.map +1 -1
  144. package/dist/esm/server/getServerManifest.native.js +6 -6
  145. package/dist/esm/server/getServerManifest.native.js.map +1 -1
  146. package/dist/esm/server/oneServe.mjs +11 -7
  147. package/dist/esm/server/oneServe.mjs.map +1 -1
  148. package/dist/esm/server/oneServe.native.js +11 -7
  149. package/dist/esm/server/oneServe.native.js.map +1 -1
  150. package/dist/esm/server/workerHandler.mjs +2 -2
  151. package/dist/esm/server/workerHandler.mjs.map +1 -1
  152. package/dist/esm/server/workerHandler.native.js +2 -2
  153. package/dist/esm/server/workerHandler.native.js.map +1 -1
  154. package/dist/esm/skewProtection.mjs +48 -8
  155. package/dist/esm/skewProtection.mjs.map +1 -1
  156. package/dist/esm/skewProtection.native.js +48 -8
  157. package/dist/esm/skewProtection.native.js.map +1 -1
  158. package/dist/esm/useLoader.mjs +64 -66
  159. package/dist/esm/useLoader.mjs.map +1 -1
  160. package/dist/esm/useLoader.native.js +112 -116
  161. package/dist/esm/useLoader.native.js.map +1 -1
  162. package/dist/esm/utils/dynamicImport.mjs +1 -1
  163. package/dist/esm/utils/dynamicImport.mjs.map +1 -1
  164. package/dist/esm/utils/dynamicImport.native.js +20 -1
  165. package/dist/esm/utils/dynamicImport.native.js.map +1 -1
  166. package/dist/esm/utils/toAbsolute.mjs +3 -1
  167. package/dist/esm/utils/toAbsolute.mjs.map +1 -1
  168. package/dist/esm/utils/toAbsolute.native.js +5 -1
  169. package/dist/esm/utils/toAbsolute.native.js.map +1 -1
  170. package/dist/esm/utils/workerImport.mjs +2 -2
  171. package/dist/esm/utils/workerImport.mjs.map +1 -1
  172. package/dist/esm/utils/workerImport.native.js +2 -2
  173. package/dist/esm/utils/workerImport.native.js.map +1 -1
  174. package/dist/esm/views/RootErrorBoundary.mjs +114 -117
  175. package/dist/esm/views/RootErrorBoundary.mjs.map +1 -1
  176. package/dist/esm/views/RootErrorBoundary.native.js +126 -146
  177. package/dist/esm/views/RootErrorBoundary.native.js.map +1 -1
  178. package/dist/esm/views/Try.mjs +17 -18
  179. package/dist/esm/views/Try.mjs.map +1 -1
  180. package/dist/esm/views/Try.native.js +28 -42
  181. package/dist/esm/views/Try.native.js.map +1 -1
  182. package/dist/esm/vite/plugins/criticalCSSPlugin.mjs +2 -1
  183. package/dist/esm/vite/plugins/criticalCSSPlugin.mjs.map +1 -1
  184. package/dist/esm/vite/plugins/criticalCSSPlugin.native.js +2 -1
  185. package/dist/esm/vite/plugins/criticalCSSPlugin.native.js.map +1 -1
  186. package/dist/esm/vite/plugins/criticalCSSPlugin.test.mjs +26 -20
  187. package/dist/esm/vite/plugins/criticalCSSPlugin.test.mjs.map +1 -1
  188. package/dist/esm/vite/plugins/criticalCSSPlugin.test.native.js +28 -20
  189. package/dist/esm/vite/plugins/criticalCSSPlugin.test.native.js.map +1 -1
  190. package/dist/esm/vite/plugins/imageDataPlugin.mjs +4 -3
  191. package/dist/esm/vite/plugins/imageDataPlugin.mjs.map +1 -1
  192. package/dist/esm/vite/plugins/imageDataPlugin.native.js +4 -3
  193. package/dist/esm/vite/plugins/imageDataPlugin.native.js.map +1 -1
  194. package/dist/esm/vite/plugins/imageDataPlugin.test.mjs +34 -69
  195. package/dist/esm/vite/plugins/imageDataPlugin.test.mjs.map +1 -1
  196. package/dist/esm/vite/plugins/imageDataPlugin.test.native.js +34 -69
  197. package/dist/esm/vite/plugins/imageDataPlugin.test.native.js.map +1 -1
  198. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs +19 -3
  199. package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs.map +1 -1
  200. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js +22 -3
  201. package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
  202. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs +22 -0
  203. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs.map +1 -0
  204. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js +26 -0
  205. package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -0
  206. package/dist/esm/vite/resolveResponse.mjs +7 -2
  207. package/dist/esm/vite/resolveResponse.mjs.map +1 -1
  208. package/dist/esm/vite/resolveResponse.native.js +7 -2
  209. package/dist/esm/vite/resolveResponse.native.js.map +1 -1
  210. package/expo-plugin.cjs +1 -0
  211. package/package.json +15 -10
  212. package/react-native-commands.cjs +1 -0
  213. package/src/cli/build.ts +156 -99
  214. package/src/cli/buildPage.ts +4 -4
  215. package/src/constants.ts +15 -0
  216. package/src/createAPIRoute.ts +35 -2
  217. package/src/createApp.tsx +2 -6
  218. package/src/createHandleRequest.ts +6 -2
  219. package/src/hooks.tsx +9 -1
  220. package/src/index.ts +8 -1
  221. package/src/metro-config/getViteMetroPluginOptions.test.ts +34 -0
  222. package/src/metro-config/getViteMetroPluginOptions.ts +14 -11
  223. package/src/router/Route.tsx +52 -2
  224. package/src/router/interceptRoutes.ts +7 -7
  225. package/src/router/params.ts +32 -0
  226. package/src/router/useScreens.tsx +18 -0
  227. package/src/serve-worker.ts +4 -2
  228. package/src/server/getServerManifest.ts +11 -7
  229. package/src/server/oneServe.ts +12 -14
  230. package/src/server/workerHandler.ts +13 -2
  231. package/src/skewProtection.ts +45 -5
  232. package/src/useLoader.ts +6 -4
  233. package/src/utils/dynamicImport.ts +2 -2
  234. package/src/utils/toAbsolute.ts +5 -0
  235. package/src/utils/workerImport.ts +2 -2
  236. package/src/views/RootErrorBoundary.tsx +18 -0
  237. package/src/views/Try.tsx +18 -0
  238. package/src/vite/plugins/criticalCSSPlugin.test.ts +34 -24
  239. package/src/vite/plugins/criticalCSSPlugin.ts +3 -2
  240. package/src/vite/plugins/imageDataPlugin.test.ts +39 -83
  241. package/src/vite/plugins/imageDataPlugin.ts +5 -4
  242. package/src/vite/plugins/sourceInspectorPlugin.test.ts +40 -0
  243. package/src/vite/plugins/sourceInspectorPlugin.ts +30 -2
  244. package/src/vite/resolveResponse.ts +6 -2
  245. package/types/cli/build.d.ts.map +1 -1
  246. package/types/constants.d.ts +9 -0
  247. package/types/constants.d.ts.map +1 -1
  248. package/types/createAPIRoute.d.ts +28 -3
  249. package/types/createAPIRoute.d.ts.map +1 -1
  250. package/types/createApp.d.ts.map +1 -1
  251. package/types/createHandleRequest.d.ts +1 -1
  252. package/types/createHandleRequest.d.ts.map +1 -1
  253. package/types/headless-server.d.ts +1 -1
  254. package/types/hooks.d.ts.map +1 -1
  255. package/types/index.d.ts +1 -1
  256. package/types/index.d.ts.map +1 -1
  257. package/types/metro-config/getViteMetroPluginOptions.d.ts +5 -0
  258. package/types/metro-config/getViteMetroPluginOptions.d.ts.map +1 -1
  259. package/types/metro-config/getViteMetroPluginOptions.test.d.ts +2 -0
  260. package/types/metro-config/getViteMetroPluginOptions.test.d.ts.map +1 -0
  261. package/types/router/Route.d.ts +1 -0
  262. package/types/router/Route.d.ts.map +1 -1
  263. package/types/router/params.d.ts +3 -0
  264. package/types/router/params.d.ts.map +1 -0
  265. package/types/router/useScreens.d.ts.map +1 -1
  266. package/types/serve-worker.d.ts +5 -3
  267. package/types/serve-worker.d.ts.map +1 -1
  268. package/types/server/getServerManifest.d.ts.map +1 -1
  269. package/types/server/oneServe.d.ts.map +1 -1
  270. package/types/server/workerHandler.d.ts +1 -1
  271. package/types/server/workerHandler.d.ts.map +1 -1
  272. package/types/skewProtection.d.ts +1 -0
  273. package/types/skewProtection.d.ts.map +1 -1
  274. package/types/useLoader.d.ts.map +1 -1
  275. package/types/utils/dynamicImport.d.ts +2 -0
  276. package/types/utils/dynamicImport.d.ts.map +1 -1
  277. package/types/utils/toAbsolute.d.ts +3 -0
  278. package/types/utils/toAbsolute.d.ts.map +1 -1
  279. package/types/views/RootErrorBoundary.d.ts.map +1 -1
  280. package/types/views/Try.d.ts.map +1 -1
  281. package/types/vite/plugins/criticalCSSPlugin.d.ts.map +1 -1
  282. package/types/vite/plugins/imageDataPlugin.d.ts.map +1 -1
  283. package/types/vite/plugins/sourceInspectorPlugin.d.ts +2 -0
  284. package/types/vite/plugins/sourceInspectorPlugin.d.ts.map +1 -1
  285. package/types/vite/plugins/sourceInspectorPlugin.test.d.ts +2 -0
  286. package/types/vite/plugins/sourceInspectorPlugin.test.d.ts.map +1 -0
  287. package/types/vite/resolveResponse.d.ts +1 -1
  288. package/types/vite/resolveResponse.d.ts.map +1 -1
@@ -1,5 +1,8 @@
1
+ import { resolve } from 'node:path'
1
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
3
 
4
+ const PROJECT_ROOT = resolve('/project')
5
+
3
6
  describe('criticalCSSPlugin', () => {
4
7
  beforeEach(() => {
5
8
  vi.resetModules()
@@ -14,12 +17,12 @@ describe('criticalCSSPlugin', () => {
14
17
  const { criticalCSSPlugin } = await import('./criticalCSSPlugin')
15
18
  const plugin = criticalCSSPlugin()
16
19
 
17
- ;(plugin.configResolved as any)({ root: '/project' })
20
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
18
21
 
19
22
  const result = await (plugin.resolveId as any).call(
20
23
  { resolve: vi.fn() },
21
24
  './styles.css',
22
- '/project/src/App.tsx'
25
+ resolve('/project/src/App.tsx')
23
26
  )
24
27
  expect(result).toBeNull()
25
28
  })
@@ -28,12 +31,12 @@ describe('criticalCSSPlugin', () => {
28
31
  const { criticalCSSPlugin } = await import('./criticalCSSPlugin')
29
32
  const plugin = criticalCSSPlugin()
30
33
 
31
- ;(plugin.configResolved as any)({ root: '/project' })
34
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
32
35
 
33
36
  const result = await (plugin.resolveId as any).call(
34
37
  { resolve: vi.fn() },
35
38
  './data.json',
36
- '/project/src/App.tsx'
39
+ resolve('/project/src/App.tsx')
37
40
  )
38
41
  expect(result).toBeNull()
39
42
  })
@@ -42,25 +45,25 @@ describe('criticalCSSPlugin', () => {
42
45
  const { criticalCSSPlugin } = await import('./criticalCSSPlugin')
43
46
  const plugin = criticalCSSPlugin()
44
47
 
45
- ;(plugin.configResolved as any)({ root: '/project' })
48
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
46
49
 
50
+ const resolvedCssPath = resolve('/project/src/styles.inline.css')
47
51
  const mockResolve = vi.fn().mockResolvedValue({
48
- id: '/project/src/styles.inline.css',
52
+ id: resolvedCssPath,
49
53
  })
50
54
 
55
+ const importerPath = resolve('/project/src/App.tsx')
51
56
  const result = await (plugin.resolveId as any).call(
52
57
  { resolve: mockResolve },
53
58
  './styles.inline.css',
54
- '/project/src/App.tsx'
59
+ importerPath
55
60
  )
56
61
 
57
- expect(mockResolve).toHaveBeenCalledWith(
58
- './styles.inline.css',
59
- '/project/src/App.tsx',
60
- { skipSelf: true }
61
- )
62
+ expect(mockResolve).toHaveBeenCalledWith('./styles.inline.css', importerPath, {
63
+ skipSelf: true,
64
+ })
62
65
 
63
- expect(result).toEqual({ id: '/project/src/styles.inline.css' })
66
+ expect(result).toEqual({ id: resolvedCssPath })
64
67
  })
65
68
 
66
69
  it('should track inline CSS source paths', async () => {
@@ -68,34 +71,37 @@ describe('criticalCSSPlugin', () => {
68
71
  await import('./criticalCSSPlugin')
69
72
  const plugin = criticalCSSPlugin()
70
73
 
71
- ;(plugin.configResolved as any)({ root: '/project' })
74
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
72
75
 
73
76
  const mockResolve = vi.fn().mockResolvedValue({
74
- id: '/project/src/layout.inline.css',
77
+ id: resolve('/project/src/layout.inline.css'),
75
78
  })
76
79
 
77
80
  await (plugin.resolveId as any).call(
78
81
  { resolve: mockResolve },
79
82
  './layout.inline.css',
80
- '/project/src/App.tsx'
83
+ resolve('/project/src/App.tsx')
81
84
  )
82
85
 
83
86
  const sources = getCriticalCSSSources()
84
- expect(sources.has('src/layout.inline.css')).toBe(true)
87
+ // relative() produces forward slashes on POSIX, backslashes on Windows
88
+ expect(
89
+ sources.has('src/layout.inline.css') || sources.has('src\\layout.inline.css')
90
+ ).toBe(true)
85
91
  })
86
92
 
87
93
  it('should return null when resolve fails', async () => {
88
94
  const { criticalCSSPlugin } = await import('./criticalCSSPlugin')
89
95
  const plugin = criticalCSSPlugin()
90
96
 
91
- ;(plugin.configResolved as any)({ root: '/project' })
97
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
92
98
 
93
99
  const mockResolve = vi.fn().mockResolvedValue(null)
94
100
 
95
101
  const result = await (plugin.resolveId as any).call(
96
102
  { resolve: mockResolve },
97
103
  './nonexistent.inline.css',
98
- '/project/src/App.tsx'
104
+ resolve('/project/src/App.tsx')
99
105
  )
100
106
 
101
107
  expect(result).toBeNull()
@@ -108,21 +114,25 @@ describe('criticalCSSPlugin', () => {
108
114
  await import('./criticalCSSPlugin')
109
115
  const plugin = criticalCSSPlugin()
110
116
 
111
- ;(plugin.configResolved as any)({ root: '/project' })
117
+ ;(plugin.configResolved as any)({ root: PROJECT_ROOT })
112
118
 
113
119
  const mockResolve = vi.fn().mockResolvedValue({
114
- id: '/project/app/layout.inline.css',
120
+ id: resolve('/project/app/layout.inline.css'),
115
121
  })
116
122
  await (plugin.resolveId as any).call(
117
123
  { resolve: mockResolve },
118
124
  './layout.inline.css',
119
- '/project/app/_layout.tsx'
125
+ resolve('/project/app/_layout.tsx')
120
126
  )
121
127
 
128
+ // Build a manifest keyed by the relative path that criticalCSSSources actually stores
129
+ const sources = getCriticalCSSSources()
130
+ const sourceKey = [...sources].find((s) => s.includes('layout.inline.css'))!
131
+
122
132
  const manifest = {
123
- 'app/layout.inline.css': {
133
+ [sourceKey]: {
124
134
  file: 'assets/layout-abc123.css',
125
- src: 'app/layout.inline.css',
135
+ src: sourceKey,
126
136
  },
127
137
  'app/_layout.tsx': {
128
138
  file: 'assets/layout-def456.js',
@@ -1,4 +1,5 @@
1
1
  import { relative } from 'node:path'
2
+ import { normalizePath } from 'vite'
2
3
  import type { Plugin } from 'vite'
3
4
 
4
5
  /**
@@ -62,8 +63,8 @@ export function criticalCSSPlugin(): Plugin {
62
63
  const resolved = await this.resolve(id, importer, { skipSelf: true })
63
64
 
64
65
  if (resolved) {
65
- // store as relative path to match manifest keys
66
- const relativePath = relative(root, resolved.id)
66
+ // store as relative path to match manifest keys (forward slashes to match Vite)
67
+ const relativePath = normalizePath(relative(root, resolved.id))
67
68
  criticalCSSSources.add(relativePath)
68
69
  return resolved
69
70
  }
@@ -1,5 +1,12 @@
1
+ import { resolve } from 'node:path'
1
2
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
3
 
4
+ // Platform-correct test paths — resolve() normalizes to native separators
5
+ const PROJECT_ROOT = resolve('/project')
6
+ const PUBLIC_DIR = resolve('/project/public')
7
+ const COMPONENTS_DIR = resolve('/project/src/components')
8
+ const HERO_FILE = resolve('/project/src/components/Hero.tsx')
9
+
3
10
  // Mock fs before importing the plugin
4
11
  vi.mock('node:fs', async () => {
5
12
  const actual = await vi.importActual('node:fs')
@@ -11,6 +18,13 @@ vi.mock('node:fs', async () => {
11
18
  }
12
19
  })
13
20
 
21
+ function mockConfig() {
22
+ return {
23
+ publicDir: PUBLIC_DIR,
24
+ root: PROJECT_ROOT,
25
+ }
26
+ }
27
+
14
28
  describe('imageDataPlugin', () => {
15
29
  beforeEach(() => {
16
30
  vi.resetModules()
@@ -25,13 +39,8 @@ describe('imageDataPlugin', () => {
25
39
  const { imageDataPlugin } = await import('./imageDataPlugin')
26
40
  const plugin = imageDataPlugin()
27
41
 
28
- const mockConfig = {
29
- publicDir: '/project/public',
30
- root: '/project',
31
- }
32
-
33
42
  if (plugin.configResolved) {
34
- ;(plugin.configResolved as any)(mockConfig)
43
+ ;(plugin.configResolved as any)(mockConfig())
35
44
  }
36
45
 
37
46
  const result = await (plugin.resolveId as any)('./image.jpg', undefined)
@@ -42,13 +51,8 @@ describe('imageDataPlugin', () => {
42
51
  const { imageDataPlugin } = await import('./imageDataPlugin')
43
52
  const plugin = imageDataPlugin()
44
53
 
45
- const mockConfig = {
46
- publicDir: '/project/public',
47
- root: '/project',
48
- }
49
-
50
54
  if (plugin.configResolved) {
51
- ;(plugin.configResolved as any)(mockConfig)
55
+ ;(plugin.configResolved as any)(mockConfig())
52
56
  }
53
57
 
54
58
  // ?imagedata in the middle should not match
@@ -60,53 +64,38 @@ describe('imageDataPlugin', () => {
60
64
  const { imageDataPlugin } = await import('./imageDataPlugin')
61
65
  const plugin = imageDataPlugin()
62
66
 
63
- const mockConfig = {
64
- publicDir: '/project/public',
65
- root: '/project',
66
- }
67
-
68
67
  if (plugin.configResolved) {
69
- ;(plugin.configResolved as any)(mockConfig)
68
+ ;(plugin.configResolved as any)(mockConfig())
70
69
  }
71
70
 
72
71
  const result = await (plugin.resolveId as any)(
73
72
  '/test-image.jpg?imagedata',
74
73
  undefined
75
74
  )
76
- expect(result).toBe('\0imagedata:/project/public/test-image.jpg')
75
+ expect(result).toBe('\0imagedata:' + resolve(PUBLIC_DIR, 'test-image.jpg'))
77
76
  })
78
77
 
79
78
  it('should resolve relative imports', async () => {
80
79
  const { imageDataPlugin } = await import('./imageDataPlugin')
81
80
  const plugin = imageDataPlugin()
82
81
 
83
- const mockConfig = {
84
- publicDir: '/project/public',
85
- root: '/project',
86
- }
87
-
88
82
  if (plugin.configResolved) {
89
- ;(plugin.configResolved as any)(mockConfig)
83
+ ;(plugin.configResolved as any)(mockConfig())
90
84
  }
91
85
 
92
86
  const result = await (plugin.resolveId as any)(
93
87
  './test-image.jpg?imagedata',
94
- '/project/src/components/Hero.tsx'
88
+ HERO_FILE
95
89
  )
96
- expect(result).toBe('\0imagedata:/project/src/components/test-image.jpg')
90
+ expect(result).toBe('\0imagedata:' + resolve(COMPONENTS_DIR, 'test-image.jpg'))
97
91
  })
98
92
 
99
93
  it('should return null for non-existent files', async () => {
100
94
  const { imageDataPlugin } = await import('./imageDataPlugin')
101
95
  const plugin = imageDataPlugin()
102
96
 
103
- const mockConfig = {
104
- publicDir: '/project/public',
105
- root: '/project',
106
- }
107
-
108
97
  if (plugin.configResolved) {
109
- ;(plugin.configResolved as any)(mockConfig)
98
+ ;(plugin.configResolved as any)(mockConfig())
110
99
  }
111
100
 
112
101
  const result = await (plugin.resolveId as any)(
@@ -122,13 +111,8 @@ describe('imageDataPlugin', () => {
122
111
  const { imageDataPlugin } = await import('./imageDataPlugin')
123
112
  const plugin = imageDataPlugin()
124
113
 
125
- const mockConfig = {
126
- publicDir: '/project/public',
127
- root: '/project',
128
- }
129
-
130
114
  if (plugin.configResolved) {
131
- ;(plugin.configResolved as any)(mockConfig)
115
+ ;(plugin.configResolved as any)(mockConfig())
132
116
  }
133
117
 
134
118
  const result = await (plugin.resolveId as any)(
@@ -142,18 +126,13 @@ describe('imageDataPlugin', () => {
142
126
  const { imageDataPlugin } = await import('./imageDataPlugin')
143
127
  const plugin = imageDataPlugin()
144
128
 
145
- const mockConfig = {
146
- publicDir: '/project/public',
147
- root: '/project',
148
- }
149
-
150
129
  if (plugin.configResolved) {
151
- ;(plugin.configResolved as any)(mockConfig)
130
+ ;(plugin.configResolved as any)(mockConfig())
152
131
  }
153
132
 
154
133
  const result = await (plugin.resolveId as any)(
155
134
  '../../../../etc/passwd?imagedata',
156
- '/project/src/components/Hero.tsx'
135
+ HERO_FILE
157
136
  )
158
137
  expect(result).toBeNull()
159
138
  })
@@ -162,13 +141,8 @@ describe('imageDataPlugin', () => {
162
141
  const { imageDataPlugin } = await import('./imageDataPlugin')
163
142
  const plugin = imageDataPlugin()
164
143
 
165
- const mockConfig = {
166
- publicDir: '/project/public',
167
- root: '/project',
168
- }
169
-
170
144
  if (plugin.configResolved) {
171
- ;(plugin.configResolved as any)(mockConfig)
145
+ ;(plugin.configResolved as any)(mockConfig())
172
146
  }
173
147
 
174
148
  const result = await (plugin.resolveId as any)(
@@ -182,22 +156,17 @@ describe('imageDataPlugin', () => {
182
156
  const { imageDataPlugin } = await import('./imageDataPlugin')
183
157
  const plugin = imageDataPlugin()
184
158
 
185
- const mockConfig = {
186
- publicDir: '/project/public',
187
- root: '/project',
188
- }
189
-
190
159
  if (plugin.configResolved) {
191
- ;(plugin.configResolved as any)(mockConfig)
160
+ ;(plugin.configResolved as any)(mockConfig())
192
161
  }
193
162
 
194
163
  // Going up and back down should still work if within bounds
195
164
  // From /project/src/components, ../.. goes to /project, then src/test-image.jpg
196
165
  const result = await (plugin.resolveId as any)(
197
166
  '../../src/test-image.jpg?imagedata',
198
- '/project/src/components/Hero.tsx'
167
+ HERO_FILE
199
168
  )
200
- expect(result).toBe('\0imagedata:/project/src/test-image.jpg')
169
+ expect(result).toBe('\0imagedata:' + resolve(PROJECT_ROOT, 'src/test-image.jpg'))
201
170
  })
202
171
  })
203
172
 
@@ -206,13 +175,8 @@ describe('imageDataPlugin', () => {
206
175
  const { imageDataPlugin } = await import('./imageDataPlugin')
207
176
  const plugin = imageDataPlugin()
208
177
 
209
- const mockConfig = {
210
- publicDir: '/project/public',
211
- root: '/project',
212
- }
213
-
214
178
  if (plugin.configResolved) {
215
- ;(plugin.configResolved as any)(mockConfig)
179
+ ;(plugin.configResolved as any)(mockConfig())
216
180
  }
217
181
 
218
182
  const mockContext = {
@@ -227,33 +191,28 @@ describe('imageDataPlugin', () => {
227
191
  const { imageDataPlugin } = await import('./imageDataPlugin')
228
192
  const plugin = imageDataPlugin()
229
193
 
230
- const mockConfig = {
231
- publicDir: '/project/public',
232
- root: '/project',
233
- }
234
-
235
194
  if (plugin.configResolved) {
236
- ;(plugin.configResolved as any)(mockConfig)
195
+ ;(plugin.configResolved as any)(mockConfig())
237
196
  }
238
197
 
239
198
  const mockContext = {
240
199
  addWatchFile: vi.fn(),
241
200
  }
242
201
 
202
+ const testFilePath = resolve(PUBLIC_DIR, 'test-image.jpg')
203
+
243
204
  // This will fail because the file doesn't actually exist
244
205
  // But it should gracefully fallback
245
206
  const result = await (plugin.load as any).call(
246
207
  mockContext,
247
- '\0imagedata:/project/public/test-image.jpg'
208
+ '\0imagedata:' + testFilePath
248
209
  )
249
210
 
250
211
  expect(result).toContain('export default')
251
212
  expect(result).toContain('"src":"/test-image.jpg"')
252
213
  expect(result).toContain('"width":')
253
214
  expect(result).toContain('"height":')
254
- expect(mockContext.addWatchFile).toHaveBeenCalledWith(
255
- '/project/public/test-image.jpg'
256
- )
215
+ expect(mockContext.addWatchFile).toHaveBeenCalledWith(testFilePath)
257
216
  })
258
217
  })
259
218
 
@@ -279,22 +238,19 @@ describe('imageDataPlugin output format', () => {
279
238
  const { imageDataPlugin } = await import('./imageDataPlugin')
280
239
  const plugin = imageDataPlugin()
281
240
 
282
- const mockConfig = {
283
- publicDir: '/project/public',
284
- root: '/project',
285
- }
286
-
287
241
  if (plugin.configResolved) {
288
- ;(plugin.configResolved as any)(mockConfig)
242
+ ;(plugin.configResolved as any)(mockConfig())
289
243
  }
290
244
 
291
245
  const mockContext = {
292
246
  addWatchFile: vi.fn(),
293
247
  }
294
248
 
249
+ const testFilePath = resolve(PUBLIC_DIR, 'test-image.jpg')
250
+
295
251
  const result = await (plugin.load as any).call(
296
252
  mockContext,
297
- '\0imagedata:/project/public/test-image.jpg'
253
+ '\0imagedata:' + testFilePath
298
254
  )
299
255
 
300
256
  // Extract JSON from the export
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from 'node:fs'
2
- import { dirname, relative, resolve } from 'node:path'
2
+ import { dirname, relative, resolve, sep } from 'node:path'
3
3
  import type { Plugin, ResolvedConfig } from 'vite'
4
+ import { normalizePath } from 'vite'
4
5
  import { processImageMeta } from '../../image/getImageData'
5
6
 
6
7
  const IMAGEDATA_SUFFIX = '?imagedata'
@@ -12,14 +13,14 @@ export function imageDataPlugin(): Plugin {
12
13
 
13
14
  function getSrcPath(filePath: string): string {
14
15
  return filePath.startsWith(publicDir)
15
- ? '/' + relative(publicDir, filePath)
16
- : '/' + relative(root, filePath)
16
+ ? '/' + normalizePath(relative(publicDir, filePath))
17
+ : '/' + normalizePath(relative(root, filePath))
17
18
  }
18
19
 
19
20
  function isPathWithinBounds(filePath: string, allowedDir: string): boolean {
20
21
  const resolved = resolve(filePath)
21
22
  const allowed = resolve(allowedDir)
22
- return resolved.startsWith(allowed + '/') || resolved === allowed
23
+ return resolved.startsWith(allowed + sep) || resolved === allowed
23
24
  }
24
25
 
25
26
  function createImageDataExport(src: string, width = 0, height = 0, blurDataURL = '') {
@@ -0,0 +1,40 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { getSourceInspectorPath, resolveEditorFilePath } from './sourceInspectorPlugin'
4
+
5
+ describe('sourceInspectorPlugin helpers', () => {
6
+ describe('getSourceInspectorPath', () => {
7
+ it('keeps project files relative to the current cwd', () => {
8
+ expect(getSourceInspectorPath('/repo/packages/one/src/App.tsx', '/repo')).toBe(
9
+ '/packages/one/src/App.tsx'
10
+ )
11
+ })
12
+
13
+ it('does not strip matching path prefixes from files outside cwd', () => {
14
+ expect(
15
+ getSourceInspectorPath('/repo-other/packages/one/src/App.tsx', '/repo')
16
+ ).toBe('/repo-other/packages/one/src/App.tsx')
17
+ })
18
+ })
19
+
20
+ describe('resolveEditorFilePath', () => {
21
+ it('resolves project-relative source paths against cwd', () => {
22
+ const fileExists = (filePath: string) =>
23
+ filePath === '/repo/packages/one/src/App.tsx'
24
+
25
+ expect(
26
+ resolveEditorFilePath('/packages/one/src/App.tsx', '/repo', fileExists)
27
+ ).toBe('/repo/packages/one/src/App.tsx')
28
+ })
29
+
30
+ it('preserves absolute source paths for files outside cwd', () => {
31
+ expect(
32
+ resolveEditorFilePath(
33
+ '/Users/n8/shared/ui/Button.tsx',
34
+ '/repo/apps/site',
35
+ () => false
36
+ )
37
+ ).toBe('/Users/n8/shared/ui/Button.tsx')
38
+ })
39
+ })
40
+ })
@@ -1,4 +1,5 @@
1
1
  import { spawn } from 'node:child_process'
2
+ import { existsSync } from 'node:fs'
2
3
  import path from 'node:path'
3
4
  import { parse } from 'oxc-parser'
4
5
  import type { Plugin, ViteDevServer } from 'vite'
@@ -91,6 +92,33 @@ async function findJsxElements(code: string, filename: string): Promise<JsxLocat
91
92
 
92
93
  type TransformOut = { code: string; map?: null } | undefined
93
94
 
95
+ export function getSourceInspectorPath(filePath: string, cwd = process.cwd()): string {
96
+ const normalizedFilePath = normalizePath(filePath)
97
+ const normalizedCwd = normalizePath(cwd)
98
+
99
+ if (normalizedFilePath === normalizedCwd) {
100
+ return '/'
101
+ }
102
+
103
+ if (normalizedFilePath.startsWith(`${normalizedCwd}/`)) {
104
+ return normalizedFilePath.slice(normalizedCwd.length)
105
+ }
106
+
107
+ return normalizedFilePath
108
+ }
109
+
110
+ export function resolveEditorFilePath(
111
+ filePath: string,
112
+ cwd = process.cwd(),
113
+ fileExists: (path: string) => boolean = existsSync
114
+ ): string {
115
+ const projectPath = path.join(cwd, filePath)
116
+
117
+ // data-one-source uses "/foo.tsx" for project-relative paths, but files outside
118
+ // cwd are stored as absolute paths and must not be re-joined onto cwd.
119
+ return fileExists(projectPath) ? projectPath : filePath
120
+ }
121
+
94
122
  /**
95
123
  * Transforms JSX to inject data-one-source attributes using oxc-parser.
96
124
  */
@@ -98,7 +126,7 @@ async function injectSourceToJsx(code: string, id: string): Promise<TransformOut
98
126
  const [filePath] = id.split('?')
99
127
  if (!filePath) return
100
128
 
101
- const location = filePath.replace(normalizePath(process.cwd()), '')
129
+ const location = getSourceInspectorPath(filePath)
102
130
 
103
131
  // Quick check - skip if no JSX-like content
104
132
  if (!code.includes('<') || !code.includes('>')) {
@@ -159,7 +187,7 @@ function openInEditor(
159
187
  return
160
188
  }
161
189
 
162
- const fullPath = path.join(process.cwd(), filePath)
190
+ const fullPath = resolveEditorFilePath(filePath)
163
191
  const l = line || '1'
164
192
  const c = column || '1'
165
193
  const buildArgs = editorArgs[resolved]
@@ -65,7 +65,9 @@ export function resolveAPIEndpoint(
65
65
  // this is the result of importing the file:
66
66
  runEndpoint: () => Promise<any>,
67
67
  request: Request,
68
- params: Record<string, string>
68
+ params: Record<string, string>,
69
+ env?: unknown,
70
+ executionCtx?: unknown
69
71
  ) {
70
72
  return resolveResponse(async () => {
71
73
  const imported = await runEndpoint()
@@ -75,7 +77,9 @@ export function resolveAPIEndpoint(
75
77
  console.warn(`No handler found for request ${requestType}`)
76
78
  return
77
79
  }
78
- return await handler(request, { params })
80
+ const worker =
81
+ env !== undefined || executionCtx !== undefined ? { env, executionCtx } : undefined
82
+ return await handler(request, { params, worker })
79
83
  })
80
84
  }
81
85
 
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAqSA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,iBA2qCA"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AA2SA,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,iBA8tCA"}
@@ -2,6 +2,15 @@ import type { One } from './vite/types';
2
2
  export declare const isWebClient: boolean;
3
3
  export declare const isWebServer: boolean;
4
4
  export declare const isNative: boolean;
5
+ /**
6
+ * True only in a browser main-thread context with a navigable history —
7
+ * i.e. `window` AND `window.history` are available. Excludes native,
8
+ * SSR, web workers / service workers (no `window`), and exotic sandboxed
9
+ * environments where `window` exists but history is stripped. Use this
10
+ * for guarding any `window.history` / `window.location` access so
11
+ * intercept routes, URL masking, etc. don't assume a full browser.
12
+ */
13
+ export declare const hasWebHistory: boolean;
5
14
  export declare const CACHE_KEY: string;
6
15
  export declare const LOADER_JS_POSTFIX_UNCACHED = "_vxrn_loader.js";
7
16
  export declare const LOADER_JS_POSTFIX_REGEX_STRING = "_\\d+_vxrn_loader.js$";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,eAAO,MAAM,WAAW,SACkD,CAAA;AAC1E,eAAO,MAAM,WAAW,SACkD,CAAA;AAC1E,eAAO,MAAM,QAAQ,SAA0C,CAAA;AAE/D,eAAO,MAAM,SAAS,QAA4E,CAAA;AAElG,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAC3D,eAAO,MAAM,8BAA8B,0BAAwC,CAAA;AACnF,eAAO,MAAM,uBAAuB,QAA6C,CAAA;AACjF,eAAO,MAAM,iBAAiB,QAA+C,CAAA;AAE7E,eAAO,MAAM,kBAAkB,QAA6B,CAAA;AAC5D,eAAO,MAAM,sBAAsB,QAAiC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAC1D,eAAO,MAAM,oBAAoB,oCAAyC,CAAA;AAE1E,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAE1D,eAAO,MAAM,oBAAoB,GAAI,qBAElC;IACD,aAAa,CAAC,EAAE,GAAG,CAAC,aAAa,CAAA;CAC7B,WAKL,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAEvC,eAAO,MAAM,WAAW,SACkD,CAAA;AAE1E,eAAO,MAAM,WAAW,SACkD,CAAA;AAE1E,eAAO,MAAM,QAAQ,SAA0C,CAAA;AAE/D;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,SAGc,CAAA;AAExC,eAAO,MAAM,SAAS,QAA4E,CAAA;AAElG,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAC3D,eAAO,MAAM,8BAA8B,0BAAwC,CAAA;AACnF,eAAO,MAAM,uBAAuB,QAA6C,CAAA;AACjF,eAAO,MAAM,iBAAiB,QAA+C,CAAA;AAE7E,eAAO,MAAM,kBAAkB,QAA6B,CAAA;AAC5D,eAAO,MAAM,sBAAsB,QAAiC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,wBAAwB,CAAA;AAC1D,eAAO,MAAM,oBAAoB,oCAAyC,CAAA;AAE1E,eAAO,MAAM,kBAAkB,2BAA2B,CAAA;AAE1D,eAAO,MAAM,oBAAoB,GAAI,qBAElC;IACD,aAAa,CAAC,EAAE,GAAG,CAAC,aAAa,CAAA;CAC7B,WAKL,CAAA"}
@@ -1,8 +1,31 @@
1
1
  import type { OneRouter } from './interfaces/router';
2
2
  type MaybePromise<T> = T | Promise<T>;
3
- type APIRouteHandler<Params extends Record<string, string> = Record<string, string>> = (request: Request, context: {
3
+ /**
4
+ * Minimal shape of the Cloudflare Workers `ExecutionContext`.
5
+ * Use `context.worker?.executionCtx?.waitUntil(promise)` from an API handler
6
+ * to keep the worker alive for fire-and-forget background work after the
7
+ * response has been sent.
8
+ */
9
+ export type WorkerExecutionContext = {
10
+ waitUntil: (promise: Promise<unknown>) => void;
11
+ passThroughOnException: () => void;
12
+ };
13
+ /** Cloudflare Workers `env` bindings. Shape is app-specific; `unknown` by default. */
14
+ export type WorkerEnv = Record<string, unknown>;
15
+ /**
16
+ * Worker-runtime context surfaced on API handlers when running under an edge
17
+ * runtime (Cloudflare Workers). Undefined in dev/Node.
18
+ */
19
+ export type WorkerContext = {
20
+ env?: WorkerEnv;
21
+ executionCtx?: WorkerExecutionContext;
22
+ };
23
+ export type APIRouteContext<Params extends Record<string, string> = Record<string, string>> = {
4
24
  params: Params;
5
- }) => MaybePromise<Response>;
25
+ /** Present on worker runtimes (Cloudflare Workers). Undefined in dev/Node. */
26
+ worker?: WorkerContext;
27
+ };
28
+ type APIRouteHandler<Params extends Record<string, string> = Record<string, string>> = (request: Request, context: APIRouteContext<Params>) => MaybePromise<Response>;
6
29
  /**
7
30
  * Type helper for API route handlers with typed params.
8
31
  *
@@ -11,8 +34,10 @@ type APIRouteHandler<Params extends Record<string, string> = Record<string, stri
11
34
  * // app/api/users/[id]+api.ts
12
35
  * import { createAPIRoute } from 'one'
13
36
  *
14
- * export const GET = createAPIRoute<'/api/users/[id]'>((request, { params }) => {
37
+ * export const GET = createAPIRoute<'/api/users/[id]'>((request, { params, worker }) => {
15
38
  * // params.id is typed as string
39
+ * // on cloudflare workers, worker.executionCtx.waitUntil() keeps background work alive
40
+ * worker?.executionCtx?.waitUntil(trackEvent(params.id))
16
41
  * return Response.json({ id: params.id })
17
42
  * })
18
43
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"createAPIRoute.d.ts","sourceRoot":"","sources":["../src/createAPIRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAEpD,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErC,KAAK,eAAe,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CACrF,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,KACxB,YAAY,CAAC,QAAQ,CAAC,CAAA;AAE3B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EACzD,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,wDAG9D;AAED,YAAY,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"createAPIRoute.d.ts","sourceRoot":"","sources":["../src/createAPIRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAEpD,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErC;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC9C,sBAAsB,EAAE,MAAM,IAAI,CAAA;CACnC,CAAA;AAED,sFAAsF;AACtF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE/C;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,YAAY,CAAC,EAAE,sBAAsB,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,eAAe,CACzB,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAC5D;IACF,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,MAAM,CAAC,EAAE,aAAa,CAAA;CACvB,CAAA;AAED,KAAK,eAAe,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CACrF,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,KAC7B,YAAY,CAAC,QAAQ,CAAC,CAAA;AAE3B;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM,EACzD,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,wDAG9D;AAED,YAAY,EAAE,eAAe,EAAE,CAAA"}