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.
- package/dist/cjs/cli/build.cjs +98 -58
- package/dist/cjs/cli/build.native.js +106 -63
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +3 -3
- package/dist/cjs/cli/buildPage.native.js +3 -3
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/constants.cjs +2 -0
- package/dist/cjs/constants.native.js +2 -0
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/createAPIRoute.native.js.map +1 -1
- package/dist/cjs/createApp.cjs +2 -6
- package/dist/cjs/createHandleRequest.cjs +2 -2
- package/dist/cjs/createHandleRequest.native.js +2 -2
- package/dist/cjs/createHandleRequest.native.js.map +1 -1
- package/dist/cjs/hooks.cjs +5 -1
- package/dist/cjs/hooks.native.js +7 -1
- package/dist/cjs/hooks.native.js.map +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/metro-config/getViteMetroPluginOptions.cjs +10 -7
- package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js +13 -10
- package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js.map +1 -1
- package/dist/cjs/metro-config/getViteMetroPluginOptions.test.cjs +23 -0
- package/dist/cjs/metro-config/getViteMetroPluginOptions.test.native.js +26 -0
- package/dist/cjs/metro-config/getViteMetroPluginOptions.test.native.js.map +1 -0
- package/dist/cjs/router/Route.cjs +21 -1
- package/dist/cjs/router/Route.native.js +22 -1
- package/dist/cjs/router/Route.native.js.map +1 -1
- package/dist/cjs/router/interceptRoutes.cjs +6 -6
- package/dist/cjs/router/interceptRoutes.native.js +6 -6
- package/dist/cjs/router/interceptRoutes.native.js.map +1 -1
- package/dist/cjs/router/params.cjs +46 -0
- package/dist/cjs/router/params.native.js +70 -0
- package/dist/cjs/router/params.native.js.map +1 -0
- package/dist/cjs/router/useScreens.cjs +3 -0
- package/dist/cjs/router/useScreens.native.js +2 -0
- package/dist/cjs/router/useScreens.native.js.map +1 -1
- package/dist/cjs/serve-worker.native.js.map +1 -1
- package/dist/cjs/server/getServerManifest.cjs +6 -6
- package/dist/cjs/server/getServerManifest.native.js +6 -6
- package/dist/cjs/server/getServerManifest.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +9 -5
- package/dist/cjs/server/oneServe.native.js +9 -5
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server/workerHandler.cjs +2 -2
- package/dist/cjs/server/workerHandler.native.js +2 -2
- package/dist/cjs/server/workerHandler.native.js.map +1 -1
- package/dist/cjs/skewProtection.cjs +48 -7
- package/dist/cjs/skewProtection.native.js +48 -7
- package/dist/cjs/skewProtection.native.js.map +1 -1
- package/dist/cjs/useLoader.cjs +67 -69
- package/dist/cjs/useLoader.native.js +113 -117
- package/dist/cjs/useLoader.native.js.map +1 -1
- package/dist/cjs/utils/dynamicImport.cjs +3 -1
- package/dist/cjs/utils/dynamicImport.native.js +22 -1
- package/dist/cjs/utils/dynamicImport.native.js.map +1 -1
- package/dist/cjs/utils/toAbsolute.cjs +5 -2
- package/dist/cjs/utils/toAbsolute.native.js +6 -1
- package/dist/cjs/utils/toAbsolute.native.js.map +1 -1
- package/dist/cjs/utils/workerImport.cjs +1 -1
- package/dist/cjs/utils/workerImport.native.js +1 -1
- package/dist/cjs/utils/workerImport.native.js.map +1 -1
- package/dist/cjs/views/RootErrorBoundary.cjs +114 -117
- package/dist/cjs/views/RootErrorBoundary.native.js +126 -146
- package/dist/cjs/views/RootErrorBoundary.native.js.map +1 -1
- package/dist/cjs/views/Try.cjs +17 -18
- package/dist/cjs/views/Try.native.js +28 -42
- package/dist/cjs/views/Try.native.js.map +1 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.cjs +2 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.native.js +2 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.test.cjs +26 -20
- package/dist/cjs/vite/plugins/criticalCSSPlugin.test.native.js +28 -20
- package/dist/cjs/vite/plugins/criticalCSSPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/imageDataPlugin.cjs +3 -2
- package/dist/cjs/vite/plugins/imageDataPlugin.native.js +3 -2
- package/dist/cjs/vite/plugins/imageDataPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/imageDataPlugin.test.cjs +34 -69
- package/dist/cjs/vite/plugins/imageDataPlugin.test.native.js +34 -69
- package/dist/cjs/vite/plugins/imageDataPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.cjs +20 -2
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js +23 -2
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.cjs +21 -0
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js +28 -0
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -0
- package/dist/cjs/vite/resolveResponse.cjs +7 -2
- package/dist/cjs/vite/resolveResponse.native.js +7 -2
- package/dist/cjs/vite/resolveResponse.native.js.map +1 -1
- package/dist/esm/cli/build.mjs +100 -60
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +108 -65
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +4 -4
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +4 -4
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/constants.mjs +2 -1
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +2 -1
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/createAPIRoute.mjs.map +1 -1
- package/dist/esm/createAPIRoute.native.js.map +1 -1
- package/dist/esm/createApp.mjs +2 -6
- package/dist/esm/createApp.mjs.map +1 -1
- package/dist/esm/createHandleRequest.mjs +2 -2
- package/dist/esm/createHandleRequest.mjs.map +1 -1
- package/dist/esm/createHandleRequest.native.js +2 -2
- package/dist/esm/createHandleRequest.native.js.map +1 -1
- package/dist/esm/hooks.mjs +5 -1
- package/dist/esm/hooks.mjs.map +1 -1
- package/dist/esm/hooks.native.js +7 -1
- package/dist/esm/hooks.native.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/metro-config/getViteMetroPluginOptions.mjs +9 -7
- package/dist/esm/metro-config/getViteMetroPluginOptions.mjs.map +1 -1
- package/dist/esm/metro-config/getViteMetroPluginOptions.native.js +12 -10
- package/dist/esm/metro-config/getViteMetroPluginOptions.native.js.map +1 -1
- package/dist/esm/metro-config/getViteMetroPluginOptions.test.mjs +24 -0
- package/dist/esm/metro-config/getViteMetroPluginOptions.test.mjs.map +1 -0
- package/dist/esm/metro-config/getViteMetroPluginOptions.test.native.js +24 -0
- package/dist/esm/metro-config/getViteMetroPluginOptions.test.native.js.map +1 -0
- package/dist/esm/router/Route.mjs +21 -1
- package/dist/esm/router/Route.mjs.map +1 -1
- package/dist/esm/router/Route.native.js +22 -1
- package/dist/esm/router/Route.native.js.map +1 -1
- package/dist/esm/router/interceptRoutes.mjs +7 -7
- package/dist/esm/router/interceptRoutes.mjs.map +1 -1
- package/dist/esm/router/interceptRoutes.native.js +7 -7
- package/dist/esm/router/interceptRoutes.native.js.map +1 -1
- package/dist/esm/router/params.mjs +21 -0
- package/dist/esm/router/params.mjs.map +1 -0
- package/dist/esm/router/params.native.js +42 -0
- package/dist/esm/router/params.native.js.map +1 -0
- package/dist/esm/router/useScreens.mjs +3 -0
- package/dist/esm/router/useScreens.mjs.map +1 -1
- package/dist/esm/router/useScreens.native.js +2 -0
- package/dist/esm/router/useScreens.native.js.map +1 -1
- package/dist/esm/serve-worker.mjs.map +1 -1
- package/dist/esm/serve-worker.native.js.map +1 -1
- package/dist/esm/server/getServerManifest.mjs +6 -6
- package/dist/esm/server/getServerManifest.mjs.map +1 -1
- package/dist/esm/server/getServerManifest.native.js +6 -6
- package/dist/esm/server/getServerManifest.native.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +11 -7
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +11 -7
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/server/workerHandler.mjs +2 -2
- package/dist/esm/server/workerHandler.mjs.map +1 -1
- package/dist/esm/server/workerHandler.native.js +2 -2
- package/dist/esm/server/workerHandler.native.js.map +1 -1
- package/dist/esm/skewProtection.mjs +48 -8
- package/dist/esm/skewProtection.mjs.map +1 -1
- package/dist/esm/skewProtection.native.js +48 -8
- package/dist/esm/skewProtection.native.js.map +1 -1
- package/dist/esm/useLoader.mjs +64 -66
- package/dist/esm/useLoader.mjs.map +1 -1
- package/dist/esm/useLoader.native.js +112 -116
- package/dist/esm/useLoader.native.js.map +1 -1
- package/dist/esm/utils/dynamicImport.mjs +1 -1
- package/dist/esm/utils/dynamicImport.mjs.map +1 -1
- package/dist/esm/utils/dynamicImport.native.js +20 -1
- package/dist/esm/utils/dynamicImport.native.js.map +1 -1
- package/dist/esm/utils/toAbsolute.mjs +3 -1
- package/dist/esm/utils/toAbsolute.mjs.map +1 -1
- package/dist/esm/utils/toAbsolute.native.js +5 -1
- package/dist/esm/utils/toAbsolute.native.js.map +1 -1
- package/dist/esm/utils/workerImport.mjs +2 -2
- package/dist/esm/utils/workerImport.mjs.map +1 -1
- package/dist/esm/utils/workerImport.native.js +2 -2
- package/dist/esm/utils/workerImport.native.js.map +1 -1
- package/dist/esm/views/RootErrorBoundary.mjs +114 -117
- package/dist/esm/views/RootErrorBoundary.mjs.map +1 -1
- package/dist/esm/views/RootErrorBoundary.native.js +126 -146
- package/dist/esm/views/RootErrorBoundary.native.js.map +1 -1
- package/dist/esm/views/Try.mjs +17 -18
- package/dist/esm/views/Try.mjs.map +1 -1
- package/dist/esm/views/Try.native.js +28 -42
- package/dist/esm/views/Try.native.js.map +1 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.mjs +2 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.native.js +2 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.test.mjs +26 -20
- package/dist/esm/vite/plugins/criticalCSSPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/criticalCSSPlugin.test.native.js +28 -20
- package/dist/esm/vite/plugins/criticalCSSPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/imageDataPlugin.mjs +4 -3
- package/dist/esm/vite/plugins/imageDataPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/imageDataPlugin.native.js +4 -3
- package/dist/esm/vite/plugins/imageDataPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/imageDataPlugin.test.mjs +34 -69
- package/dist/esm/vite/plugins/imageDataPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/imageDataPlugin.test.native.js +34 -69
- package/dist/esm/vite/plugins/imageDataPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs +19 -3
- package/dist/esm/vite/plugins/sourceInspectorPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js +22 -3
- package/dist/esm/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs +22 -0
- package/dist/esm/vite/plugins/sourceInspectorPlugin.test.mjs.map +1 -0
- package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js +26 -0
- package/dist/esm/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -0
- package/dist/esm/vite/resolveResponse.mjs +7 -2
- package/dist/esm/vite/resolveResponse.mjs.map +1 -1
- package/dist/esm/vite/resolveResponse.native.js +7 -2
- package/dist/esm/vite/resolveResponse.native.js.map +1 -1
- package/expo-plugin.cjs +1 -0
- package/package.json +15 -10
- package/react-native-commands.cjs +1 -0
- package/src/cli/build.ts +156 -99
- package/src/cli/buildPage.ts +4 -4
- package/src/constants.ts +15 -0
- package/src/createAPIRoute.ts +35 -2
- package/src/createApp.tsx +2 -6
- package/src/createHandleRequest.ts +6 -2
- package/src/hooks.tsx +9 -1
- package/src/index.ts +8 -1
- package/src/metro-config/getViteMetroPluginOptions.test.ts +34 -0
- package/src/metro-config/getViteMetroPluginOptions.ts +14 -11
- package/src/router/Route.tsx +52 -2
- package/src/router/interceptRoutes.ts +7 -7
- package/src/router/params.ts +32 -0
- package/src/router/useScreens.tsx +18 -0
- package/src/serve-worker.ts +4 -2
- package/src/server/getServerManifest.ts +11 -7
- package/src/server/oneServe.ts +12 -14
- package/src/server/workerHandler.ts +13 -2
- package/src/skewProtection.ts +45 -5
- package/src/useLoader.ts +6 -4
- package/src/utils/dynamicImport.ts +2 -2
- package/src/utils/toAbsolute.ts +5 -0
- package/src/utils/workerImport.ts +2 -2
- package/src/views/RootErrorBoundary.tsx +18 -0
- package/src/views/Try.tsx +18 -0
- package/src/vite/plugins/criticalCSSPlugin.test.ts +34 -24
- package/src/vite/plugins/criticalCSSPlugin.ts +3 -2
- package/src/vite/plugins/imageDataPlugin.test.ts +39 -83
- package/src/vite/plugins/imageDataPlugin.ts +5 -4
- package/src/vite/plugins/sourceInspectorPlugin.test.ts +40 -0
- package/src/vite/plugins/sourceInspectorPlugin.ts +30 -2
- package/src/vite/resolveResponse.ts +6 -2
- package/types/cli/build.d.ts.map +1 -1
- package/types/constants.d.ts +9 -0
- package/types/constants.d.ts.map +1 -1
- package/types/createAPIRoute.d.ts +28 -3
- package/types/createAPIRoute.d.ts.map +1 -1
- package/types/createApp.d.ts.map +1 -1
- package/types/createHandleRequest.d.ts +1 -1
- package/types/createHandleRequest.d.ts.map +1 -1
- package/types/headless-server.d.ts +1 -1
- package/types/hooks.d.ts.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/metro-config/getViteMetroPluginOptions.d.ts +5 -0
- package/types/metro-config/getViteMetroPluginOptions.d.ts.map +1 -1
- package/types/metro-config/getViteMetroPluginOptions.test.d.ts +2 -0
- package/types/metro-config/getViteMetroPluginOptions.test.d.ts.map +1 -0
- package/types/router/Route.d.ts +1 -0
- package/types/router/Route.d.ts.map +1 -1
- package/types/router/params.d.ts +3 -0
- package/types/router/params.d.ts.map +1 -0
- package/types/router/useScreens.d.ts.map +1 -1
- package/types/serve-worker.d.ts +5 -3
- package/types/serve-worker.d.ts.map +1 -1
- package/types/server/getServerManifest.d.ts.map +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/server/workerHandler.d.ts +1 -1
- package/types/server/workerHandler.d.ts.map +1 -1
- package/types/skewProtection.d.ts +1 -0
- package/types/skewProtection.d.ts.map +1 -1
- package/types/useLoader.d.ts.map +1 -1
- package/types/utils/dynamicImport.d.ts +2 -0
- package/types/utils/dynamicImport.d.ts.map +1 -1
- package/types/utils/toAbsolute.d.ts +3 -0
- package/types/utils/toAbsolute.d.ts.map +1 -1
- package/types/views/RootErrorBoundary.d.ts.map +1 -1
- package/types/views/Try.d.ts.map +1 -1
- package/types/vite/plugins/criticalCSSPlugin.d.ts.map +1 -1
- package/types/vite/plugins/imageDataPlugin.d.ts.map +1 -1
- package/types/vite/plugins/sourceInspectorPlugin.d.ts +2 -0
- package/types/vite/plugins/sourceInspectorPlugin.d.ts.map +1 -1
- package/types/vite/plugins/sourceInspectorPlugin.test.d.ts +2 -0
- package/types/vite/plugins/sourceInspectorPlugin.test.d.ts.map +1 -0
- package/types/vite/resolveResponse.d.ts +1 -1
- package/types/vite/resolveResponse.d.ts.map +1 -1
package/src/cli/build.ts
CHANGED
|
@@ -5,7 +5,13 @@ import { resolvePath } from '@vxrn/resolve'
|
|
|
5
5
|
import FSExtra from 'fs-extra'
|
|
6
6
|
import MicroMatch from 'micromatch'
|
|
7
7
|
import type { OutputAsset, RolldownOutput } from 'rolldown'
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createBuilder,
|
|
10
|
+
type InlineConfig,
|
|
11
|
+
mergeConfig,
|
|
12
|
+
normalizePath,
|
|
13
|
+
build as viteBuild,
|
|
14
|
+
} from 'vite'
|
|
9
15
|
import {
|
|
10
16
|
type ClientManifestEntry,
|
|
11
17
|
fillOptions,
|
|
@@ -19,7 +25,7 @@ import { setServerGlobals } from '../server/setServerGlobals'
|
|
|
19
25
|
import { getPathnameFromFilePath } from '../utils/getPathnameFromFilePath'
|
|
20
26
|
import { getRouterRootFromOneOptions } from '../utils/getRouterRootFromOneOptions'
|
|
21
27
|
import { isRolldown } from '../utils/isRolldown'
|
|
22
|
-
import { toAbsolute } from '../utils/toAbsolute'
|
|
28
|
+
import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
|
|
23
29
|
import { buildVercelOutputDirectory } from '../vercel/build/buildVercelOutputDirectory'
|
|
24
30
|
import { getManifest } from '../vite/getManifest'
|
|
25
31
|
import { loadUserOneOptions } from '../vite/loadConfig'
|
|
@@ -380,24 +386,59 @@ export async function build(args: {
|
|
|
380
386
|
const { optimizeDeps } = getOptimizeDeps('build')
|
|
381
387
|
const { rolldownOptions: _rolldownOptions, ...optimizeDepsNoRolldown } = optimizeDeps
|
|
382
388
|
|
|
389
|
+
// unified mode: api + middleware routes share config with the SSR server build —
|
|
390
|
+
// same defines, plugins, externalization rules, no blanket noExternal: true.
|
|
391
|
+
// when off, keep the legacy path that derives from webBuildConfig with
|
|
392
|
+
// ssr.noExternal: true hard-coded (back-compat).
|
|
393
|
+
const serverOpts = oneOptions.build?.server
|
|
394
|
+
const isUnified =
|
|
395
|
+
typeof serverOpts === 'object' && serverOpts !== null && serverOpts.unified === true
|
|
396
|
+
|
|
383
397
|
// clone plugin hooks so vite's wrapHookObject doesn't fail on reuse across builds
|
|
384
398
|
// (vite defines non-configurable getters on hook objects during the first build)
|
|
385
|
-
|
|
399
|
+
let baseForApi = isUnified
|
|
400
|
+
? clonePluginHooks(vxrnOutput.serverBuildConfig ?? vxrnOutput.webBuildConfig)
|
|
401
|
+
: clonePluginHooks(vxrnOutput.webBuildConfig)
|
|
402
|
+
|
|
403
|
+
if (isUnified) {
|
|
404
|
+
// serverBuildConfig has rolldownOptions.input: ['virtual:one-entry'] —
|
|
405
|
+
// vite mergeConfig concatenates that with the api build's input object,
|
|
406
|
+
// which rolldown then tries to iterate as a string list. strip it so the
|
|
407
|
+
// per-routes input map in buildCustomRoutes takes effect cleanly.
|
|
408
|
+
//
|
|
409
|
+
// also strip `omit-api-routes`, the server's transform plugin that empties
|
|
410
|
+
// any +api / _middleware file. correct for the SSR render bundle, wrong
|
|
411
|
+
// for api/middleware builds where those files ARE the entry points.
|
|
412
|
+
const clone: InlineConfig = {
|
|
413
|
+
...baseForApi,
|
|
414
|
+
build: baseForApi.build ? { ...baseForApi.build } : undefined,
|
|
415
|
+
plugins: baseForApi.plugins
|
|
416
|
+
? (baseForApi.plugins as any[]).filter(
|
|
417
|
+
(p) => p && typeof p === 'object' && p.name !== 'omit-api-routes'
|
|
418
|
+
)
|
|
419
|
+
: undefined,
|
|
420
|
+
}
|
|
421
|
+
if (clone.build && (clone.build as any).rolldownOptions) {
|
|
422
|
+
const ro = { ...((clone.build as any).rolldownOptions as any) }
|
|
423
|
+
delete ro.input
|
|
424
|
+
;(clone.build as any).rolldownOptions = ro
|
|
425
|
+
}
|
|
426
|
+
if (clone.build) {
|
|
427
|
+
delete (clone.build as any).outDir
|
|
428
|
+
}
|
|
429
|
+
baseForApi = clone
|
|
430
|
+
}
|
|
386
431
|
|
|
387
|
-
const apiBuildConfig = mergeConfig(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
environments: {
|
|
395
|
-
client: {
|
|
396
|
-
optimizeDeps: { rolldownOptions: _rolldownOptions },
|
|
397
|
-
},
|
|
432
|
+
const apiBuildConfig = mergeConfig(baseForApi, {
|
|
433
|
+
configFile: false,
|
|
434
|
+
appType: 'custom',
|
|
435
|
+
optimizeDeps: optimizeDepsNoRolldown,
|
|
436
|
+
environments: {
|
|
437
|
+
client: {
|
|
438
|
+
optimizeDeps: { rolldownOptions: _rolldownOptions },
|
|
398
439
|
},
|
|
399
|
-
}
|
|
400
|
-
)
|
|
440
|
+
},
|
|
441
|
+
} satisfies InlineConfig)
|
|
401
442
|
|
|
402
443
|
async function buildCustomRoutes(subFolder: string, routes: RouteInfo<string>[]) {
|
|
403
444
|
const input = routes.reduce((entries, { page, file }) => {
|
|
@@ -413,19 +454,20 @@ export async function build(args: {
|
|
|
413
454
|
appType: 'custom',
|
|
414
455
|
configFile: false,
|
|
415
456
|
|
|
416
|
-
// plugins: [
|
|
417
|
-
// nodeExternals({
|
|
418
|
-
// exclude: optimizeDeps.include,
|
|
419
|
-
// }) as any,
|
|
420
|
-
// ],
|
|
421
|
-
|
|
422
457
|
define: vxrnOutput!.processEnvDefines,
|
|
423
458
|
|
|
424
|
-
ssr:
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
459
|
+
ssr: isUnified
|
|
460
|
+
? {
|
|
461
|
+
// in unified mode let the base (serverBuildConfig) set ssr.noExternal
|
|
462
|
+
// — default is now ['react', 'react-dom'] instead of `true`, so
|
|
463
|
+
// rolldown can externalize the rest.
|
|
464
|
+
optimizeDeps: optimizeDepsNoRolldown,
|
|
465
|
+
}
|
|
466
|
+
: {
|
|
467
|
+
noExternal: true,
|
|
468
|
+
external: ['react', 'react-dom'],
|
|
469
|
+
optimizeDeps: optimizeDepsNoRolldown,
|
|
470
|
+
},
|
|
429
471
|
|
|
430
472
|
environments: {
|
|
431
473
|
ssr: {
|
|
@@ -456,7 +498,10 @@ export async function build(args: {
|
|
|
456
498
|
// prevents it from shaking out the exports
|
|
457
499
|
preserveEntrySignatures: 'strict',
|
|
458
500
|
input: input,
|
|
459
|
-
|
|
501
|
+
// in unified mode, inherit externals from serverBuildConfig (user
|
|
502
|
+
// ssr.external / rolldownOptions.external). the legacy path resets
|
|
503
|
+
// them to [] so per-route files bundle everything.
|
|
504
|
+
...(isUnified ? {} : { external: [] }),
|
|
460
505
|
output: {
|
|
461
506
|
entryFileNames: '[name]',
|
|
462
507
|
exports: 'auto',
|
|
@@ -528,7 +573,7 @@ export async function build(args: {
|
|
|
528
573
|
if (middlewareBuildInfo) {
|
|
529
574
|
for (const middleware of manifest.middlewareRoutes) {
|
|
530
575
|
const absoluteRoot = resolve(process.cwd(), options.root)
|
|
531
|
-
const fullPath = join(absoluteRoot, routerRoot, middleware.file)
|
|
576
|
+
const fullPath = normalizePath(join(absoluteRoot, routerRoot, middleware.file))
|
|
532
577
|
const outChunks = middlewareBuildInfo.output.filter((x) => x.type === 'chunk')
|
|
533
578
|
const chunk = outChunks.find((x) => x.facadeModuleId === fullPath)
|
|
534
579
|
if (!chunk) throw new Error(`internal err finding middleware`)
|
|
@@ -537,7 +582,7 @@ export async function build(args: {
|
|
|
537
582
|
}
|
|
538
583
|
|
|
539
584
|
// for the require Sitemap in getRoutes
|
|
540
|
-
globalThis['require'] = createRequire(
|
|
585
|
+
globalThis['require'] = createRequire(import.meta.dirname + '/')
|
|
541
586
|
|
|
542
587
|
const assets: OutputAsset[] = []
|
|
543
588
|
|
|
@@ -607,7 +652,10 @@ export async function build(args: {
|
|
|
607
652
|
// layout files start with _layout
|
|
608
653
|
if (file.startsWith('_layout') && id.includes(`/${routerRoot}/`)) {
|
|
609
654
|
// contextKey format is "./_layout.tsx" or "./subdir/_layout.tsx"
|
|
610
|
-
const relativePath = relative(process.cwd(), id).replace(
|
|
655
|
+
const relativePath = normalizePath(relative(process.cwd(), id)).replace(
|
|
656
|
+
`${routerRoot}/`,
|
|
657
|
+
''
|
|
658
|
+
)
|
|
611
659
|
const contextKey = `./${relativePath}`
|
|
612
660
|
layoutServerPaths.set(contextKey, output.fileName)
|
|
613
661
|
}
|
|
@@ -650,10 +698,8 @@ export async function build(args: {
|
|
|
650
698
|
}
|
|
651
699
|
|
|
652
700
|
// resolve the full module path for this route
|
|
653
|
-
const routeModulePath =
|
|
654
|
-
resolve(process.cwd(), options.root),
|
|
655
|
-
routerRoot,
|
|
656
|
-
foundRoute.file.slice(2)
|
|
701
|
+
const routeModulePath = normalizePath(
|
|
702
|
+
join(resolve(process.cwd(), options.root), routerRoot, foundRoute.file.slice(2))
|
|
657
703
|
)
|
|
658
704
|
|
|
659
705
|
// find the server chunk containing this route
|
|
@@ -942,7 +988,7 @@ export async function build(args: {
|
|
|
942
988
|
|
|
943
989
|
let exported
|
|
944
990
|
try {
|
|
945
|
-
exported = await import(
|
|
991
|
+
exported = await import(toAbsoluteUrl(serverJsPath))
|
|
946
992
|
} catch (err) {
|
|
947
993
|
console.error(`Error importing page (original error)`, err)
|
|
948
994
|
// err cause not showing in vite or something
|
|
@@ -1152,11 +1198,22 @@ export async function build(args: {
|
|
|
1152
1198
|
}))
|
|
1153
1199
|
}
|
|
1154
1200
|
|
|
1155
|
-
// swap out for the built middleware path
|
|
1201
|
+
// swap out for the built middleware path.
|
|
1202
|
+
// page routes have compiled middleware paths attached via buildPage
|
|
1203
|
+
// (buildInfo.middlewares). api routes don't go through buildPage, so fall
|
|
1204
|
+
// back to the builtMiddlewares map keyed by the middleware source file.
|
|
1156
1205
|
const buildInfo = builtRoutes.find((x) => x.routeFile === route.file)
|
|
1157
|
-
if (built.middlewares
|
|
1206
|
+
if (built.middlewares) {
|
|
1158
1207
|
for (const [index, mw] of built.middlewares.entries()) {
|
|
1159
|
-
|
|
1208
|
+
const viaBuildInfo = buildInfo?.middlewares?.[index]
|
|
1209
|
+
if (viaBuildInfo) {
|
|
1210
|
+
mw.contextKey = viaBuildInfo
|
|
1211
|
+
continue
|
|
1212
|
+
}
|
|
1213
|
+
const viaMiddlewareMap = builtMiddlewares[mw.contextKey]
|
|
1214
|
+
if (viaMiddlewareMap) {
|
|
1215
|
+
mw.contextKey = viaMiddlewareMap
|
|
1216
|
+
}
|
|
1160
1217
|
}
|
|
1161
1218
|
}
|
|
1162
1219
|
|
|
@@ -1244,7 +1301,14 @@ export async function build(args: {
|
|
|
1244
1301
|
|
|
1245
1302
|
case 'cloudflare': {
|
|
1246
1303
|
// Generate lazy import functions - modules load on-demand, not all upfront
|
|
1247
|
-
//
|
|
1304
|
+
// The worker config keeps route modules separate so they can stay lazy.
|
|
1305
|
+
const workerSrcDir = join(options.root, outDir)
|
|
1306
|
+
const getWorkerSourceImportPath = (routeFile: string) => {
|
|
1307
|
+
const importPath = normalizePath(
|
|
1308
|
+
relative(workerSrcDir, join(options.root, routerRoot, routeFile))
|
|
1309
|
+
)
|
|
1310
|
+
return importPath.startsWith('.') ? importPath : `./${importPath}`
|
|
1311
|
+
}
|
|
1248
1312
|
const pageRouteMap: string[] = []
|
|
1249
1313
|
const apiRouteMap: string[] = []
|
|
1250
1314
|
const middlewareRouteMap: string[] = []
|
|
@@ -1263,19 +1327,18 @@ export async function build(args: {
|
|
|
1263
1327
|
// Generate lazy imports for API routes
|
|
1264
1328
|
for (const route of buildInfoForWriting.manifest.apiRoutes) {
|
|
1265
1329
|
if (route.file) {
|
|
1266
|
-
// API
|
|
1267
|
-
//
|
|
1268
|
-
|
|
1269
|
-
const apiFileName = route.page.slice(1).replace(/\[/g, '_').replace(/\]/g, '_')
|
|
1270
|
-
const importPath = `./api/${apiFileName}.js`
|
|
1330
|
+
// Import API routes from source so the Cloudflare plugin can apply its
|
|
1331
|
+
// own unenv/CJS transforms instead of re-bundling pre-built chunks.
|
|
1332
|
+
const importPath = getWorkerSourceImportPath(route.file)
|
|
1271
1333
|
apiRouteMap.push(` '${route.page}': () => import('${importPath}')`)
|
|
1272
1334
|
}
|
|
1273
1335
|
}
|
|
1274
1336
|
|
|
1275
1337
|
// Generate lazy imports for middlewares
|
|
1276
|
-
//
|
|
1277
|
-
|
|
1278
|
-
|
|
1338
|
+
// Keep the built output path as the lookup key, but import the source
|
|
1339
|
+
// file so the plugin owns the middleware dependency graph too.
|
|
1340
|
+
for (const [sourceFile, builtPath] of Object.entries(builtMiddlewares)) {
|
|
1341
|
+
const importPath = getWorkerSourceImportPath(sourceFile)
|
|
1279
1342
|
middlewareRouteMap.push(` '${builtPath}': () => import('${importPath}')`)
|
|
1280
1343
|
}
|
|
1281
1344
|
|
|
@@ -1334,7 +1397,7 @@ export default {
|
|
|
1334
1397
|
}
|
|
1335
1398
|
|
|
1336
1399
|
try {
|
|
1337
|
-
const response = await server.fetch(request)
|
|
1400
|
+
const response = await server.fetch(request, env, ctx)
|
|
1338
1401
|
|
|
1339
1402
|
// no route matched or 404 → try static assets
|
|
1340
1403
|
if (!response || response.status === 404) {
|
|
@@ -1359,45 +1422,41 @@ export default {
|
|
|
1359
1422
|
`
|
|
1360
1423
|
await FSExtra.writeFile(workerSrcPath, workerCode)
|
|
1361
1424
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1425
|
+
const projectName = await getCloudflareProjectName(options.root)
|
|
1426
|
+
const userWranglerConfig = await loadUserWranglerConfig(options.root)
|
|
1427
|
+
const wranglerInputConfig = createCloudflareWranglerConfig(
|
|
1428
|
+
projectName,
|
|
1429
|
+
userWranglerConfig?.config
|
|
1430
|
+
)
|
|
1431
|
+
wranglerInputConfig.main = relative(join(options.root, outDir), workerSrcPath)
|
|
1432
|
+
|
|
1433
|
+
const wranglerInputPath = join(options.root, outDir, '_wrangler.input.jsonc')
|
|
1434
|
+
await FSExtra.writeFile(
|
|
1435
|
+
wranglerInputPath,
|
|
1436
|
+
`${JSON.stringify(wranglerInputConfig, null, 2)}\n`
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
// Bundle the worker using Cloudflare's Vite plugin so we pick up unenv
|
|
1440
|
+
// polyfills and esmExternalRequirePlugin for Node-first CJS deps.
|
|
1364
1441
|
console.info('\n [cloudflare] Bundling worker...')
|
|
1365
|
-
await
|
|
1442
|
+
const { cloudflare } = await import('@cloudflare/vite-plugin')
|
|
1443
|
+
const builder = await createBuilder({
|
|
1366
1444
|
root: options.root,
|
|
1367
1445
|
mode: 'production',
|
|
1368
1446
|
logLevel: 'warn',
|
|
1369
|
-
|
|
1370
|
-
outDir,
|
|
1371
|
-
emptyOutDir: false,
|
|
1372
|
-
// Use SSR mode with node target for proper Node.js module resolution
|
|
1373
|
-
ssr: workerSrcPath,
|
|
1374
|
-
rolldownOptions: {
|
|
1375
|
-
external: [
|
|
1376
|
-
// React Native dev tools - not needed in production
|
|
1377
|
-
'@react-native/dev-middleware',
|
|
1378
|
-
'@react-native/debugger-shell',
|
|
1379
|
-
'metro',
|
|
1380
|
-
'metro-core',
|
|
1381
|
-
'metro-runtime',
|
|
1382
|
-
// Native modules that can't run in workers
|
|
1383
|
-
/\.node$/,
|
|
1384
|
-
],
|
|
1385
|
-
output: {
|
|
1386
|
-
entryFileNames: 'worker.js',
|
|
1387
|
-
format: 'es',
|
|
1388
|
-
// Keep dynamic imports separate for lazy loading
|
|
1389
|
-
inlineDynamicImports: false,
|
|
1390
|
-
},
|
|
1391
|
-
},
|
|
1392
|
-
minify: true,
|
|
1393
|
-
target: 'esnext',
|
|
1394
|
-
},
|
|
1447
|
+
configFile: false,
|
|
1395
1448
|
define: {
|
|
1396
1449
|
'process.env.NODE_ENV': JSON.stringify('production'),
|
|
1397
1450
|
'process.env.VITE_ENVIRONMENT': JSON.stringify('ssr'),
|
|
1451
|
+
'process.env.ONE_CACHE_KEY': JSON.stringify(constants.CACHE_KEY),
|
|
1398
1452
|
},
|
|
1453
|
+
plugins: [
|
|
1454
|
+
cloudflare({
|
|
1455
|
+
configPath: wranglerInputPath,
|
|
1456
|
+
viteEnvironment: { name: 'worker' },
|
|
1457
|
+
}),
|
|
1458
|
+
],
|
|
1399
1459
|
resolve: {
|
|
1400
|
-
conditions: ['workerd', 'worker', 'node', 'module', 'default'],
|
|
1401
1460
|
alias: [
|
|
1402
1461
|
// rolldown can't parse react-native's Flow syntax; alias to react-native-web for ssr
|
|
1403
1462
|
{
|
|
@@ -1418,37 +1477,35 @@ export default {
|
|
|
1418
1477
|
},
|
|
1419
1478
|
],
|
|
1420
1479
|
},
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1480
|
+
build: {
|
|
1481
|
+
outDir,
|
|
1482
|
+
emptyOutDir: false,
|
|
1483
|
+
rolldownOptions: {
|
|
1484
|
+
// Match the main web build behavior so RN packages that import
|
|
1485
|
+
// native-only symbols from react-native can still bundle against
|
|
1486
|
+
// the react-native-web alias in the worker graph.
|
|
1487
|
+
shimMissingExports: true,
|
|
1488
|
+
},
|
|
1424
1489
|
},
|
|
1425
1490
|
})
|
|
1491
|
+
const workerEnv = builder.environments.worker
|
|
1492
|
+
if (!workerEnv) {
|
|
1493
|
+
throw new Error('[one] plugin did not register "worker" environment')
|
|
1494
|
+
}
|
|
1495
|
+
await builder.build(workerEnv)
|
|
1426
1496
|
|
|
1427
1497
|
// Clean up temp file
|
|
1428
1498
|
await FSExtra.remove(workerSrcPath)
|
|
1429
|
-
|
|
1430
|
-
// Use jsonc for wrangler config (recommended for new projects)
|
|
1431
|
-
// Use assets with run_worker_first so all requests go through worker (enables middleware on SSG pages)
|
|
1432
|
-
const projectName = await getCloudflareProjectName(options.root)
|
|
1433
|
-
const userWranglerConfig = await loadUserWranglerConfig(options.root)
|
|
1434
|
-
const wranglerConfig = createCloudflareWranglerConfig(
|
|
1435
|
-
projectName,
|
|
1436
|
-
userWranglerConfig?.config
|
|
1437
|
-
)
|
|
1499
|
+
await FSExtra.remove(wranglerInputPath)
|
|
1438
1500
|
|
|
1439
1501
|
if (userWranglerConfig) {
|
|
1440
1502
|
console.info(
|
|
1441
|
-
` [cloudflare] Merging ${relative(options.root, userWranglerConfig.path)} into ${outDir}/wrangler.
|
|
1503
|
+
` [cloudflare] Merging ${relative(options.root, userWranglerConfig.path)} into ${outDir}/worker/wrangler.json`
|
|
1442
1504
|
)
|
|
1443
1505
|
}
|
|
1444
1506
|
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
`${JSON.stringify(wranglerConfig, null, 2)}\n`
|
|
1448
|
-
)
|
|
1449
|
-
|
|
1450
|
-
postBuildLogs.push(`Cloudflare worker bundled at ${outDir}/worker.js`)
|
|
1451
|
-
postBuildLogs.push(`To deploy: cd ${outDir} && wrangler deploy`)
|
|
1507
|
+
postBuildLogs.push(`Cloudflare worker bundled at ${outDir}/worker/index.js`)
|
|
1508
|
+
postBuildLogs.push(`To deploy: cd ${outDir}/worker && wrangler deploy`)
|
|
1452
1509
|
|
|
1453
1510
|
break
|
|
1454
1511
|
}
|
package/src/cli/buildPage.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { LOADER_JS_POSTFIX_UNCACHED } from '../constants'
|
|
|
5
5
|
import type { LoaderProps } from '../types'
|
|
6
6
|
import { getLoaderPath, getPreloadCSSPath, getPreloadPath } from '../utils/cleanUrl'
|
|
7
7
|
import { isResponse } from '../utils/isResponse'
|
|
8
|
-
import { toAbsolute } from '../utils/toAbsolute'
|
|
8
|
+
import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
|
|
9
9
|
import { replaceLoader } from '../vite/replaceLoader'
|
|
10
10
|
import type { One, RouteInfo } from '../vite/types'
|
|
11
11
|
|
|
@@ -174,7 +174,7 @@ prefetchCSS()
|
|
|
174
174
|
recordTiming('writeCSSPreload', performance.now() - t0)
|
|
175
175
|
|
|
176
176
|
t0 = performance.now()
|
|
177
|
-
const exported = await import(
|
|
177
|
+
const exported = await import(toAbsoluteUrl(serverJsPath))
|
|
178
178
|
recordTiming('importServerModule', performance.now() - t0)
|
|
179
179
|
|
|
180
180
|
const loaderProps: LoaderProps = { path, params }
|
|
@@ -195,7 +195,7 @@ prefetchCSS()
|
|
|
195
195
|
// derive server dir from clientDir (e.g. dist/client -> dist/server)
|
|
196
196
|
const serverDir = join(clientDir, '..', 'server')
|
|
197
197
|
const layoutExported = await import(
|
|
198
|
-
|
|
198
|
+
toAbsoluteUrl(join(serverDir, layoutServerPath))
|
|
199
199
|
)
|
|
200
200
|
const layoutLoaderData = await layoutExported?.loader?.(loaderProps)
|
|
201
201
|
return { contextKey: layout.contextKey, loaderData: layoutLoaderData }
|
|
@@ -478,7 +478,7 @@ params:\n\n${JSON.stringify(params || null, null, 2)}`
|
|
|
478
478
|
|
|
479
479
|
async function getRender(serverEntry: string) {
|
|
480
480
|
try {
|
|
481
|
-
const serverImport = await import(serverEntry)
|
|
481
|
+
const serverImport = await import(toAbsoluteUrl(serverEntry))
|
|
482
482
|
|
|
483
483
|
const render =
|
|
484
484
|
serverImport.default.render ||
|
package/src/constants.ts
CHANGED
|
@@ -3,10 +3,25 @@ import type { One } from './vite/types'
|
|
|
3
3
|
|
|
4
4
|
export const isWebClient =
|
|
5
5
|
process.env.TAMAGUI_TARGET !== 'native' && typeof window !== 'undefined'
|
|
6
|
+
|
|
6
7
|
export const isWebServer =
|
|
7
8
|
process.env.TAMAGUI_TARGET !== 'native' && typeof window === 'undefined'
|
|
9
|
+
|
|
8
10
|
export const isNative = process.env.TAMAGUI_TARGET === 'native'
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* True only in a browser main-thread context with a navigable history —
|
|
14
|
+
* i.e. `window` AND `window.history` are available. Excludes native,
|
|
15
|
+
* SSR, web workers / service workers (no `window`), and exotic sandboxed
|
|
16
|
+
* environments where `window` exists but history is stripped. Use this
|
|
17
|
+
* for guarding any `window.history` / `window.location` access so
|
|
18
|
+
* intercept routes, URL masking, etc. don't assume a full browser.
|
|
19
|
+
*/
|
|
20
|
+
export const hasWebHistory =
|
|
21
|
+
isWebClient &&
|
|
22
|
+
typeof window.history !== 'undefined' &&
|
|
23
|
+
typeof window.location !== 'undefined'
|
|
24
|
+
|
|
10
25
|
export const CACHE_KEY = `${process.env.ONE_CACHE_KEY ?? Math.round(Math.random() * 100_000_000)}`
|
|
11
26
|
|
|
12
27
|
export const LOADER_JS_POSTFIX_UNCACHED = `_vxrn_loader.js`
|
package/src/createAPIRoute.ts
CHANGED
|
@@ -2,9 +2,40 @@ import type { OneRouter } from './interfaces/router'
|
|
|
2
2
|
|
|
3
3
|
type MaybePromise<T> = T | Promise<T>
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Minimal shape of the Cloudflare Workers `ExecutionContext`.
|
|
7
|
+
* Use `context.worker?.executionCtx?.waitUntil(promise)` from an API handler
|
|
8
|
+
* to keep the worker alive for fire-and-forget background work after the
|
|
9
|
+
* response has been sent.
|
|
10
|
+
*/
|
|
11
|
+
export type WorkerExecutionContext = {
|
|
12
|
+
waitUntil: (promise: Promise<unknown>) => void
|
|
13
|
+
passThroughOnException: () => void
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Cloudflare Workers `env` bindings. Shape is app-specific; `unknown` by default. */
|
|
17
|
+
export type WorkerEnv = Record<string, unknown>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Worker-runtime context surfaced on API handlers when running under an edge
|
|
21
|
+
* runtime (Cloudflare Workers). Undefined in dev/Node.
|
|
22
|
+
*/
|
|
23
|
+
export type WorkerContext = {
|
|
24
|
+
env?: WorkerEnv
|
|
25
|
+
executionCtx?: WorkerExecutionContext
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type APIRouteContext<
|
|
29
|
+
Params extends Record<string, string> = Record<string, string>,
|
|
30
|
+
> = {
|
|
31
|
+
params: Params
|
|
32
|
+
/** Present on worker runtimes (Cloudflare Workers). Undefined in dev/Node. */
|
|
33
|
+
worker?: WorkerContext
|
|
34
|
+
}
|
|
35
|
+
|
|
5
36
|
type APIRouteHandler<Params extends Record<string, string> = Record<string, string>> = (
|
|
6
37
|
request: Request,
|
|
7
|
-
context:
|
|
38
|
+
context: APIRouteContext<Params>
|
|
8
39
|
) => MaybePromise<Response>
|
|
9
40
|
|
|
10
41
|
/**
|
|
@@ -15,8 +46,10 @@ type APIRouteHandler<Params extends Record<string, string> = Record<string, stri
|
|
|
15
46
|
* // app/api/users/[id]+api.ts
|
|
16
47
|
* import { createAPIRoute } from 'one'
|
|
17
48
|
*
|
|
18
|
-
* export const GET = createAPIRoute<'/api/users/[id]'>((request, { params }) => {
|
|
49
|
+
* export const GET = createAPIRoute<'/api/users/[id]'>((request, { params, worker }) => {
|
|
19
50
|
* // params.id is typed as string
|
|
51
|
+
* // on cloudflare workers, worker.executionCtx.waitUntil() keeps background work alive
|
|
52
|
+
* worker?.executionCtx?.waitUntil(trackEvent(params.id))
|
|
20
53
|
* return Response.json({ id: params.id })
|
|
21
54
|
* })
|
|
22
55
|
* ```
|
package/src/createApp.tsx
CHANGED
|
@@ -8,6 +8,7 @@ import { render } from './render'
|
|
|
8
8
|
import { initClientMatches } from './router/router'
|
|
9
9
|
import { registerPreloadedRoute } from './router/useViteRoutes'
|
|
10
10
|
import { setupSkewProtection } from './skewProtection'
|
|
11
|
+
import { handleSkewError } from './utils/dynamicImport'
|
|
11
12
|
import { findRootLayout } from './utils/findRootLayout'
|
|
12
13
|
import type { RenderAppProps } from './types'
|
|
13
14
|
import { getServerHeadInsertions } from './useServerHeadInsertion'
|
|
@@ -241,12 +242,7 @@ export function createApp(options: CreateAppProps) {
|
|
|
241
242
|
if (typeof window !== 'undefined' && process.env.ONE_SKEW_PROTECTION !== 'false') {
|
|
242
243
|
window.addEventListener('vite:preloadError', (e) => {
|
|
243
244
|
e.preventDefault()
|
|
244
|
-
|
|
245
|
-
const last = sessionStorage.getItem(key)
|
|
246
|
-
if (!last || Date.now() - Number(last) > 10_000) {
|
|
247
|
-
sessionStorage.setItem(key, String(Date.now()))
|
|
248
|
-
window.location.reload()
|
|
249
|
-
}
|
|
245
|
+
handleSkewError()
|
|
250
246
|
})
|
|
251
247
|
}
|
|
252
248
|
|
|
@@ -120,7 +120,9 @@ export async function resolveAPIRoute(
|
|
|
120
120
|
handlers: RequestHandlers,
|
|
121
121
|
request: Request,
|
|
122
122
|
url: URL,
|
|
123
|
-
route: RouteInfoCompiled
|
|
123
|
+
route: RouteInfoCompiled,
|
|
124
|
+
env?: unknown,
|
|
125
|
+
executionCtx?: unknown
|
|
124
126
|
) {
|
|
125
127
|
const { pathname } = url
|
|
126
128
|
const params = getRouteParams(pathname, route)
|
|
@@ -145,7 +147,9 @@ export async function resolveAPIRoute(
|
|
|
145
147
|
},
|
|
146
148
|
}),
|
|
147
149
|
request,
|
|
148
|
-
params || {}
|
|
150
|
+
params || {},
|
|
151
|
+
env,
|
|
152
|
+
executionCtx
|
|
149
153
|
)
|
|
150
154
|
} catch (err) {
|
|
151
155
|
if (isResponse(err)) {
|
package/src/hooks.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import React, { createContext, useContext } from 'react'
|
|
|
2
2
|
import type { OneRouter } from './interfaces/router'
|
|
3
3
|
import { router } from './router/imperative-api'
|
|
4
4
|
import { RouteParamsContext, useRouteNode } from './router/Route'
|
|
5
|
+
import { mergeDynamicParams } from './router/params'
|
|
5
6
|
import { RouteInfoContext } from './router/RouteInfoContext'
|
|
6
7
|
import { navigationRef, useStoreRootState, useStoreRouteInfo } from './router/router'
|
|
7
8
|
import { getServerContext } from './vite/one-server-only'
|
|
@@ -177,7 +178,14 @@ export const useGlobalSearchParams = useActiveParams
|
|
|
177
178
|
* ```
|
|
178
179
|
*/
|
|
179
180
|
export function useParams<TParams extends object = SearchParams>(): Partial<TParams> {
|
|
180
|
-
const
|
|
181
|
+
const contextParams = React.useContext(RouteParamsContext) ?? {}
|
|
182
|
+
const routeNode = useRouteNode()
|
|
183
|
+
const routeInfoParams = useRouteInfo().params
|
|
184
|
+
|
|
185
|
+
const params = React.useMemo(
|
|
186
|
+
() => mergeDynamicParams(contextParams, routeNode?.dynamic, routeInfoParams),
|
|
187
|
+
[contextParams, routeInfoParams, routeNode]
|
|
188
|
+
)
|
|
181
189
|
|
|
182
190
|
return React.useMemo(() => {
|
|
183
191
|
return Object.fromEntries(
|
package/src/index.ts
CHANGED
|
@@ -53,7 +53,14 @@ export { onClientLoaderResolve } from './clientLoaderResolver'
|
|
|
53
53
|
// middleware
|
|
54
54
|
export { createMiddleware, type Middleware } from './createMiddleware'
|
|
55
55
|
// api routes
|
|
56
|
-
export {
|
|
56
|
+
export {
|
|
57
|
+
createAPIRoute,
|
|
58
|
+
type APIRouteContext,
|
|
59
|
+
type APIRouteHandler,
|
|
60
|
+
type WorkerContext,
|
|
61
|
+
type WorkerEnv,
|
|
62
|
+
type WorkerExecutionContext,
|
|
63
|
+
} from './createAPIRoute'
|
|
57
64
|
export { getURL } from './getURL'
|
|
58
65
|
export { Head } from './head'
|
|
59
66
|
// for easier expo-router migration
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { normalizeReSource } from './getViteMetroPluginOptions'
|
|
3
|
+
|
|
4
|
+
// String.raw avoids double-escaping: String.raw`[\\/]` is the 5-char string [ \ \ / ]
|
|
5
|
+
// which is exactly what regex.source produces for /[\\/]/
|
|
6
|
+
|
|
7
|
+
describe('normalizeReSource', () => {
|
|
8
|
+
it(String.raw`[\\/] to \/`, () => {
|
|
9
|
+
expect(normalizeReSource(String.raw`[\\/]`)).toBe(String.raw`\/`)
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it(String.raw`[^\\/] to [^/]`, () => {
|
|
13
|
+
expect(normalizeReSource(String.raw`[^\\/]`)).toBe('[^/]')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('full Windows micromatch regex', () => {
|
|
17
|
+
// micromatch.makeRe('**/*.web.(ts|tsx)').source on Windows (picomatch 2.x)
|
|
18
|
+
const windowsSource = String.raw`^(?:(?:^|[\\/]|(?:(?:(?!(?:^|[\\/])\.).)*?)[\\/])(?!\.)(?=.)[^\\/]*?\.web\.(ts|tsx))$`
|
|
19
|
+
const posixSource = String.raw`^(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.web\.(ts|tsx))$`
|
|
20
|
+
|
|
21
|
+
expect(normalizeReSource(windowsSource)).toBe(posixSource)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('no-op for POSIX regex', () => {
|
|
25
|
+
const posixSource = String.raw`^(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.web\.(ts|tsx))$`
|
|
26
|
+
|
|
27
|
+
expect(normalizeReSource(posixSource)).toBe(posixSource)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('multiple groups in one source', () => {
|
|
31
|
+
const source = String.raw`a[\\/]b[\\/]c[^\\/]d`
|
|
32
|
+
expect(normalizeReSource(source)).toBe(String.raw`a\/b\/c[^/]d`)
|
|
33
|
+
})
|
|
34
|
+
})
|