one 1.25.12 → 1.25.15
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 +37 -186
- package/dist/cjs/cli/build.native.js +270 -423
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +7 -7
- package/dist/cjs/cli/buildPage.native.js +7 -7
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/cli/buildPageWorker.cjs +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js.map +1 -1
- package/dist/cjs/cli/serverRouteModules.cjs +47 -0
- package/dist/cjs/cli/serverRouteModules.native.js +52 -0
- package/dist/cjs/cli/serverRouteModules.native.js.map +1 -0
- package/dist/cjs/cli/workerPool.native.js.map +1 -1
- package/dist/cjs/createApp.cjs +3 -0
- package/dist/cjs/createDevHandleRequest.cjs +151 -0
- package/dist/cjs/createDevHandleRequest.native.js +194 -0
- package/dist/cjs/createDevHandleRequest.native.js.map +1 -0
- package/dist/cjs/createHandleRequest.cjs +1 -123
- package/dist/cjs/createHandleRequest.native.js +1 -163
- package/dist/cjs/createHandleRequest.native.js.map +1 -1
- package/dist/cjs/createHandleRequest.test.cjs +25 -25
- package/dist/cjs/createHandleRequest.test.native.js +25 -25
- package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
- package/dist/cjs/headless-server.native.js.map +1 -1
- package/dist/cjs/headless.cjs +4 -0
- package/dist/cjs/headless.native.js +4 -0
- package/dist/cjs/headless.native.js.map +1 -1
- package/dist/cjs/layouts/Drawer.cjs +0 -2
- package/dist/cjs/layouts/Drawer.native.js.map +1 -1
- package/dist/cjs/layouts/Tabs.cjs +0 -2
- package/dist/cjs/layouts/Tabs.native.js.map +1 -1
- package/dist/cjs/router/diagnoseRouteLoadFailure.native.js.map +1 -1
- package/dist/cjs/router/useViteRoutes.cjs +9 -1
- package/dist/cjs/router/useViteRoutes.native.js +9 -1
- package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
- package/dist/cjs/router/web/WebStackView.cjs +0 -2
- package/dist/cjs/router/web/WebStackView.native.js +0 -2
- package/dist/cjs/router/web/WebStackView.native.js.map +1 -1
- package/dist/cjs/serve-worker.cjs +3 -2
- package/dist/cjs/serve-worker.native.js +3 -2
- package/dist/cjs/serve-worker.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +23 -4
- package/dist/cjs/server/oneServe.native.js +25 -6
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server/routeExportsFromEntry.cjs +47 -0
- package/dist/cjs/server/routeExportsFromEntry.native.js +52 -0
- package/dist/cjs/server/routeExportsFromEntry.native.js.map +1 -0
- package/dist/cjs/server/workerHandler.cjs +30 -12
- package/dist/cjs/server/workerHandler.native.js +32 -13
- package/dist/cjs/server/workerHandler.native.js.map +1 -1
- package/dist/cjs/server/workerHandler.test.cjs +43 -10
- package/dist/cjs/server/workerHandler.test.native.js +46 -10
- package/dist/cjs/server/workerHandler.test.native.js.map +1 -1
- package/dist/cjs/views/ScrollBehavior.native.js.map +1 -1
- package/dist/cjs/vite/cloudflareWranglerConfig.cjs +247 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.native.js +392 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.native.js.map +1 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.cjs +116 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js +120 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
- package/dist/cjs/vite/one.cjs +4 -2
- package/dist/cjs/vite/one.native.js +8 -6
- package/dist/cjs/vite/one.native.js.map +1 -1
- package/dist/cjs/vite/plugins/SSRCSSPlugin.cjs +10 -1
- package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js +52 -3
- package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.cjs +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.cjs +4 -0
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +14 -5
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +15 -5
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.cjs +47 -0
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +9 -7
- package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +11 -7
- package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.cjs +12 -0
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/workerdDevPlugin.cjs +364 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js +461 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js.map +1 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.cjs +42 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js +45 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
- package/dist/cjs/vite/replaceLoader.cjs +6 -3
- package/dist/cjs/vite/replaceLoader.native.js +8 -3
- package/dist/cjs/vite/replaceLoader.native.js.map +1 -1
- package/dist/esm/cli/build.mjs +31 -180
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +264 -417
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +7 -7
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +7 -7
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/cli/buildPageWorker.mjs +1 -1
- package/dist/esm/cli/buildPageWorker.mjs.map +1 -1
- package/dist/esm/cli/buildPageWorker.native.js +1 -1
- package/dist/esm/cli/buildPageWorker.native.js.map +1 -1
- package/dist/esm/cli/serverRouteModules.mjs +22 -0
- package/dist/esm/cli/serverRouteModules.mjs.map +1 -0
- package/dist/esm/cli/serverRouteModules.native.js +24 -0
- package/dist/esm/cli/serverRouteModules.native.js.map +1 -0
- package/dist/esm/cli/workerPool.mjs.map +1 -1
- package/dist/esm/cli/workerPool.native.js.map +1 -1
- package/dist/esm/createApp.mjs +4 -1
- package/dist/esm/createApp.mjs.map +1 -1
- package/dist/esm/createDevHandleRequest.mjs +126 -0
- package/dist/esm/createDevHandleRequest.mjs.map +1 -0
- package/dist/esm/createDevHandleRequest.native.js +166 -0
- package/dist/esm/createDevHandleRequest.native.js.map +1 -0
- package/dist/esm/createHandleRequest.mjs +1 -123
- package/dist/esm/createHandleRequest.mjs.map +1 -1
- package/dist/esm/createHandleRequest.native.js +1 -163
- package/dist/esm/createHandleRequest.native.js.map +1 -1
- package/dist/esm/createHandleRequest.test.mjs +1 -1
- package/dist/esm/createHandleRequest.test.native.js +1 -1
- package/dist/esm/headless-server.mjs.map +1 -1
- package/dist/esm/headless-server.native.js.map +1 -1
- package/dist/esm/headless.mjs +4 -0
- package/dist/esm/headless.mjs.map +1 -1
- package/dist/esm/headless.native.js +4 -0
- package/dist/esm/headless.native.js.map +1 -1
- package/dist/esm/layouts/Drawer.mjs +0 -2
- package/dist/esm/layouts/Drawer.mjs.map +1 -1
- package/dist/esm/layouts/Drawer.native.js.map +1 -1
- package/dist/esm/layouts/Tabs.mjs +0 -2
- package/dist/esm/layouts/Tabs.mjs.map +1 -1
- package/dist/esm/layouts/Tabs.native.js.map +1 -1
- package/dist/esm/router/diagnoseRouteLoadFailure.mjs.map +1 -1
- package/dist/esm/router/diagnoseRouteLoadFailure.native.js.map +1 -1
- package/dist/esm/router/useViteRoutes.mjs +9 -1
- package/dist/esm/router/useViteRoutes.mjs.map +1 -1
- package/dist/esm/router/useViteRoutes.native.js +9 -1
- package/dist/esm/router/useViteRoutes.native.js.map +1 -1
- package/dist/esm/router/web/WebStackView.mjs +0 -2
- package/dist/esm/router/web/WebStackView.mjs.map +1 -1
- package/dist/esm/router/web/WebStackView.native.js +0 -2
- package/dist/esm/router/web/WebStackView.native.js.map +1 -1
- package/dist/esm/serve-worker.mjs +3 -2
- package/dist/esm/serve-worker.mjs.map +1 -1
- package/dist/esm/serve-worker.native.js +3 -2
- package/dist/esm/serve-worker.native.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +23 -4
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +25 -6
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/server/routeExportsFromEntry.mjs +21 -0
- package/dist/esm/server/routeExportsFromEntry.mjs.map +1 -0
- package/dist/esm/server/routeExportsFromEntry.native.js +23 -0
- package/dist/esm/server/routeExportsFromEntry.native.js.map +1 -0
- package/dist/esm/server/workerHandler.mjs +30 -12
- package/dist/esm/server/workerHandler.mjs.map +1 -1
- package/dist/esm/server/workerHandler.native.js +32 -13
- package/dist/esm/server/workerHandler.native.js.map +1 -1
- package/dist/esm/server/workerHandler.test.mjs +43 -10
- package/dist/esm/server/workerHandler.test.mjs.map +1 -1
- package/dist/esm/server/workerHandler.test.native.js +46 -10
- package/dist/esm/server/workerHandler.test.native.js.map +1 -1
- package/dist/esm/views/ScrollBehavior.mjs.map +1 -1
- package/dist/esm/views/ScrollBehavior.native.js.map +1 -1
- package/dist/esm/vite/cloudflareWranglerConfig.mjs +202 -0
- package/dist/esm/vite/cloudflareWranglerConfig.mjs.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.native.js +344 -0
- package/dist/esm/vite/cloudflareWranglerConfig.native.js.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.mjs +117 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.mjs.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.native.js +118 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
- package/dist/esm/vite/one.mjs +4 -2
- package/dist/esm/vite/one.mjs.map +1 -1
- package/dist/esm/vite/one.native.js +8 -6
- package/dist/esm/vite/one.native.js.map +1 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.mjs +10 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.native.js +52 -3
- package/dist/esm/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.mjs +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.native.js +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs +4 -0
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +13 -4
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +14 -4
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs +47 -0
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +9 -7
- package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +11 -7
- package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs +12 -0
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs +336 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js +430 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs +43 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js +43 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
- package/dist/esm/vite/replaceLoader.mjs +6 -3
- package/dist/esm/vite/replaceLoader.mjs.map +1 -1
- package/dist/esm/vite/replaceLoader.native.js +8 -3
- package/dist/esm/vite/replaceLoader.native.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.ts +48 -224
- package/src/cli/buildPage.ts +9 -7
- package/src/cli/buildPageWorker.ts +1 -0
- package/src/cli/serverRouteModules.ts +33 -0
- package/src/cli/workerPool.ts +1 -0
- package/src/createApp.tsx +5 -1
- package/src/createDevHandleRequest.ts +186 -0
- package/src/createHandleRequest.test.ts +1 -1
- package/src/createHandleRequest.ts +2 -172
- package/src/headless-server.ts +0 -1
- package/src/headless.tsx +5 -0
- package/src/layouts/Drawer.web.tsx +0 -3
- package/src/layouts/Tabs.web.tsx +0 -2
- package/src/router/diagnoseRouteLoadFailure.ts +3 -1
- package/src/router/useViteRoutes.tsx +9 -1
- package/src/router/web/WebStackView.tsx +0 -3
- package/src/serve-worker.ts +6 -1
- package/src/server/oneServe.ts +40 -16
- package/src/server/routeExportsFromEntry.ts +59 -0
- package/src/server/workerHandler.test.ts +37 -9
- package/src/server/workerHandler.ts +39 -13
- package/src/views/ScrollBehavior.tsx +5 -1
- package/src/vite/cloudflareWranglerConfig.test.ts +101 -0
- package/src/vite/cloudflareWranglerConfig.ts +252 -0
- package/src/vite/one.ts +14 -1
- package/src/vite/plugins/SSRCSSPlugin.ts +17 -2
- package/src/vite/plugins/environmentGuardPlugin.test.ts +5 -0
- package/src/vite/plugins/environmentGuardPlugin.ts +2 -2
- package/src/vite/plugins/fileSystemRouterPlugin.test.ts +44 -0
- package/src/vite/plugins/fileSystemRouterPlugin.tsx +20 -8
- package/src/vite/plugins/virtualEntryPlugin.test.ts +13 -0
- package/src/vite/plugins/virtualEntryPlugin.ts +13 -9
- package/src/vite/plugins/workerdDevPlugin.test.ts +44 -0
- package/src/vite/plugins/workerdDevPlugin.ts +398 -0
- package/src/vite/replaceLoader.ts +10 -2
- package/types/cli/build.d.ts.map +1 -1
- package/types/cli/buildPage.d.ts +1 -1
- package/types/cli/buildPage.d.ts.map +1 -1
- package/types/cli/serverRouteModules.d.ts +2 -0
- package/types/cli/serverRouteModules.d.ts.map +1 -0
- package/types/cli/workerPool.d.ts +1 -0
- package/types/cli/workerPool.d.ts.map +1 -1
- package/types/createApp.d.ts.map +1 -1
- package/types/createDevHandleRequest.d.ts +10 -0
- package/types/createDevHandleRequest.d.ts.map +1 -0
- package/types/createHandleRequest.d.ts +2 -9
- package/types/createHandleRequest.d.ts.map +1 -1
- package/types/headless-server.d.ts +0 -1
- package/types/headless-server.d.ts.map +1 -1
- package/types/headless.d.ts.map +1 -1
- package/types/layouts/Drawer.web.d.ts.map +1 -1
- package/types/layouts/Tabs.web.d.ts.map +1 -1
- package/types/router/diagnoseRouteLoadFailure.d.ts.map +1 -1
- package/types/router/useViteRoutes.d.ts.map +1 -1
- package/types/router/web/WebStackView.d.ts.map +1 -1
- package/types/serve-worker.d.ts +3 -1
- package/types/serve-worker.d.ts.map +1 -1
- package/types/server/oneServe.d.ts +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/server/routeExportsFromEntry.d.ts +29 -0
- package/types/server/routeExportsFromEntry.d.ts.map +1 -0
- package/types/server/workerHandler.d.ts +2 -1
- package/types/server/workerHandler.d.ts.map +1 -1
- package/types/views/ScrollBehavior.d.ts.map +1 -1
- package/types/vite/cloudflareWranglerConfig.d.ts +21 -0
- package/types/vite/cloudflareWranglerConfig.d.ts.map +1 -0
- package/types/vite/cloudflareWranglerConfig.test.d.ts +2 -0
- package/types/vite/cloudflareWranglerConfig.test.d.ts.map +1 -0
- package/types/vite/one.d.ts.map +1 -1
- package/types/vite/plugins/SSRCSSPlugin.d.ts.map +1 -1
- package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
- package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
- package/types/vite/plugins/workerdDevPlugin.d.ts +15 -0
- package/types/vite/plugins/workerdDevPlugin.d.ts.map +1 -0
- package/types/vite/plugins/workerdDevPlugin.test.d.ts +2 -0
- package/types/vite/plugins/workerdDevPlugin.test.d.ts.map +1 -0
- package/types/vite/replaceLoader.d.ts +2 -1
- package/types/vite/replaceLoader.d.ts.map +1 -1
- package/dist/cjs/headless/devHeadlessNote.cjs +0 -34
- package/dist/cjs/headless/devHeadlessNote.native.js +0 -37
- package/dist/cjs/headless/devHeadlessNote.native.js.map +0 -1
- package/dist/esm/headless/devHeadlessNote.mjs +0 -9
- package/dist/esm/headless/devHeadlessNote.mjs.map +0 -1
- package/dist/esm/headless/devHeadlessNote.native.js +0 -9
- package/dist/esm/headless/devHeadlessNote.native.js.map +0 -1
- package/src/headless/devHeadlessNote.ts +0 -13
- package/types/headless/devHeadlessNote.d.ts +0 -2
- package/types/headless/devHeadlessNote.d.ts.map +0 -1
|
@@ -15,21 +15,23 @@ import {
|
|
|
15
15
|
} from '../createHandleRequest'
|
|
16
16
|
import type { RenderAppProps } from '../types'
|
|
17
17
|
import { getPathFromLoaderPath } from '../utils/cleanUrl'
|
|
18
|
+
import { getRouterRootFromOneOptions } from '../utils/getRouterRootFromOneOptions'
|
|
18
19
|
import { isResponse } from '../utils/isResponse'
|
|
19
20
|
import { resolveResponse } from '../vite/resolveResponse'
|
|
20
21
|
import type { One } from '../vite/types'
|
|
21
22
|
import type { RouteInfoCompiled } from './createRoutesManifest'
|
|
23
|
+
import { getRouteExportsFromEntry } from './routeExportsFromEntry'
|
|
22
24
|
import { setSSRLoaderData } from './ssrLoaderData'
|
|
23
25
|
import { getFetchStaticHtml } from './staticHtmlFetcher'
|
|
24
26
|
|
|
25
27
|
export type LazyRoutes = {
|
|
28
|
+
pages?: Record<string, () => Promise<any>>
|
|
26
29
|
serverEntry: () => Promise<{
|
|
27
30
|
default: {
|
|
28
31
|
render: (props: any) => any
|
|
29
32
|
renderStream?: (props: any) => Promise<ReadableStream>
|
|
30
33
|
}
|
|
31
34
|
}>
|
|
32
|
-
pages: Record<string, () => Promise<any>>
|
|
33
35
|
api: Record<string, () => Promise<any>>
|
|
34
36
|
middlewares: Record<string, () => Promise<any>>
|
|
35
37
|
}
|
|
@@ -38,10 +40,15 @@ type WorkerHandlerOptions = {
|
|
|
38
40
|
oneOptions: One.PluginOptions
|
|
39
41
|
buildInfo: One.BuildInfo
|
|
40
42
|
lazyRoutes: LazyRoutes
|
|
43
|
+
// when true, skip the module/loader caches so vite hmr of a route file is
|
|
44
|
+
// visible on the next request. production omits this.
|
|
45
|
+
disableModuleCache?: boolean
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
export function createWorkerHandler(options: WorkerHandlerOptions) {
|
|
44
49
|
const { oneOptions } = options
|
|
50
|
+
const disableModuleCache = !!options.disableModuleCache
|
|
51
|
+
const routerRoot = getRouterRootFromOneOptions(oneOptions)
|
|
45
52
|
|
|
46
53
|
// mutable state for route swapping
|
|
47
54
|
let currentLazyRoutes = options.lazyRoutes
|
|
@@ -91,13 +98,21 @@ export function createWorkerHandler(options: WorkerHandlerOptions) {
|
|
|
91
98
|
let renderStream: ((props: RenderAppProps) => Promise<ReadableStream>) | null = null
|
|
92
99
|
let renderLoading: Promise<void> | null = null
|
|
93
100
|
let renderGeneration = 0
|
|
101
|
+
let entryLoading: Promise<any> | null = null
|
|
102
|
+
|
|
103
|
+
// route modules are resolved through the built server entry, see
|
|
104
|
+
// routeExportsFromEntry
|
|
105
|
+
function loadServerEntry(): Promise<any> {
|
|
106
|
+
if (!entryLoading) entryLoading = currentLazyRoutes.serverEntry()
|
|
107
|
+
return entryLoading
|
|
108
|
+
}
|
|
94
109
|
|
|
95
110
|
function ensureRenderLoaded(): void | Promise<void> {
|
|
96
111
|
if (render) return
|
|
97
112
|
if (renderLoading) return renderLoading
|
|
98
113
|
const gen = ++renderGeneration
|
|
99
114
|
renderLoading = (async () => {
|
|
100
|
-
const entry = await
|
|
115
|
+
const entry = await loadServerEntry()
|
|
101
116
|
// if updateRoutes was called while we were loading, discard stale entry
|
|
102
117
|
if (gen !== renderGeneration) return
|
|
103
118
|
render = entry.default.render as any
|
|
@@ -137,25 +152,35 @@ export function createWorkerHandler(options: WorkerHandlerOptions) {
|
|
|
137
152
|
lazyKey: string | undefined
|
|
138
153
|
): Function | null | Promise<Function | null> {
|
|
139
154
|
const cacheKey = lazyKey || ''
|
|
140
|
-
|
|
141
|
-
|
|
155
|
+
if (!disableModuleCache) {
|
|
156
|
+
const cached = loaderCache.get(cacheKey)
|
|
157
|
+
if (cached !== undefined) return cached
|
|
158
|
+
}
|
|
142
159
|
|
|
143
160
|
return (async () => {
|
|
144
161
|
let routeExported: any
|
|
145
|
-
if (moduleImportCache.has(cacheKey)) {
|
|
162
|
+
if (!disableModuleCache && moduleImportCache.has(cacheKey)) {
|
|
146
163
|
routeExported = moduleImportCache.get(cacheKey)
|
|
147
|
-
} else if (
|
|
148
|
-
routeExported = await currentLazyRoutes.pages[
|
|
149
|
-
moduleImportCache.set(cacheKey, routeExported)
|
|
164
|
+
} else if (currentLazyRoutes.pages?.[cacheKey]) {
|
|
165
|
+
routeExported = await currentLazyRoutes.pages[cacheKey]()
|
|
166
|
+
if (!disableModuleCache) moduleImportCache.set(cacheKey, routeExported)
|
|
150
167
|
} else {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
routeExported = lazyKey
|
|
169
|
+
? await getRouteExportsFromEntry(await loadServerEntry(), routerRoot, lazyKey)
|
|
170
|
+
: null
|
|
171
|
+
if (!routeExported) {
|
|
172
|
+
console.warn(`[one/worker] no lazy route for ${cacheKey}`)
|
|
173
|
+
if (!disableModuleCache) loaderCache.set(cacheKey, null)
|
|
174
|
+
return null
|
|
175
|
+
}
|
|
176
|
+
if (!disableModuleCache) moduleImportCache.set(cacheKey, routeExported)
|
|
154
177
|
}
|
|
155
178
|
|
|
156
179
|
const loader = routeExported?.loader || null
|
|
157
|
-
|
|
158
|
-
|
|
180
|
+
if (!disableModuleCache) {
|
|
181
|
+
loaderCache.set(cacheKey, loader)
|
|
182
|
+
loaderCacheFnMap.set(cacheKey, routeExported?.loaderCache ?? null)
|
|
183
|
+
}
|
|
159
184
|
return loader
|
|
160
185
|
})()
|
|
161
186
|
}
|
|
@@ -789,6 +814,7 @@ export function createWorkerHandler(options: WorkerHandlerOptions) {
|
|
|
789
814
|
render = null
|
|
790
815
|
renderStream = null
|
|
791
816
|
renderLoading = null
|
|
817
|
+
entryLoading = null
|
|
792
818
|
}
|
|
793
819
|
|
|
794
820
|
return { handleRequest, updateRoutes }
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useEffect } from 'react'
|
|
2
2
|
import { setLastAction } from '../router/lastAction'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
routeInfo,
|
|
5
|
+
subscribeToLoadingState,
|
|
6
|
+
subscribeToRootState,
|
|
7
|
+
} from '../router/router'
|
|
4
8
|
|
|
5
9
|
const KEY = 'one-sr'
|
|
6
10
|
const GROUP_KEY = 'one-sr-groups'
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import { afterEach, describe, expect, it } from 'vitest'
|
|
5
|
+
import {
|
|
6
|
+
createCloudflareWranglerConfig,
|
|
7
|
+
isExperimentalWorkerDevEnabled,
|
|
8
|
+
loadUserWranglerConfigSync,
|
|
9
|
+
shouldEnableWorkerdDev,
|
|
10
|
+
} from './cloudflareWranglerConfig'
|
|
11
|
+
|
|
12
|
+
describe('createCloudflareWranglerConfig', () => {
|
|
13
|
+
it('synthesizes a worker config when no user wrangler file exists', () => {
|
|
14
|
+
const config = createCloudflareWranglerConfig('my-app')
|
|
15
|
+
expect(config.name).toBe('my-app')
|
|
16
|
+
expect(config.main).toBe('worker.js')
|
|
17
|
+
expect(config.compatibility_flags).toEqual(['nodejs_compat'])
|
|
18
|
+
expect(config.find_additional_modules).toBe(true)
|
|
19
|
+
expect(config.assets).toEqual({
|
|
20
|
+
directory: 'client',
|
|
21
|
+
binding: 'ASSETS',
|
|
22
|
+
run_worker_first: true,
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('merges user wrangler.jsonc the same way the cloudflare build does', () => {
|
|
27
|
+
const config = createCloudflareWranglerConfig('generated-name', {
|
|
28
|
+
name: 'test-cloudflare-user-config',
|
|
29
|
+
compatibility_date: '2025-01-01',
|
|
30
|
+
compatibility_flags: ['nodejs_als'],
|
|
31
|
+
vars: { CUSTOM_VALUE: 'from-root-config' },
|
|
32
|
+
assets: { html_handling: 'auto-trailing-slash' },
|
|
33
|
+
rules: [{ type: 'ESModule', globs: ['./extra/**/*.js'], fallthrough: true }],
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect(config.name).toBe('test-cloudflare-user-config')
|
|
37
|
+
expect(config.main).toBe('worker.js')
|
|
38
|
+
expect(config.compatibility_date).toBe('2025-01-01')
|
|
39
|
+
expect(config.compatibility_flags).toEqual(['nodejs_compat', 'nodejs_als'])
|
|
40
|
+
expect(config.vars).toEqual({ CUSTOM_VALUE: 'from-root-config' })
|
|
41
|
+
expect(config.assets).toEqual({
|
|
42
|
+
html_handling: 'auto-trailing-slash',
|
|
43
|
+
directory: 'client',
|
|
44
|
+
binding: 'ASSETS',
|
|
45
|
+
run_worker_first: true,
|
|
46
|
+
})
|
|
47
|
+
expect(config.rules).toEqual([
|
|
48
|
+
{ type: 'ESModule', globs: ['./server/**/*.js'], fallthrough: true },
|
|
49
|
+
{ type: 'ESModule', globs: ['./api/**/*.js'], fallthrough: true },
|
|
50
|
+
{ type: 'ESModule', globs: ['./middlewares/**/*.js'], fallthrough: true },
|
|
51
|
+
{ type: 'ESModule', globs: ['./assets/**/*.js'], fallthrough: true },
|
|
52
|
+
{ type: 'ESModule', globs: ['./extra/**/*.js'], fallthrough: true },
|
|
53
|
+
])
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe('shouldEnableWorkerdDev', () => {
|
|
58
|
+
const previous = process.env.ONE_EXPERIMENTAL_WORKER_DEV
|
|
59
|
+
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
if (previous === undefined) delete process.env.ONE_EXPERIMENTAL_WORKER_DEV
|
|
62
|
+
else process.env.ONE_EXPERIMENTAL_WORKER_DEV = previous
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('is off when the flag is unset', () => {
|
|
66
|
+
delete process.env.ONE_EXPERIMENTAL_WORKER_DEV
|
|
67
|
+
expect(isExperimentalWorkerDevEnabled()).toBe(false)
|
|
68
|
+
expect(shouldEnableWorkerdDev('cloudflare', '/tmp')).toBe(false)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('is off when the flag is on but the app has no cloudflare target or wrangler file', () => {
|
|
72
|
+
process.env.ONE_EXPERIMENTAL_WORKER_DEV = '1'
|
|
73
|
+
const root = mkdtempSync(join(tmpdir(), 'one-workerd-flag-'))
|
|
74
|
+
try {
|
|
75
|
+
expect(shouldEnableWorkerdDev(undefined, root)).toBe(false)
|
|
76
|
+
expect(shouldEnableWorkerdDev('node', root)).toBe(false)
|
|
77
|
+
} finally {
|
|
78
|
+
rmSync(root, { recursive: true, force: true })
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('is on when the flag is set and deploy is cloudflare', () => {
|
|
83
|
+
process.env.ONE_EXPERIMENTAL_WORKER_DEV = '1'
|
|
84
|
+
expect(shouldEnableWorkerdDev('cloudflare', '/tmp-does-not-exist')).toBe(true)
|
|
85
|
+
expect(shouldEnableWorkerdDev({ target: 'cloudflare' }, '/tmp-does-not-exist')).toBe(
|
|
86
|
+
true
|
|
87
|
+
)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('is on when the flag is set and wrangler.jsonc exists', () => {
|
|
91
|
+
process.env.ONE_EXPERIMENTAL_WORKER_DEV = '1'
|
|
92
|
+
const root = mkdtempSync(join(tmpdir(), 'one-workerd-wrangler-'))
|
|
93
|
+
try {
|
|
94
|
+
writeFileSync(join(root, 'wrangler.jsonc'), '{ "name": "from-file" }\n')
|
|
95
|
+
expect(shouldEnableWorkerdDev(undefined, root)).toBe(true)
|
|
96
|
+
expect(loadUserWranglerConfigSync(root)?.config.name).toBe('from-file')
|
|
97
|
+
} finally {
|
|
98
|
+
rmSync(root, { recursive: true, force: true })
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
})
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { join, relative } from 'node:path'
|
|
3
|
+
import FSExtra from 'fs-extra'
|
|
4
|
+
|
|
5
|
+
export type JsonPrimitive = string | number | boolean | null
|
|
6
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }
|
|
7
|
+
|
|
8
|
+
export const GENERATED_CLOUDFLARE_WRANGLER_RULES: JsonValue[] = [
|
|
9
|
+
{ type: 'ESModule', globs: ['./server/**/*.js'], fallthrough: true },
|
|
10
|
+
{ type: 'ESModule', globs: ['./api/**/*.js'], fallthrough: true },
|
|
11
|
+
{ type: 'ESModule', globs: ['./middlewares/**/*.js'], fallthrough: true },
|
|
12
|
+
{ type: 'ESModule', globs: ['./assets/**/*.js'], fallthrough: true },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
export function isPlainObject(value: unknown): value is Record<string, JsonValue> {
|
|
16
|
+
return !!value && typeof value === 'object' && !Array.isArray(value)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function mergeJsonObjects(
|
|
20
|
+
base: Record<string, JsonValue>,
|
|
21
|
+
overrides: Record<string, JsonValue>
|
|
22
|
+
): Record<string, JsonValue> {
|
|
23
|
+
const merged: Record<string, JsonValue> = { ...base }
|
|
24
|
+
|
|
25
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
26
|
+
const baseValue = merged[key]
|
|
27
|
+
if (isPlainObject(baseValue) && isPlainObject(value)) {
|
|
28
|
+
merged[key] = mergeJsonObjects(baseValue, value)
|
|
29
|
+
} else {
|
|
30
|
+
merged[key] = value
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return merged
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function dedupeJsonValues<T extends JsonValue>(values: T[]): T[] {
|
|
38
|
+
const seen = new Set<string>()
|
|
39
|
+
return values.filter((value) => {
|
|
40
|
+
const key = JSON.stringify(value)
|
|
41
|
+
if (seen.has(key)) return false
|
|
42
|
+
seen.add(key)
|
|
43
|
+
return true
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function mergeCloudflareCompatibilityFlags(flags: unknown): string[] {
|
|
48
|
+
const userFlags = Array.isArray(flags)
|
|
49
|
+
? flags.filter((flag): flag is string => typeof flag === 'string')
|
|
50
|
+
: []
|
|
51
|
+
|
|
52
|
+
return dedupeJsonValues<string>(['nodejs_compat', ...userFlags])
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function mergeCloudflareRules(rules: unknown): JsonValue[] {
|
|
56
|
+
const userRules = Array.isArray(rules)
|
|
57
|
+
? rules.filter((rule): rule is JsonValue => isPlainObject(rule))
|
|
58
|
+
: []
|
|
59
|
+
|
|
60
|
+
return dedupeJsonValues<JsonValue>([
|
|
61
|
+
...GENERATED_CLOUDFLARE_WRANGLER_RULES,
|
|
62
|
+
...userRules,
|
|
63
|
+
])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// minimal JSONC parser: strips line/block comments (string-aware) and trailing
|
|
67
|
+
// commas, then runs JSON.parse. sufficient for small hand-written config files.
|
|
68
|
+
function parseJsonc(text: string): unknown {
|
|
69
|
+
let out = ''
|
|
70
|
+
let i = 0
|
|
71
|
+
let inString = false
|
|
72
|
+
let quote = ''
|
|
73
|
+
while (i < text.length) {
|
|
74
|
+
const ch = text[i]
|
|
75
|
+
const next = text[i + 1]
|
|
76
|
+
if (inString) {
|
|
77
|
+
if (ch === '\\') {
|
|
78
|
+
out += ch + (next ?? '')
|
|
79
|
+
i += 2
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
if (ch === quote) inString = false
|
|
83
|
+
out += ch
|
|
84
|
+
i++
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
if (ch === '"' || ch === "'") {
|
|
88
|
+
inString = true
|
|
89
|
+
quote = ch
|
|
90
|
+
out += ch
|
|
91
|
+
i++
|
|
92
|
+
continue
|
|
93
|
+
}
|
|
94
|
+
if (ch === '/' && next === '/') {
|
|
95
|
+
while (i < text.length && text[i] !== '\n') i++
|
|
96
|
+
continue
|
|
97
|
+
}
|
|
98
|
+
if (ch === '/' && next === '*') {
|
|
99
|
+
i += 2
|
|
100
|
+
while (i < text.length - 1 && !(text[i] === '*' && text[i + 1] === '/')) i++
|
|
101
|
+
i += 2
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
out += ch
|
|
105
|
+
i++
|
|
106
|
+
}
|
|
107
|
+
return JSON.parse(out.replace(/,(\s*[}\]])/g, '$1'))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const WRANGLER_FILE_NAMES = ['wrangler.jsonc', 'wrangler.json'] as const
|
|
111
|
+
|
|
112
|
+
function wranglerCandidateRoots(root: string): string[] {
|
|
113
|
+
return [...new Set([root, process.cwd()])]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function hasUserWranglerConfig(root: string): boolean {
|
|
117
|
+
for (const candidateRoot of wranglerCandidateRoots(root)) {
|
|
118
|
+
for (const fileName of WRANGLER_FILE_NAMES) {
|
|
119
|
+
if (existsSync(join(candidateRoot, fileName))) return true
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function parseUserWranglerFile(configPath: string): {
|
|
126
|
+
path: string
|
|
127
|
+
config: Record<string, JsonValue>
|
|
128
|
+
} {
|
|
129
|
+
const contents = readFileSync(configPath, 'utf-8')
|
|
130
|
+
let parsed: unknown
|
|
131
|
+
try {
|
|
132
|
+
parsed = parseJsonc(contents)
|
|
133
|
+
} catch (err) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`Failed to parse ${relative(process.cwd(), configPath)}: ${(err as Error).message}`
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!isPlainObject(parsed)) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`Expected ${relative(process.cwd(), configPath)} to contain a top-level JSON object`
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
path: configPath,
|
|
147
|
+
config: parsed,
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function loadUserWranglerConfigSync(
|
|
152
|
+
root: string
|
|
153
|
+
): { path: string; config: Record<string, JsonValue> } | null {
|
|
154
|
+
for (const candidateRoot of wranglerCandidateRoots(root)) {
|
|
155
|
+
for (const fileName of WRANGLER_FILE_NAMES) {
|
|
156
|
+
const configPath = join(candidateRoot, fileName)
|
|
157
|
+
if (!existsSync(configPath)) continue
|
|
158
|
+
return parseUserWranglerFile(configPath)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export async function loadUserWranglerConfig(
|
|
165
|
+
root: string
|
|
166
|
+
): Promise<{ path: string; config: Record<string, JsonValue> } | null> {
|
|
167
|
+
const candidateRoots = wranglerCandidateRoots(root)
|
|
168
|
+
|
|
169
|
+
for (const candidateRoot of candidateRoots) {
|
|
170
|
+
for (const fileName of WRANGLER_FILE_NAMES) {
|
|
171
|
+
const configPath = join(candidateRoot, fileName)
|
|
172
|
+
if (!(await FSExtra.pathExists(configPath))) {
|
|
173
|
+
continue
|
|
174
|
+
}
|
|
175
|
+
return parseUserWranglerFile(configPath)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return null
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function createCloudflareWranglerConfig(
|
|
183
|
+
projectName: string,
|
|
184
|
+
userConfig?: Record<string, JsonValue>
|
|
185
|
+
): Record<string, JsonValue> {
|
|
186
|
+
const generatedConfig: Record<string, JsonValue> = {
|
|
187
|
+
name: projectName,
|
|
188
|
+
main: 'worker.js',
|
|
189
|
+
compatibility_date: '2024-12-05',
|
|
190
|
+
compatibility_flags: ['nodejs_compat'],
|
|
191
|
+
find_additional_modules: true,
|
|
192
|
+
rules: GENERATED_CLOUDFLARE_WRANGLER_RULES,
|
|
193
|
+
assets: {
|
|
194
|
+
directory: 'client',
|
|
195
|
+
binding: 'ASSETS',
|
|
196
|
+
run_worker_first: true,
|
|
197
|
+
},
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const mergedConfig = userConfig
|
|
201
|
+
? mergeJsonObjects(generatedConfig, userConfig)
|
|
202
|
+
: generatedConfig
|
|
203
|
+
|
|
204
|
+
mergedConfig.main = 'worker.js'
|
|
205
|
+
mergedConfig.find_additional_modules = true
|
|
206
|
+
mergedConfig.compatibility_flags = mergeCloudflareCompatibilityFlags(
|
|
207
|
+
mergedConfig.compatibility_flags
|
|
208
|
+
)
|
|
209
|
+
mergedConfig.rules = mergeCloudflareRules(mergedConfig.rules)
|
|
210
|
+
mergedConfig.assets = {
|
|
211
|
+
...(isPlainObject(mergedConfig.assets) ? mergedConfig.assets : {}),
|
|
212
|
+
directory: 'client',
|
|
213
|
+
binding: 'ASSETS',
|
|
214
|
+
run_worker_first: true,
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return mergedConfig
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function getCloudflareProjectNameSync(root: string): string {
|
|
221
|
+
try {
|
|
222
|
+
const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8'))
|
|
223
|
+
if (pkg.name) {
|
|
224
|
+
return String(pkg.name).replace(/^@[^/]+\//, '')
|
|
225
|
+
}
|
|
226
|
+
} catch {}
|
|
227
|
+
return 'one-app'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export async function getCloudflareProjectName(root: string): Promise<string> {
|
|
231
|
+
try {
|
|
232
|
+
const pkg = JSON.parse(await FSExtra.readFile(join(root, 'package.json'), 'utf-8'))
|
|
233
|
+
if (pkg.name) {
|
|
234
|
+
return pkg.name.replace(/^@[^/]+\//, '')
|
|
235
|
+
}
|
|
236
|
+
} catch {}
|
|
237
|
+
return 'one-app'
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function isExperimentalWorkerDevEnabled(): boolean {
|
|
241
|
+
return process.env.ONE_EXPERIMENTAL_WORKER_DEV === '1'
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export function shouldEnableWorkerdDev(deploy: unknown, root: string): boolean {
|
|
245
|
+
if (!isExperimentalWorkerDevEnabled()) return false
|
|
246
|
+
const target =
|
|
247
|
+
typeof deploy === 'string'
|
|
248
|
+
? deploy
|
|
249
|
+
: (deploy as { target?: string } | undefined)?.target
|
|
250
|
+
if (target === 'cloudflare') return true
|
|
251
|
+
return hasUserWranglerConfig(root)
|
|
252
|
+
}
|
package/src/vite/one.ts
CHANGED
|
@@ -34,6 +34,10 @@ import { SSRCSSPlugin } from './plugins/SSRCSSPlugin'
|
|
|
34
34
|
import { virtualEntryId } from './plugins/virtualEntryConstants'
|
|
35
35
|
import { createVirtualEntry } from './plugins/virtualEntryPlugin'
|
|
36
36
|
import { environmentGuardPlugin } from './plugins/environmentGuardPlugin'
|
|
37
|
+
import {
|
|
38
|
+
createWorkerdDevPlugins,
|
|
39
|
+
shouldEnableWorkerdDev,
|
|
40
|
+
} from './plugins/workerdDevPlugin'
|
|
37
41
|
import type { One } from './types'
|
|
38
42
|
|
|
39
43
|
type MetroOptions = MetroPluginOptions
|
|
@@ -553,7 +557,11 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
553
557
|
resolveId: {
|
|
554
558
|
filter: { id: RN_DEEP_IMPORT_RE },
|
|
555
559
|
handler(source) {
|
|
556
|
-
if (
|
|
560
|
+
if (
|
|
561
|
+
this.environment?.name === 'client' ||
|
|
562
|
+
this.environment?.name === 'ssr' ||
|
|
563
|
+
this.environment?.name === 'worker'
|
|
564
|
+
) {
|
|
557
565
|
return '\0rn-empty-module'
|
|
558
566
|
}
|
|
559
567
|
},
|
|
@@ -867,7 +875,12 @@ export function one(options: One.PluginOptions = {}): PluginOption {
|
|
|
867
875
|
return inspector ? sourceInspectorPlugin({ editor }) : []
|
|
868
876
|
})()
|
|
869
877
|
|
|
878
|
+
const workerdDevPlugins = shouldEnableWorkerdDev(options.web?.deploy, root)
|
|
879
|
+
? createWorkerdDevPlugins(options, root, routeIndex)
|
|
880
|
+
: []
|
|
881
|
+
|
|
870
882
|
return [
|
|
883
|
+
...workerdDevPlugins,
|
|
871
884
|
...vxrnPlugins,
|
|
872
885
|
...devAndProdPlugins,
|
|
873
886
|
...inspectorPlugins,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Plugin, ViteDevServer } from 'vite'
|
|
1
|
+
import type { ModuleNode, Plugin, ViteDevServer } from 'vite'
|
|
2
2
|
import { VIRTUAL_SSR_CSS_ENTRY, VIRTUAL_SSR_CSS_HREF } from '../../constants'
|
|
3
3
|
|
|
4
4
|
// thanks to hi-ogawa https://github.com/hi-ogawa/vite-plugins/tree/main/packages/ssr-css
|
|
@@ -152,6 +152,21 @@ async function collectStyleUrls(
|
|
|
152
152
|
): Promise<string[]> {
|
|
153
153
|
const visited = new Set<string>()
|
|
154
154
|
|
|
155
|
+
// every module in importedModules already carries the id vite resolved when
|
|
156
|
+
// it entered the graph, so walk them directly. resolveUrl runs the whole
|
|
157
|
+
// plugin container and was awaited once per import EDGE rather than once per
|
|
158
|
+
// module, which on a large app is the entire cost of serving this stylesheet.
|
|
159
|
+
// the walk is an explicit stack so a deep import chain cannot overflow.
|
|
160
|
+
function walk(root: ModuleNode) {
|
|
161
|
+
const stack = [root]
|
|
162
|
+
while (stack.length) {
|
|
163
|
+
const mod = stack.pop()!
|
|
164
|
+
if (!mod.id || mod.url.includes('.server.') || visited.has(mod.id)) continue
|
|
165
|
+
visited.add(mod.id)
|
|
166
|
+
for (const childMod of mod.importedModules) stack.push(childMod)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
155
170
|
async function traverse(url: string) {
|
|
156
171
|
if (url.includes('.server.')) return
|
|
157
172
|
const [, id] = await server.moduleGraph.resolveUrl(url)
|
|
@@ -163,7 +178,7 @@ async function collectStyleUrls(
|
|
|
163
178
|
if (!mod) {
|
|
164
179
|
return
|
|
165
180
|
}
|
|
166
|
-
|
|
181
|
+
for (const childMod of mod.importedModules) walk(childMod)
|
|
167
182
|
}
|
|
168
183
|
|
|
169
184
|
// ensure vite's import analysis is ready _only_ for top entries to not go too aggresive
|
|
@@ -135,6 +135,11 @@ describe('environmentGuardPlugin', () => {
|
|
|
135
135
|
expect(result).toBe('export {}')
|
|
136
136
|
})
|
|
137
137
|
|
|
138
|
+
it('web-only: allowed in worker', () => {
|
|
139
|
+
const result = loadEnvironmentGuard('\0one-env-guard:web-only:worker:server')
|
|
140
|
+
expect(result).toBe('export {}')
|
|
141
|
+
})
|
|
142
|
+
|
|
138
143
|
it('web-only: forbidden in ios', () => {
|
|
139
144
|
const result = loadEnvironmentGuard('\0one-env-guard:web-only:ios:unknown')
|
|
140
145
|
expect(result).toContain('throw new Error')
|
|
@@ -35,11 +35,11 @@ const GUARD_SPECIFIERS = [
|
|
|
35
35
|
const GUARD_SPECIFIERS_RE = new RegExp(`^(?:${GUARD_SPECIFIERS.join('|')})$`)
|
|
36
36
|
|
|
37
37
|
type GuardSpecifier = (typeof GUARD_SPECIFIERS)[number]
|
|
38
|
-
type ViteEnvironment = 'client' | 'ssr' | 'ios' | 'android'
|
|
38
|
+
type ViteEnvironment = 'client' | 'ssr' | 'ios' | 'android' | 'worker'
|
|
39
39
|
|
|
40
40
|
const ALLOWED_BY_NAME: Partial<Record<GuardSpecifier, readonly ViteEnvironment[]>> = {
|
|
41
41
|
'native-only': ['ios', 'android'],
|
|
42
|
-
'web-only': ['client', 'ssr'],
|
|
42
|
+
'web-only': ['client', 'ssr', 'worker'],
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const ALLOWED_BY_CONSUMER: Partial<Record<GuardSpecifier, 'server' | 'client'>> = {
|
|
@@ -124,6 +124,50 @@ describe('createFileSystemRouterPlugin', () => {
|
|
|
124
124
|
)
|
|
125
125
|
})
|
|
126
126
|
|
|
127
|
+
it('does not install the node request middleware when a worker environment exists', async () => {
|
|
128
|
+
process.env.IS_VXRN_CLI = '1'
|
|
129
|
+
tempRoot = mkdtempSync(path.join(tmpdir(), 'one-router-worker-'))
|
|
130
|
+
const appDir = path.join(tempRoot, 'app')
|
|
131
|
+
writeFileSync(path.join(tempRoot, 'package.json'), '{}\n')
|
|
132
|
+
mkdirSync(appDir)
|
|
133
|
+
writeFileSync(
|
|
134
|
+
path.join(appDir, 'index.tsx'),
|
|
135
|
+
'export default function Index() { return null }\n'
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
;(globalThis as any).__vxrnPluginConfig__ = {
|
|
139
|
+
web: {
|
|
140
|
+
defaultRenderMode: 'ssg',
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const { createRouteIndex } = await import('../../utils/routeIndex')
|
|
145
|
+
const { createFileSystemRouterPlugin } = await import('./fileSystemRouterPlugin')
|
|
146
|
+
const plugin = createFileSystemRouterPlugin(
|
|
147
|
+
{
|
|
148
|
+
router: { root: appDir },
|
|
149
|
+
},
|
|
150
|
+
createRouteIndex({ routerRoot: appDir })
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
const use = vi.fn()
|
|
154
|
+
const server = {
|
|
155
|
+
environments: {
|
|
156
|
+
ssr: {},
|
|
157
|
+
worker: { moduleGraph: { getModuleById: vi.fn() } },
|
|
158
|
+
},
|
|
159
|
+
middlewares: { use },
|
|
160
|
+
watcher: {
|
|
161
|
+
addListener: vi.fn(),
|
|
162
|
+
on: vi.fn(),
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const installMiddlewares = (plugin as any).configureServer(server)
|
|
167
|
+
installMiddlewares()
|
|
168
|
+
expect(use).not.toHaveBeenCalled()
|
|
169
|
+
})
|
|
170
|
+
|
|
127
171
|
it('caches dev ssg html until the module runner is invalidated', async () => {
|
|
128
172
|
process.env.VITE_ENVIRONMENT = 'ssr'
|
|
129
173
|
tempRoot = mkdtempSync(path.join(tmpdir(), 'one-router-ssg-cache-'))
|