waku 1.0.0-alpha.9 → 1.0.0-beta.1
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/README.md +35 -24
- package/dist/adapters/cloudflare.js +28 -14
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/netlify-build-enhancer.js +4 -4
- package/dist/adapters/netlify-build-enhancer.js.map +1 -1
- package/dist/adapters/vercel-build-enhancer.js +3 -2
- package/dist/adapters/vercel-build-enhancer.js.map +1 -1
- package/dist/lib/types.d.ts +5 -4
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils/managed.js +10 -11
- package/dist/lib/utils/managed.js.map +1 -1
- package/dist/lib/utils/path.js +4 -3
- package/dist/lib/utils/path.js.map +1 -1
- package/dist/lib/utils/prefetch.d.ts +23 -0
- package/dist/lib/utils/prefetch.js +49 -0
- package/dist/lib/utils/prefetch.js.map +1 -0
- package/dist/lib/utils/prune-build.d.ts +29 -0
- package/dist/lib/utils/prune-build.js +96 -0
- package/dist/lib/utils/prune-build.js.map +1 -0
- package/dist/lib/utils/react-debug-channel.d.ts +1 -3
- package/dist/lib/utils/react-debug-channel.js +6 -7
- package/dist/lib/utils/react-debug-channel.js.map +1 -1
- package/dist/lib/utils/render.d.ts +1 -1
- package/dist/lib/utils/render.js +20 -3
- package/dist/lib/utils/render.js.map +1 -1
- package/dist/lib/utils/request.js +36 -0
- package/dist/lib/utils/request.js.map +1 -1
- package/dist/lib/utils/ssr.js +2 -32
- package/dist/lib/utils/ssr.js.map +1 -1
- package/dist/lib/vite-entries/entry.browser.js +5 -0
- package/dist/lib/vite-entries/entry.browser.js.map +1 -1
- package/dist/lib/vite-entries/entry.build.d.ts +3 -1
- package/dist/lib/vite-entries/entry.build.js +13 -9
- package/dist/lib/vite-entries/entry.build.js.map +1 -1
- package/dist/lib/vite-plugins/adapter-alias.d.ts +4 -0
- package/dist/lib/vite-plugins/{default-adapter.js → adapter-alias.js} +3 -3
- package/dist/lib/vite-plugins/adapter-alias.js.map +1 -0
- package/dist/lib/vite-plugins/{user-entries.d.ts → app-entries.d.ts} +1 -1
- package/dist/lib/vite-plugins/{user-entries.js → app-entries.js} +3 -3
- package/dist/lib/vite-plugins/app-entries.js.map +1 -0
- package/dist/lib/vite-plugins/build-id.d.ts +2 -0
- package/dist/lib/vite-plugins/build-id.js +20 -0
- package/dist/lib/vite-plugins/build-id.js.map +1 -0
- package/dist/lib/vite-plugins/combined-plugins.js +34 -14
- package/dist/lib/vite-plugins/combined-plugins.js.map +1 -1
- package/dist/lib/vite-plugins/{main.d.ts → environments.d.ts} +1 -1
- package/dist/lib/vite-plugins/{main.js → environments.js} +3 -3
- package/dist/lib/vite-plugins/environments.js.map +1 -0
- package/dist/lib/vite-plugins/html-shell.d.ts +2 -0
- package/dist/lib/vite-plugins/{fallback-html.js → html-shell.js} +5 -5
- package/dist/lib/vite-plugins/html-shell.js.map +1 -0
- package/dist/lib/vite-plugins/rsc-devtools.d.ts +2 -0
- package/dist/lib/vite-plugins/{react-debug.js → rsc-devtools.js} +3 -3
- package/dist/lib/vite-plugins/rsc-devtools.js.map +1 -0
- package/dist/lib/vite-plugins/static-build.d.ts +5 -0
- package/dist/lib/vite-plugins/{build-static-files.js → static-build.js} +23 -5
- package/dist/lib/vite-plugins/static-build.js.map +1 -0
- package/dist/lib/vite-rsc/handler.js +15 -6
- package/dist/lib/vite-rsc/handler.js.map +1 -1
- package/dist/lib/vite-rsc/ssr.js +2 -2
- package/dist/lib/vite-rsc/ssr.js.map +1 -1
- package/dist/minimal/client.d.ts +3 -0
- package/dist/minimal/client.js +39 -34
- package/dist/minimal/client.js.map +1 -1
- package/dist/router/client.d.ts +1 -3
- package/dist/router/client.js +45 -48
- package/dist/router/client.js.map +1 -1
- package/dist/router/create-pages.d.ts +36 -2
- package/dist/router/create-pages.js +318 -321
- package/dist/router/create-pages.js.map +1 -1
- package/dist/router/define-router.d.ts +9 -2
- package/dist/router/define-router.js +171 -85
- package/dist/router/define-router.js.map +1 -1
- package/dist/router/fs-router.d.ts +18 -6
- package/dist/router/fs-router.js +28 -25
- package/dist/router/fs-router.js.map +1 -1
- package/dist/router/server.d.ts +1 -0
- package/dist/router/server.js.map +1 -1
- package/dist/vite-plugins.d.ts +5 -5
- package/dist/vite-plugins.js +5 -5
- package/dist/vite-plugins.js.map +1 -1
- package/package.json +7 -7
- package/dist/lib/vite-plugins/build-static-files.d.ts +0 -4
- package/dist/lib/vite-plugins/build-static-files.js.map +0 -1
- package/dist/lib/vite-plugins/default-adapter.d.ts +0 -4
- package/dist/lib/vite-plugins/default-adapter.js.map +0 -1
- package/dist/lib/vite-plugins/fallback-html.d.ts +0 -2
- package/dist/lib/vite-plugins/fallback-html.js.map +0 -1
- package/dist/lib/vite-plugins/main.js.map +0 -1
- package/dist/lib/vite-plugins/react-debug.d.ts +0 -2
- package/dist/lib/vite-plugins/react-debug.js.map +0 -1
- package/dist/lib/vite-plugins/user-entries.js.map +0 -1
package/README.md
CHANGED
|
@@ -15,8 +15,6 @@ visit [waku.gg](https://waku.gg) or `npm create waku@latest`
|
|
|
15
15
|
|
|
16
16
|
**Waku** _(wah-ku)_ or **わく** is the minimal React framework. It’s lightweight and designed for a fun developer experience, yet supports all the latest React 19 features like server components and actions. Built for marketing sites, headless commerce, and web apps. For large enterprise applications, you may prefer a heavier framework.
|
|
17
17
|
|
|
18
|
-
> Please try Waku on non-production projects and report any issues you find. Contributors are welcome.
|
|
19
|
-
|
|
20
18
|
## Getting started
|
|
21
19
|
|
|
22
20
|
Start a new Waku project with the `create` command for your preferred package manager. It will scaffold a new project with our default [Waku starter](https://github.com/wakujs/waku/tree/main/examples/01_template).
|
|
@@ -31,7 +29,7 @@ npm create waku@latest
|
|
|
31
29
|
- `waku build` to generate a production build
|
|
32
30
|
- `waku start` to serve the production build locally
|
|
33
31
|
|
|
34
|
-
**Node.js version requirement:** `^
|
|
32
|
+
**Node.js version requirement:** `^26.0.0` or `^24.0.0` or `^22.13.0`
|
|
35
33
|
|
|
36
34
|
## Rendering
|
|
37
35
|
|
|
@@ -761,7 +759,7 @@ This allows you to have a `dynamic` slice component while keeping the rest of th
|
|
|
761
759
|
|
|
762
760
|
### Link
|
|
763
761
|
|
|
764
|
-
The `<Link />` component should be used for internal links. It accepts a `to` prop for the destination
|
|
762
|
+
The `<Link />` component should be used for internal links. It accepts a `to` prop for the destination and handles client-side navigation through Waku's router.
|
|
765
763
|
|
|
766
764
|
```tsx
|
|
767
765
|
// ./src/pages/index.tsx
|
|
@@ -1027,6 +1025,26 @@ export const getConfig = async () => {
|
|
|
1027
1025
|
};
|
|
1028
1026
|
```
|
|
1029
1027
|
|
|
1028
|
+
## Middleware
|
|
1029
|
+
|
|
1030
|
+
In the default Waku setup, files in `./src/middleware` are automatically loaded as [Hono middleware](https://hono.dev/docs/guides/middleware). Each file should default export a function that returns a `MiddlewareHandler`.
|
|
1031
|
+
|
|
1032
|
+
```ts
|
|
1033
|
+
// ./src/middleware/logger.ts
|
|
1034
|
+
import type { MiddlewareHandler } from 'hono';
|
|
1035
|
+
|
|
1036
|
+
const logger = (): MiddlewareHandler => {
|
|
1037
|
+
return async (c, next) => {
|
|
1038
|
+
console.log(c.req.method, c.req.path);
|
|
1039
|
+
await next();
|
|
1040
|
+
};
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
export default logger;
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
If you provide a custom `./src/waku.server.tsx`, pass middleware through the adapter options with `middlewareModules` or `middlewareFns`.
|
|
1047
|
+
|
|
1030
1048
|
## Data fetching
|
|
1031
1049
|
|
|
1032
1050
|
### Server
|
|
@@ -1454,10 +1472,9 @@ For advanced users who want to avoid deploying functions, use the server entry f
|
|
|
1454
1472
|
import { fsRouter } from 'waku';
|
|
1455
1473
|
import adapter from 'waku/adapters/vercel';
|
|
1456
1474
|
|
|
1457
|
-
export default adapter(
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
);
|
|
1475
|
+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
|
|
1476
|
+
static: true,
|
|
1477
|
+
});
|
|
1461
1478
|
```
|
|
1462
1479
|
|
|
1463
1480
|
### Netlify
|
|
@@ -1479,10 +1496,9 @@ For advanced users who want to avoid deploying functions, use the server entry f
|
|
|
1479
1496
|
import { fsRouter } from 'waku';
|
|
1480
1497
|
import adapter from 'waku/adapters/netlify';
|
|
1481
1498
|
|
|
1482
|
-
export default adapter(
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
);
|
|
1499
|
+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
|
|
1500
|
+
static: true,
|
|
1501
|
+
});
|
|
1486
1502
|
```
|
|
1487
1503
|
|
|
1488
1504
|
### Cloudflare Workers
|
|
@@ -1502,10 +1518,9 @@ wrangler deploy
|
|
|
1502
1518
|
import { fsRouter } from 'waku';
|
|
1503
1519
|
import adapter from 'waku/adapters/cloudflare';
|
|
1504
1520
|
|
|
1505
|
-
export default adapter(
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
);
|
|
1521
|
+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
|
|
1522
|
+
static: true,
|
|
1523
|
+
});
|
|
1509
1524
|
```
|
|
1510
1525
|
|
|
1511
1526
|
### Deno Deploy (experimental)
|
|
@@ -1516,9 +1531,7 @@ export default adapter(
|
|
|
1516
1531
|
import { fsRouter } from 'waku';
|
|
1517
1532
|
import adapter from 'waku/adapters/deno';
|
|
1518
1533
|
|
|
1519
|
-
export default adapter(
|
|
1520
|
-
fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
|
|
1521
|
-
);
|
|
1534
|
+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')));
|
|
1522
1535
|
```
|
|
1523
1536
|
|
|
1524
1537
|
```sh
|
|
@@ -1534,9 +1547,7 @@ deployctl deploy --prod dist/serve-deno.js --exclude node_modules
|
|
|
1534
1547
|
import { fsRouter } from 'waku';
|
|
1535
1548
|
import adapter from 'waku/adapters/bun';
|
|
1536
1549
|
|
|
1537
|
-
export default adapter(
|
|
1538
|
-
fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
|
|
1539
|
-
);
|
|
1550
|
+
export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')));
|
|
1540
1551
|
```
|
|
1541
1552
|
|
|
1542
1553
|
```sh
|
|
@@ -1552,8 +1563,8 @@ import { fsRouter } from 'waku';
|
|
|
1552
1563
|
import adapter from 'waku/adapters/aws-lambda';
|
|
1553
1564
|
|
|
1554
1565
|
export default adapter(
|
|
1555
|
-
fsRouter(import.meta.glob('
|
|
1556
|
-
streaming: false, // optional, default is false
|
|
1566
|
+
fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')),
|
|
1567
|
+
{ streaming: false }, // optional, default is false
|
|
1557
1568
|
);
|
|
1558
1569
|
```
|
|
1559
1570
|
|
|
@@ -4,6 +4,12 @@ import { unstable_constants as constants, unstable_consumeMultiplexedStream as c
|
|
|
4
4
|
const { DIST_PUBLIC } = constants;
|
|
5
5
|
const { contextMiddleware, rscMiddleware, middlewareRunner } = honoMiddleware;
|
|
6
6
|
const DO_NOT_BUNDLE = '';
|
|
7
|
+
const PRUNABLE_KEY_PREFIX = '\0__prunable__/';
|
|
8
|
+
const emptyStream = ()=>new ReadableStream({
|
|
9
|
+
start (controller) {
|
|
10
|
+
controller.close();
|
|
11
|
+
}
|
|
12
|
+
});
|
|
7
13
|
function isWranglerDev(req) {
|
|
8
14
|
// This header seems to only be set for production cloudflare workers
|
|
9
15
|
return !req.headers.get('cf-visitor');
|
|
@@ -44,14 +50,15 @@ export default createServerEntryAdapter(({ processRequest, processBuild, setAllE
|
|
|
44
50
|
DIST_PUBLIC,
|
|
45
51
|
serverless: !options?.static
|
|
46
52
|
};
|
|
53
|
+
const buildBody = ()=>produceMultiplexedStream(async (emitFile)=>{
|
|
54
|
+
await processBuild({
|
|
55
|
+
emitFile,
|
|
56
|
+
unstable_registerPrunableFile: (srcPath)=>emitFile(PRUNABLE_KEY_PREFIX + srcPath, emptyStream())
|
|
57
|
+
});
|
|
58
|
+
});
|
|
47
59
|
const fetchFn = async (req)=>{
|
|
48
60
|
if (new URL(req.url).pathname === `/${internalPathToBuildStaticFiles}`) {
|
|
49
|
-
|
|
50
|
-
await processBuild({
|
|
51
|
-
emitFile
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
return new Response(body);
|
|
61
|
+
return new Response(buildBody());
|
|
55
62
|
}
|
|
56
63
|
let cloudflareContext;
|
|
57
64
|
try {
|
|
@@ -88,18 +95,25 @@ export default createServerEntryAdapter(({ processRequest, processBuild, setAllE
|
|
|
88
95
|
server.middlewares.use(async (_req, res, next)=>{
|
|
89
96
|
try {
|
|
90
97
|
const { Readable } = await import(/* @vite-ignore */ DO_NOT_BUNDLE + 'node:stream');
|
|
91
|
-
|
|
92
|
-
await processBuild({
|
|
93
|
-
emitFile
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
Readable.fromWeb(body).pipe(res);
|
|
98
|
+
Readable.fromWeb(buildBody()).pipe(res);
|
|
97
99
|
} catch (err) {
|
|
98
100
|
next(err);
|
|
99
101
|
}
|
|
100
102
|
});
|
|
101
|
-
const response = await fetch(server.baseUrl + internalPathToBuildStaticFiles
|
|
102
|
-
|
|
103
|
+
const response = await fetch(server.baseUrl + internalPathToBuildStaticFiles, {
|
|
104
|
+
headers: {
|
|
105
|
+
connection: 'close'
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
await consumeMultiplexedStream(response.body, async (key, stream)=>{
|
|
109
|
+
if (key.startsWith(PRUNABLE_KEY_PREFIX)) {
|
|
110
|
+
utils.unstable_registerPrunableFile(key.slice(PRUNABLE_KEY_PREFIX.length));
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
await utils.emitFile(key, stream);
|
|
114
|
+
});
|
|
115
|
+
// https://github.com/nodejs/node/issues/56645
|
|
116
|
+
await new Promise((resolve)=>setTimeout(resolve, 100));
|
|
103
117
|
await server.close();
|
|
104
118
|
},
|
|
105
119
|
buildOptions,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/cloudflare.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { Hono } from 'hono/tiny';\nimport {\n unstable_createServerEntryAdapter as createServerEntryAdapter,\n unstable_startPreviewServer as startPreviewServer,\n} from 'waku/adapter-builders';\nimport {\n unstable_constants as constants,\n unstable_consumeMultiplexedStream as consumeMultiplexedStream,\n unstable_honoMiddleware as honoMiddleware,\n unstable_produceMultiplexedStream as produceMultiplexedStream,\n} from 'waku/internals';\nimport type { BuildOptions } from './cloudflare-build-enhancer.js';\n\nconst { DIST_PUBLIC } = constants;\nconst { contextMiddleware, rscMiddleware, middlewareRunner } = honoMiddleware;\n\nconst DO_NOT_BUNDLE = '';\n\nfunction isWranglerDev(req: Request): boolean {\n // This header seems to only be set for production cloudflare workers\n return !req.headers.get('cf-visitor');\n}\n\nfunction removeGzipEncoding(res: Response): Response {\n const contentType = res.headers.get('content-type');\n if (\n !contentType ||\n contentType.includes('text/html') ||\n contentType.includes('text/plain')\n ) {\n const headers = new Headers(res.headers);\n headers.set('content-encoding', 'Identity');\n return new Response(res.body, {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n }\n return res;\n}\n\nexport default createServerEntryAdapter(\n (\n { processRequest, processBuild, setAllEnv, config, notFoundHtml },\n options?: {\n static?: boolean;\n handlers?: Record<string, unknown>;\n assetsDir?: string;\n middlewareFns?: (() => MiddlewareHandler)[];\n middlewareModules?: Record<string, () => Promise<unknown>>;\n internalPathToBuildStaticFiles?: string;\n },\n ) => {\n const {\n middlewareFns = [],\n middlewareModules = {},\n internalPathToBuildStaticFiles = '__waku_internal_build_static_files',\n } = options || {};\n const app = new Hono();\n app.notFound((c) => {\n if (notFoundHtml) {\n return c.html(notFoundHtml, 404);\n }\n return c.text('404 Not Found', 404);\n });\n app.use(contextMiddleware());\n for (const middlewareFn of middlewareFns) {\n app.use(middlewareFn());\n }\n app.use(middlewareRunner(middlewareModules as never));\n app.use(rscMiddleware({ processRequest }));\n const buildOptions: BuildOptions = {\n srcDir: config.srcDir,\n distDir: config.distDir,\n DIST_PUBLIC,\n serverless: !options?.static,\n };\n\n const fetchFn = async (req: Request) => {\n if (new URL(req.url).pathname === `/${internalPathToBuildStaticFiles}`) {\n const body = produceMultiplexedStream(async (emitFile) => {\n await processBuild({ emitFile });\n });\n return new Response(body);\n }\n let cloudflareContext;\n try {\n cloudflareContext = await import(\n /* @vite-ignore */ DO_NOT_BUNDLE + 'cloudflare:workers'\n );\n } catch {\n // Not in a Cloudflare environment\n }\n let res: Response | Promise<Response>;\n if (cloudflareContext) {\n const { env, waitUntil, passThroughOnException } = cloudflareContext;\n res = app.fetch(req, env, {\n waitUntil,\n passThroughOnException,\n props: undefined,\n });\n } else {\n res = app.fetch(req);\n }\n // Workaround https://github.com/cloudflare/workers-sdk/issues/6577\n if (import.meta.env?.PROD && isWranglerDev(req)) {\n if ('then' in res) {\n res = res.then((res) => removeGzipEncoding(res));\n } else {\n res = removeGzipEncoding(res);\n }\n }\n return res;\n };\n\n return {\n fetch: fetchFn,\n build: async (utils) => {\n const server = await startPreviewServer();\n // Fallback middleware for the case without @cloudflare/vite-plugin\n server.middlewares.use(async (_req, res, next) => {\n try {\n const { Readable } = await import(\n /* @vite-ignore */ DO_NOT_BUNDLE + 'node:stream'\n );\n const body = produceMultiplexedStream(async (emitFile) => {\n await processBuild({ emitFile });\n });\n Readable.fromWeb(body as never).pipe(res);\n } catch (err) {\n next(err);\n }\n });\n const response = await fetch(\n server.baseUrl + internalPathToBuildStaticFiles,\n );\n await consumeMultiplexedStream(response.body!, utils.emitFile);\n await server.close();\n },\n buildOptions,\n buildEnhancers: ['waku/adapters/cloudflare-build-enhancer'],\n defaultExport: {\n ...options?.handlers,\n fetch(req: Request, env: Record<string, string>) {\n setAllEnv(env);\n return fetchFn(req);\n },\n },\n };\n },\n);\n"],"names":["Hono","unstable_createServerEntryAdapter","createServerEntryAdapter","unstable_startPreviewServer","startPreviewServer","unstable_constants","constants","unstable_consumeMultiplexedStream","consumeMultiplexedStream","unstable_honoMiddleware","honoMiddleware","unstable_produceMultiplexedStream","produceMultiplexedStream","DIST_PUBLIC","contextMiddleware","rscMiddleware","middlewareRunner","DO_NOT_BUNDLE","isWranglerDev","req","headers","get","removeGzipEncoding","res","contentType","includes","Headers","set","Response","body","status","statusText","processRequest","processBuild","setAllEnv","config","notFoundHtml","options","middlewareFns","middlewareModules","internalPathToBuildStaticFiles","app","notFound","c","html","text","use","middlewareFn","buildOptions","srcDir","distDir","serverless","static","fetchFn","URL","url","pathname","emitFile","cloudflareContext","env","waitUntil","passThroughOnException","fetch","props","undefined","PROD","then","build","utils","server","middlewares","_req","next","Readable","fromWeb","pipe","err","response","baseUrl","close","buildEnhancers","defaultExport","handlers"],"mappings":"AACA,SAASA,IAAI,QAAQ,YAAY;AACjC,SACEC,qCAAqCC,wBAAwB,EAC7DC,+BAA+BC,kBAAkB,QAC5C,wBAAwB;AAC/B,SACEC,sBAAsBC,SAAS,EAC/BC,qCAAqCC,wBAAwB,EAC7DC,2BAA2BC,cAAc,EACzCC,qCAAqCC,wBAAwB,QACxD,iBAAiB;AAGxB,MAAM,EAAEC,WAAW,EAAE,GAAGP;AACxB,MAAM,EAAEQ,iBAAiB,EAAEC,aAAa,EAAEC,gBAAgB,EAAE,GAAGN;AAE/D,MAAMO,gBAAgB;AAEtB,SAASC,cAAcC,GAAY;IACjC,qEAAqE;IACrE,OAAO,CAACA,IAAIC,OAAO,CAACC,GAAG,CAAC;AAC1B;AAEA,SAASC,mBAAmBC,GAAa;IACvC,MAAMC,cAAcD,IAAIH,OAAO,CAACC,GAAG,CAAC;IACpC,IACE,CAACG,eACDA,YAAYC,QAAQ,CAAC,gBACrBD,YAAYC,QAAQ,CAAC,eACrB;QACA,MAAML,UAAU,IAAIM,QAAQH,IAAIH,OAAO;QACvCA,QAAQO,GAAG,CAAC,oBAAoB;QAChC,OAAO,IAAIC,SAASL,IAAIM,IAAI,EAAE;YAC5BC,QAAQP,IAAIO,MAAM;YAClBC,YAAYR,IAAIQ,UAAU;YAC1BX;QACF;IACF;IACA,OAAOG;AACT;AAEA,eAAerB,yBACb,CACE,EAAE8B,cAAc,EAAEC,YAAY,EAAEC,SAAS,EAAEC,MAAM,EAAEC,YAAY,EAAE,EACjEC;IASA,MAAM,EACJC,gBAAgB,EAAE,EAClBC,oBAAoB,CAAC,CAAC,EACtBC,iCAAiC,oCAAoC,EACtE,GAAGH,WAAW,CAAC;IAChB,MAAMI,MAAM,IAAIzC;IAChByC,IAAIC,QAAQ,CAAC,CAACC;QACZ,IAAIP,cAAc;YAChB,OAAOO,EAAEC,IAAI,CAACR,cAAc;QAC9B;QACA,OAAOO,EAAEE,IAAI,CAAC,iBAAiB;IACjC;IACAJ,IAAIK,GAAG,CAAChC;IACR,KAAK,MAAMiC,gBAAgBT,cAAe;QACxCG,IAAIK,GAAG,CAACC;IACV;IACAN,IAAIK,GAAG,CAAC9B,iBAAiBuB;IACzBE,IAAIK,GAAG,CAAC/B,cAAc;QAAEiB;IAAe;IACvC,MAAMgB,eAA6B;QACjCC,QAAQd,OAAOc,MAAM;QACrBC,SAASf,OAAOe,OAAO;QACvBrC;QACAsC,YAAY,CAACd,SAASe;IACxB;IAEA,MAAMC,UAAU,OAAOlC;QACrB,IAAI,IAAImC,IAAInC,IAAIoC,GAAG,EAAEC,QAAQ,KAAK,CAAC,CAAC,EAAEhB,gCAAgC,EAAE;YACtE,MAAMX,OAAOjB,yBAAyB,OAAO6C;gBAC3C,MAAMxB,aAAa;oBAAEwB;gBAAS;YAChC;YACA,OAAO,IAAI7B,SAASC;QACtB;QACA,IAAI6B;QACJ,IAAI;YACFA,oBAAoB,MAAM,MAAM,CAC9B,gBAAgB,GAAGzC,gBAAgB;QAEvC,EAAE,OAAM;QACN,kCAAkC;QACpC;QACA,IAAIM;QACJ,IAAImC,mBAAmB;YACrB,MAAM,EAAEC,GAAG,EAAEC,SAAS,EAAEC,sBAAsB,EAAE,GAAGH;YACnDnC,MAAMkB,IAAIqB,KAAK,CAAC3C,KAAKwC,KAAK;gBACxBC;gBACAC;gBACAE,OAAOC;YACT;QACF,OAAO;YACLzC,MAAMkB,IAAIqB,KAAK,CAAC3C;QAClB;QACA,mEAAmE;QACnE,IAAI,YAAYwC,GAAG,EAAEM,QAAQ/C,cAAcC,MAAM;YAC/C,IAAI,UAAUI,KAAK;gBACjBA,MAAMA,IAAI2C,IAAI,CAAC,CAAC3C,MAAQD,mBAAmBC;YAC7C,OAAO;gBACLA,MAAMD,mBAAmBC;YAC3B;QACF;QACA,OAAOA;IACT;IAEA,OAAO;QACLuC,OAAOT;QACPc,OAAO,OAAOC;YACZ,MAAMC,SAAS,MAAMjE;YACrB,mEAAmE;YACnEiE,OAAOC,WAAW,CAACxB,GAAG,CAAC,OAAOyB,MAAMhD,KAAKiD;gBACvC,IAAI;oBACF,MAAM,EAAEC,QAAQ,EAAE,GAAG,MAAM,MAAM,CAC/B,gBAAgB,GAAGxD,gBAAgB;oBAErC,MAAMY,OAAOjB,yBAAyB,OAAO6C;wBAC3C,MAAMxB,aAAa;4BAAEwB;wBAAS;oBAChC;oBACAgB,SAASC,OAAO,CAAC7C,MAAe8C,IAAI,CAACpD;gBACvC,EAAE,OAAOqD,KAAK;oBACZJ,KAAKI;gBACP;YACF;YACA,MAAMC,WAAW,MAAMf,MACrBO,OAAOS,OAAO,GAAGtC;YAEnB,MAAMhC,yBAAyBqE,SAAShD,IAAI,EAAGuC,MAAMX,QAAQ;YAC7D,MAAMY,OAAOU,KAAK;QACpB;QACA/B;QACAgC,gBAAgB;YAAC;SAA0C;QAC3DC,eAAe;YACb,GAAG5C,SAAS6C,QAAQ;YACpBpB,OAAM3C,GAAY,EAAEwC,GAA2B;gBAC7CzB,UAAUyB;gBACV,OAAON,QAAQlC;YACjB;QACF;IACF;AACF,GACA"}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/cloudflare.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono';\nimport { Hono } from 'hono/tiny';\nimport {\n unstable_createServerEntryAdapter as createServerEntryAdapter,\n unstable_startPreviewServer as startPreviewServer,\n} from 'waku/adapter-builders';\nimport {\n unstable_constants as constants,\n unstable_consumeMultiplexedStream as consumeMultiplexedStream,\n unstable_honoMiddleware as honoMiddleware,\n unstable_produceMultiplexedStream as produceMultiplexedStream,\n} from 'waku/internals';\nimport type { BuildOptions } from './cloudflare-build-enhancer.js';\n\nconst { DIST_PUBLIC } = constants;\nconst { contextMiddleware, rscMiddleware, middlewareRunner } = honoMiddleware;\n\nconst DO_NOT_BUNDLE = '';\n\nconst PRUNABLE_KEY_PREFIX = '\\0__prunable__/';\n\nconst emptyStream = () =>\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.close();\n },\n });\n\nfunction isWranglerDev(req: Request): boolean {\n // This header seems to only be set for production cloudflare workers\n return !req.headers.get('cf-visitor');\n}\n\nfunction removeGzipEncoding(res: Response): Response {\n const contentType = res.headers.get('content-type');\n if (\n !contentType ||\n contentType.includes('text/html') ||\n contentType.includes('text/plain')\n ) {\n const headers = new Headers(res.headers);\n headers.set('content-encoding', 'Identity');\n return new Response(res.body, {\n status: res.status,\n statusText: res.statusText,\n headers,\n });\n }\n return res;\n}\n\nexport default createServerEntryAdapter(\n (\n { processRequest, processBuild, setAllEnv, config, notFoundHtml },\n options?: {\n static?: boolean;\n handlers?: Record<string, unknown>;\n assetsDir?: string;\n middlewareFns?: (() => MiddlewareHandler)[];\n middlewareModules?: Record<string, () => Promise<unknown>>;\n internalPathToBuildStaticFiles?: string;\n },\n ) => {\n const {\n middlewareFns = [],\n middlewareModules = {},\n internalPathToBuildStaticFiles = '__waku_internal_build_static_files',\n } = options || {};\n const app = new Hono();\n app.notFound((c) => {\n if (notFoundHtml) {\n return c.html(notFoundHtml, 404);\n }\n return c.text('404 Not Found', 404);\n });\n app.use(contextMiddleware());\n for (const middlewareFn of middlewareFns) {\n app.use(middlewareFn());\n }\n app.use(middlewareRunner(middlewareModules as never));\n app.use(rscMiddleware({ processRequest }));\n const buildOptions: BuildOptions = {\n srcDir: config.srcDir,\n distDir: config.distDir,\n DIST_PUBLIC,\n serverless: !options?.static,\n };\n\n const buildBody = () =>\n produceMultiplexedStream(async (emitFile) => {\n await processBuild({\n emitFile,\n unstable_registerPrunableFile: (srcPath) =>\n emitFile(PRUNABLE_KEY_PREFIX + srcPath, emptyStream()),\n });\n });\n\n const fetchFn = async (req: Request) => {\n if (new URL(req.url).pathname === `/${internalPathToBuildStaticFiles}`) {\n return new Response(buildBody());\n }\n let cloudflareContext;\n try {\n cloudflareContext = await import(\n /* @vite-ignore */ DO_NOT_BUNDLE + 'cloudflare:workers'\n );\n } catch {\n // Not in a Cloudflare environment\n }\n let res: Response | Promise<Response>;\n if (cloudflareContext) {\n const { env, waitUntil, passThroughOnException } = cloudflareContext;\n res = app.fetch(req, env, {\n waitUntil,\n passThroughOnException,\n props: undefined,\n });\n } else {\n res = app.fetch(req);\n }\n // Workaround https://github.com/cloudflare/workers-sdk/issues/6577\n if (import.meta.env?.PROD && isWranglerDev(req)) {\n if ('then' in res) {\n res = res.then((res) => removeGzipEncoding(res));\n } else {\n res = removeGzipEncoding(res);\n }\n }\n return res;\n };\n\n return {\n fetch: fetchFn,\n build: async (utils) => {\n const server = await startPreviewServer();\n // Fallback middleware for the case without @cloudflare/vite-plugin\n server.middlewares.use(async (_req, res, next) => {\n try {\n const { Readable } = await import(\n /* @vite-ignore */ DO_NOT_BUNDLE + 'node:stream'\n );\n Readable.fromWeb(buildBody() as never).pipe(res);\n } catch (err) {\n next(err);\n }\n });\n const response = await fetch(\n server.baseUrl + internalPathToBuildStaticFiles,\n { headers: { connection: 'close' } },\n );\n await consumeMultiplexedStream(response.body!, async (key, stream) => {\n if (key.startsWith(PRUNABLE_KEY_PREFIX)) {\n utils.unstable_registerPrunableFile(\n key.slice(PRUNABLE_KEY_PREFIX.length),\n );\n return;\n }\n await utils.emitFile(key, stream);\n });\n // https://github.com/nodejs/node/issues/56645\n await new Promise((resolve) => setTimeout(resolve, 100));\n await server.close();\n },\n buildOptions,\n buildEnhancers: ['waku/adapters/cloudflare-build-enhancer'],\n defaultExport: {\n ...options?.handlers,\n fetch(req: Request, env: Record<string, string>) {\n setAllEnv(env);\n return fetchFn(req);\n },\n },\n };\n },\n);\n"],"names":["Hono","unstable_createServerEntryAdapter","createServerEntryAdapter","unstable_startPreviewServer","startPreviewServer","unstable_constants","constants","unstable_consumeMultiplexedStream","consumeMultiplexedStream","unstable_honoMiddleware","honoMiddleware","unstable_produceMultiplexedStream","produceMultiplexedStream","DIST_PUBLIC","contextMiddleware","rscMiddleware","middlewareRunner","DO_NOT_BUNDLE","PRUNABLE_KEY_PREFIX","emptyStream","ReadableStream","start","controller","close","isWranglerDev","req","headers","get","removeGzipEncoding","res","contentType","includes","Headers","set","Response","body","status","statusText","processRequest","processBuild","setAllEnv","config","notFoundHtml","options","middlewareFns","middlewareModules","internalPathToBuildStaticFiles","app","notFound","c","html","text","use","middlewareFn","buildOptions","srcDir","distDir","serverless","static","buildBody","emitFile","unstable_registerPrunableFile","srcPath","fetchFn","URL","url","pathname","cloudflareContext","env","waitUntil","passThroughOnException","fetch","props","undefined","PROD","then","build","utils","server","middlewares","_req","next","Readable","fromWeb","pipe","err","response","baseUrl","connection","key","stream","startsWith","slice","length","Promise","resolve","setTimeout","buildEnhancers","defaultExport","handlers"],"mappings":"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"}
|
|
@@ -7,14 +7,14 @@ async function postBuild({ distDir, privateDir, rscBase, DIST_PUBLIC, serverless
|
|
|
7
7
|
recursive: true
|
|
8
8
|
});
|
|
9
9
|
writeFileSync(path.join(functionsDir, 'serve.js'), `\
|
|
10
|
-
const { INTERNAL_runFetch } = await import(
|
|
10
|
+
const { INTERNAL_runFetch } = await import(${JSON.stringify(`../${distDir}/server/index.js`)});
|
|
11
11
|
|
|
12
12
|
export default async (request, context) =>
|
|
13
13
|
INTERNAL_runFetch(process.env, request, { context });
|
|
14
14
|
|
|
15
15
|
export const config = {
|
|
16
16
|
preferStatic: true,
|
|
17
|
-
path: ['/', '/*',
|
|
17
|
+
path: ['/', '/*', ${JSON.stringify(`/${rscBase}/**/*`)}],
|
|
18
18
|
};
|
|
19
19
|
`);
|
|
20
20
|
}
|
|
@@ -23,9 +23,9 @@ export const config = {
|
|
|
23
23
|
writeFileSync(netlifyTomlFile, `\
|
|
24
24
|
[build]
|
|
25
25
|
command = "npm run build"
|
|
26
|
-
publish =
|
|
26
|
+
publish = ${JSON.stringify(`${distDir}/${DIST_PUBLIC}`)}
|
|
27
27
|
[functions]
|
|
28
|
-
included_files = [
|
|
28
|
+
included_files = [${JSON.stringify(`${privateDir}/**`)}]
|
|
29
29
|
directory = "netlify-functions"
|
|
30
30
|
`);
|
|
31
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/netlify-build-enhancer.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nexport type BuildOptions = {\n distDir: string;\n privateDir: string;\n rscBase: string;\n DIST_PUBLIC: string;\n serverless: boolean;\n};\n\nasync function postBuild({\n distDir,\n privateDir,\n rscBase,\n DIST_PUBLIC,\n serverless,\n}: BuildOptions) {\n if (serverless) {\n const functionsDir = path.resolve('netlify-functions');\n mkdirSync(functionsDir, {\n recursive: true,\n });\n writeFileSync(\n path.join(functionsDir, 'serve.js'),\n `\\\nconst { INTERNAL_runFetch } = await import(
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/netlify-build-enhancer.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nexport type BuildOptions = {\n distDir: string;\n privateDir: string;\n rscBase: string;\n DIST_PUBLIC: string;\n serverless: boolean;\n};\n\nasync function postBuild({\n distDir,\n privateDir,\n rscBase,\n DIST_PUBLIC,\n serverless,\n}: BuildOptions) {\n if (serverless) {\n const functionsDir = path.resolve('netlify-functions');\n mkdirSync(functionsDir, {\n recursive: true,\n });\n writeFileSync(\n path.join(functionsDir, 'serve.js'),\n `\\\nconst { INTERNAL_runFetch } = await import(${JSON.stringify(`../${distDir}/server/index.js`)});\n\nexport default async (request, context) =>\n INTERNAL_runFetch(process.env, request, { context });\n\nexport const config = {\n preferStatic: true,\n path: ['/', '/*', ${JSON.stringify(`/${rscBase}/**/*`)}],\n};\n`,\n );\n }\n const netlifyTomlFile = path.resolve('netlify.toml');\n if (!existsSync(netlifyTomlFile)) {\n writeFileSync(\n netlifyTomlFile,\n `\\\n[build]\n command = \"npm run build\"\n publish = ${JSON.stringify(`${distDir}/${DIST_PUBLIC}`)}\n[functions]\n included_files = [${JSON.stringify(`${privateDir}/**`)}]\n directory = \"netlify-functions\"\n`,\n );\n }\n}\n\nexport default async function buildEnhancer(\n build: (utils: unknown, options: BuildOptions) => Promise<void>,\n): Promise<typeof build> {\n return async (utils: unknown, options: BuildOptions) => {\n await build(utils, options);\n await postBuild(options);\n };\n}\n"],"names":["existsSync","mkdirSync","writeFileSync","path","postBuild","distDir","privateDir","rscBase","DIST_PUBLIC","serverless","functionsDir","resolve","recursive","join","JSON","stringify","netlifyTomlFile","buildEnhancer","build","utils","options"],"mappings":"AAAA,SAASA,UAAU,EAAEC,SAAS,EAAEC,aAAa,QAAQ,UAAU;AAC/D,OAAOC,UAAU,YAAY;AAU7B,eAAeC,UAAU,EACvBC,OAAO,EACPC,UAAU,EACVC,OAAO,EACPC,WAAW,EACXC,UAAU,EACG;IACb,IAAIA,YAAY;QACd,MAAMC,eAAeP,KAAKQ,OAAO,CAAC;QAClCV,UAAUS,cAAc;YACtBE,WAAW;QACb;QACAV,cACEC,KAAKU,IAAI,CAACH,cAAc,aACxB,CAAC;2CACoC,EAAEI,KAAKC,SAAS,CAAC,CAAC,GAAG,EAAEV,QAAQ,gBAAgB,CAAC,EAAE;;;;;;;oBAOzE,EAAES,KAAKC,SAAS,CAAC,CAAC,CAAC,EAAER,QAAQ,KAAK,CAAC,EAAE;;AAEzD,CAAC;IAEC;IACA,MAAMS,kBAAkBb,KAAKQ,OAAO,CAAC;IACrC,IAAI,CAACX,WAAWgB,kBAAkB;QAChCd,cACEc,iBACA,CAAC;;;YAGK,EAAEF,KAAKC,SAAS,CAAC,GAAGV,QAAQ,CAAC,EAAEG,aAAa,EAAE;;oBAEtC,EAAEM,KAAKC,SAAS,CAAC,GAAGT,WAAW,GAAG,CAAC,EAAE;;AAEzD,CAAC;IAEC;AACF;AAEA,eAAe,eAAeW,cAC5BC,KAA+D;IAE/D,OAAO,OAAOC,OAAgBC;QAC5B,MAAMF,MAAMC,OAAOC;QACnB,MAAMhB,UAAUgB;IAClB;AACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cpSync, existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
const escapeRegExp = (s)=>s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
|
|
3
4
|
async function postBuild({ assetsDir, distDir, rscBase, privateDir, basePath, DIST_PUBLIC, serverless }) {
|
|
4
5
|
const SERVE_JS = 'serve-vercel.js';
|
|
5
6
|
const serveCode = `
|
|
@@ -49,7 +50,7 @@ export default getRequestListener(
|
|
|
49
50
|
}
|
|
50
51
|
const routes = [
|
|
51
52
|
{
|
|
52
|
-
src: `^${basePath}${assetsDir}/(.*)$`,
|
|
53
|
+
src: `^${escapeRegExp(basePath)}${escapeRegExp(assetsDir)}/(.*)$`,
|
|
53
54
|
headers: {
|
|
54
55
|
'cache-control': 'public, immutable, max-age=31536000'
|
|
55
56
|
}
|
|
@@ -59,7 +60,7 @@ export default getRequestListener(
|
|
|
59
60
|
handle: 'filesystem'
|
|
60
61
|
},
|
|
61
62
|
{
|
|
62
|
-
src: basePath + '(.*)',
|
|
63
|
+
src: escapeRegExp(basePath) + '(.*)',
|
|
63
64
|
dest: basePath + rscBase + '/'
|
|
64
65
|
}
|
|
65
66
|
] : []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/vercel-build-enhancer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nexport type BuildOptions = {\n assetsDir: string;\n distDir: string;\n rscBase: string;\n privateDir: string;\n basePath: string;\n DIST_PUBLIC: string;\n serverless: boolean;\n};\n\nasync function postBuild({\n assetsDir,\n distDir,\n rscBase,\n privateDir,\n basePath,\n DIST_PUBLIC,\n serverless,\n}: BuildOptions) {\n const SERVE_JS = 'serve-vercel.js';\n const serveCode = `\nimport { INTERNAL_runFetch } from './server/index.js';\n\nconst getRequestListener = globalThis.__WAKU_HONO_NODE_SERVER_GET_REQUEST_LISTENER__;\n\nexport default getRequestListener(\n (req, ...args) => INTERNAL_runFetch(process.env, req, ...args)\n);\n`;\n const publicDir = path.resolve(distDir, DIST_PUBLIC);\n const outputDir = path.resolve('.vercel', 'output');\n cpSync(publicDir, path.join(outputDir, 'static'), { recursive: true });\n\n if (serverless) {\n // for serverless function\n // TODO(waku): can use `@vercel/nft` to packaging with native dependencies\n const serverlessDir = path.join(outputDir, 'functions', rscBase + '.func');\n rmSync(serverlessDir, { recursive: true, force: true });\n mkdirSync(path.join(serverlessDir, distDir), {\n recursive: true,\n });\n writeFileSync(path.resolve(distDir, SERVE_JS), serveCode);\n cpSync(path.resolve(distDir), path.join(serverlessDir, distDir), {\n recursive: true,\n });\n if (existsSync(path.resolve(privateDir))) {\n cpSync(path.resolve(privateDir), path.join(serverlessDir, privateDir), {\n recursive: true,\n dereference: true,\n });\n }\n const vcConfigJson = {\n runtime: 'nodejs22.x',\n handler: `${distDir}/${SERVE_JS}`,\n launcherType: 'Nodejs',\n };\n writeFileSync(\n path.join(serverlessDir, '.vc-config.json'),\n JSON.stringify(vcConfigJson, null, 2),\n );\n writeFileSync(\n path.join(serverlessDir, 'package.json'),\n JSON.stringify({ type: 'module' }, null, 2),\n );\n }\n const routes = [\n {\n src: `^${basePath}${assetsDir}/(.*)$`,\n headers: {\n 'cache-control': 'public, immutable, max-age=31536000',\n },\n },\n ...(serverless\n ? [\n { handle: 'filesystem' },\n {\n src: basePath + '(.*)',\n dest: basePath + rscBase + '/',\n },\n ]\n : []),\n ];\n const configJson = { version: 3, routes };\n mkdirSync(outputDir, { recursive: true });\n writeFileSync(\n path.join(outputDir, 'config.json'),\n JSON.stringify(configJson, null, 2),\n );\n}\n\nexport default async function buildEnhancer(\n build: (utils: unknown, options: BuildOptions) => Promise<void>,\n): Promise<typeof build> {\n return async (utils: unknown, options: BuildOptions) => {\n await build(utils, options);\n await postBuild(options);\n };\n}\n"],"names":["cpSync","existsSync","mkdirSync","rmSync","writeFileSync","path","postBuild","assetsDir","distDir","rscBase","privateDir","basePath","DIST_PUBLIC","serverless","SERVE_JS","serveCode","publicDir","resolve","outputDir","join","recursive","serverlessDir","force","dereference","vcConfigJson","runtime","handler","launcherType","JSON","stringify","type","routes","src","headers","handle","dest","configJson","version","buildEnhancer","build","utils","options"],"mappings":"AAAA,SAASA,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAEC,MAAM,EAAEC,aAAa,QAAQ,UAAU;AAC/E,OAAOC,UAAU,YAAY;
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/vercel-build-enhancer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\n\nconst escapeRegExp = (s: string) => s.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n\nexport type BuildOptions = {\n assetsDir: string;\n distDir: string;\n rscBase: string;\n privateDir: string;\n basePath: string;\n DIST_PUBLIC: string;\n serverless: boolean;\n};\n\nasync function postBuild({\n assetsDir,\n distDir,\n rscBase,\n privateDir,\n basePath,\n DIST_PUBLIC,\n serverless,\n}: BuildOptions) {\n const SERVE_JS = 'serve-vercel.js';\n const serveCode = `\nimport { INTERNAL_runFetch } from './server/index.js';\n\nconst getRequestListener = globalThis.__WAKU_HONO_NODE_SERVER_GET_REQUEST_LISTENER__;\n\nexport default getRequestListener(\n (req, ...args) => INTERNAL_runFetch(process.env, req, ...args)\n);\n`;\n const publicDir = path.resolve(distDir, DIST_PUBLIC);\n const outputDir = path.resolve('.vercel', 'output');\n cpSync(publicDir, path.join(outputDir, 'static'), { recursive: true });\n\n if (serverless) {\n // for serverless function\n // TODO(waku): can use `@vercel/nft` to packaging with native dependencies\n const serverlessDir = path.join(outputDir, 'functions', rscBase + '.func');\n rmSync(serverlessDir, { recursive: true, force: true });\n mkdirSync(path.join(serverlessDir, distDir), {\n recursive: true,\n });\n writeFileSync(path.resolve(distDir, SERVE_JS), serveCode);\n cpSync(path.resolve(distDir), path.join(serverlessDir, distDir), {\n recursive: true,\n });\n if (existsSync(path.resolve(privateDir))) {\n cpSync(path.resolve(privateDir), path.join(serverlessDir, privateDir), {\n recursive: true,\n dereference: true,\n });\n }\n const vcConfigJson = {\n runtime: 'nodejs22.x',\n handler: `${distDir}/${SERVE_JS}`,\n launcherType: 'Nodejs',\n };\n writeFileSync(\n path.join(serverlessDir, '.vc-config.json'),\n JSON.stringify(vcConfigJson, null, 2),\n );\n writeFileSync(\n path.join(serverlessDir, 'package.json'),\n JSON.stringify({ type: 'module' }, null, 2),\n );\n }\n const routes = [\n {\n src: `^${escapeRegExp(basePath)}${escapeRegExp(assetsDir)}/(.*)$`,\n headers: {\n 'cache-control': 'public, immutable, max-age=31536000',\n },\n },\n ...(serverless\n ? [\n { handle: 'filesystem' },\n {\n src: escapeRegExp(basePath) + '(.*)',\n dest: basePath + rscBase + '/',\n },\n ]\n : []),\n ];\n const configJson = { version: 3, routes };\n mkdirSync(outputDir, { recursive: true });\n writeFileSync(\n path.join(outputDir, 'config.json'),\n JSON.stringify(configJson, null, 2),\n );\n}\n\nexport default async function buildEnhancer(\n build: (utils: unknown, options: BuildOptions) => Promise<void>,\n): Promise<typeof build> {\n return async (utils: unknown, options: BuildOptions) => {\n await build(utils, options);\n await postBuild(options);\n };\n}\n"],"names":["cpSync","existsSync","mkdirSync","rmSync","writeFileSync","path","escapeRegExp","s","replace","postBuild","assetsDir","distDir","rscBase","privateDir","basePath","DIST_PUBLIC","serverless","SERVE_JS","serveCode","publicDir","resolve","outputDir","join","recursive","serverlessDir","force","dereference","vcConfigJson","runtime","handler","launcherType","JSON","stringify","type","routes","src","headers","handle","dest","configJson","version","buildEnhancer","build","utils","options"],"mappings":"AAAA,SAASA,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAEC,MAAM,EAAEC,aAAa,QAAQ,UAAU;AAC/E,OAAOC,UAAU,YAAY;AAE7B,MAAMC,eAAe,CAACC,IAAcA,EAAEC,OAAO,CAAC,uBAAuB;AAYrE,eAAeC,UAAU,EACvBC,SAAS,EACTC,OAAO,EACPC,OAAO,EACPC,UAAU,EACVC,QAAQ,EACRC,WAAW,EACXC,UAAU,EACG;IACb,MAAMC,WAAW;IACjB,MAAMC,YAAY,CAAC;;;;;;;;AAQrB,CAAC;IACC,MAAMC,YAAYd,KAAKe,OAAO,CAACT,SAASI;IACxC,MAAMM,YAAYhB,KAAKe,OAAO,CAAC,WAAW;IAC1CpB,OAAOmB,WAAWd,KAAKiB,IAAI,CAACD,WAAW,WAAW;QAAEE,WAAW;IAAK;IAEpE,IAAIP,YAAY;QACd,0BAA0B;QAC1B,0EAA0E;QAC1E,MAAMQ,gBAAgBnB,KAAKiB,IAAI,CAACD,WAAW,aAAaT,UAAU;QAClET,OAAOqB,eAAe;YAAED,WAAW;YAAME,OAAO;QAAK;QACrDvB,UAAUG,KAAKiB,IAAI,CAACE,eAAeb,UAAU;YAC3CY,WAAW;QACb;QACAnB,cAAcC,KAAKe,OAAO,CAACT,SAASM,WAAWC;QAC/ClB,OAAOK,KAAKe,OAAO,CAACT,UAAUN,KAAKiB,IAAI,CAACE,eAAeb,UAAU;YAC/DY,WAAW;QACb;QACA,IAAItB,WAAWI,KAAKe,OAAO,CAACP,cAAc;YACxCb,OAAOK,KAAKe,OAAO,CAACP,aAAaR,KAAKiB,IAAI,CAACE,eAAeX,aAAa;gBACrEU,WAAW;gBACXG,aAAa;YACf;QACF;QACA,MAAMC,eAAe;YACnBC,SAAS;YACTC,SAAS,GAAGlB,QAAQ,CAAC,EAAEM,UAAU;YACjCa,cAAc;QAChB;QACA1B,cACEC,KAAKiB,IAAI,CAACE,eAAe,oBACzBO,KAAKC,SAAS,CAACL,cAAc,MAAM;QAErCvB,cACEC,KAAKiB,IAAI,CAACE,eAAe,iBACzBO,KAAKC,SAAS,CAAC;YAAEC,MAAM;QAAS,GAAG,MAAM;IAE7C;IACA,MAAMC,SAAS;QACb;YACEC,KAAK,CAAC,CAAC,EAAE7B,aAAaQ,YAAYR,aAAaI,WAAW,MAAM,CAAC;YACjE0B,SAAS;gBACP,iBAAiB;YACnB;QACF;WACIpB,aACA;YACE;gBAAEqB,QAAQ;YAAa;YACvB;gBACEF,KAAK7B,aAAaQ,YAAY;gBAC9BwB,MAAMxB,WAAWF,UAAU;YAC7B;SACD,GACD,EAAE;KACP;IACD,MAAM2B,aAAa;QAAEC,SAAS;QAAGN;IAAO;IACxChC,UAAUmB,WAAW;QAAEE,WAAW;IAAK;IACvCnB,cACEC,KAAKiB,IAAI,CAACD,WAAW,gBACrBU,KAAKC,SAAS,CAACO,YAAY,MAAM;AAErC;AAEA,eAAe,eAAeE,cAC5BC,KAA+D;IAE/D,OAAO,OAAOC,OAAgBC;QAC5B,MAAMF,MAAMC,OAAOC;QACnB,MAAMnC,UAAUmC;IAClB;AACF"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
import type { Config } from '../config.js';
|
|
3
3
|
type Elements = Record<string, unknown>;
|
|
4
4
|
export type Unstable_RenderRsc = (elements: Elements, options?: {
|
|
5
|
+
value?: unknown;
|
|
5
6
|
unstable_clientModuleCallback?: (ids: string[]) => void;
|
|
6
7
|
}) => Promise<ReadableStream>;
|
|
7
8
|
export type Unstable_ParseRsc = (rscStream: ReadableStream) => Promise<Elements>;
|
|
@@ -44,6 +45,7 @@ export type Unstable_HandleBuild = (utils: {
|
|
|
44
45
|
withRequest: <T>(req: Request, fn: () => T) => T;
|
|
45
46
|
generateFile: (fileName: string, body: ReadableStream | string) => Promise<void>;
|
|
46
47
|
generateDefaultHtml: (fileName: string) => Promise<void>;
|
|
48
|
+
unstable_registerPrunableFile: (srcPath: string) => void;
|
|
47
49
|
}) => Promise<void>;
|
|
48
50
|
export type Unstable_Handlers = {
|
|
49
51
|
handleRequest: Unstable_HandleRequest;
|
|
@@ -54,16 +56,15 @@ export type Unstable_ServerEntry = {
|
|
|
54
56
|
fetch: (req: Request, ...args: any[]) => Response | Promise<Response>;
|
|
55
57
|
build: (utils: {
|
|
56
58
|
emitFile: Unstable_EmitFile;
|
|
59
|
+
unstable_registerPrunableFile: (srcPath: string) => void;
|
|
57
60
|
}, ...args: any[]) => Promise<void>;
|
|
58
61
|
buildOptions?: Record<string, unknown>;
|
|
59
62
|
buildEnhancers?: string[];
|
|
60
63
|
defaultExport?: unknown;
|
|
61
64
|
[someOtherProperty: string]: unknown;
|
|
62
65
|
};
|
|
63
|
-
export type Unstable_ProcessRequest = (
|
|
64
|
-
export type Unstable_ProcessBuild = (
|
|
65
|
-
emitFile: Unstable_EmitFile;
|
|
66
|
-
}) => Promise<void>;
|
|
66
|
+
export type Unstable_ProcessRequest = (arg: Parameters<Unstable_ServerEntry['fetch']>[0]) => Promise<Response | null>;
|
|
67
|
+
export type Unstable_ProcessBuild = (arg: Parameters<Unstable_ServerEntry['build']>[0]) => Promise<void>;
|
|
67
68
|
export type Unstable_CreateServerEntryAdapter = <Options>(fn: (args: {
|
|
68
69
|
handlers: Unstable_Handlers;
|
|
69
70
|
processRequest: Unstable_ProcessRequest;
|
package/dist/lib/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { Config } from '../config.js';\n\ntype Elements = Record<string, unknown>;\n\nexport type Unstable_RenderRsc = (\n elements: Elements,\n options?: {\n unstable_clientModuleCallback?: (ids: string[]) => void;\n },\n) => Promise<ReadableStream>;\n\nexport type Unstable_ParseRsc = (\n rscStream: ReadableStream,\n) => Promise<Elements>;\n\nexport type Unstable_RenderHtml = (\n elementsStream: ReadableStream,\n html: ReactNode,\n options: {\n rscPath: string;\n formState?: unknown;\n status?: number;\n nonce?: string;\n unstable_extraScriptContent?: string;\n },\n) => Promise<Response>;\n\nexport type Unstable_EmitFile = (\n filePath: string,\n body: ReadableStream,\n) => Promise<void>;\n\nexport type Unstable_HandleRequest = (\n input: (\n | { type: 'component'; rscPath: string; rscParams: unknown }\n | {\n type: 'function';\n fn: (...args: unknown[]) => Promise<unknown>;\n args: unknown[];\n }\n | {\n type: 'action';\n fn: () => Promise<unknown>;\n }\n | { type: 'custom' }\n ) & {\n pathname: string;\n req: Request;\n },\n utils: {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n loadBuildMetadata: (key: string) => Promise<string | undefined>;\n },\n) => Promise<ReadableStream | Response | 'fallback' | null | undefined>;\n\nexport type Unstable_HandleBuild = (utils: {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n rscPath2pathname: (rscPath: string) => string;\n saveBuildMetadata: (key: string, value: string) => Promise<void>;\n withRequest: <T>(req: Request, fn: () => T) => T;\n generateFile: (\n fileName: string,\n body: ReadableStream | string,\n ) => Promise<void>;\n generateDefaultHtml: (fileName: string) => Promise<void>;\n}) => Promise<void>;\n\nexport type Unstable_Handlers = {\n handleRequest: Unstable_HandleRequest;\n handleBuild: Unstable_HandleBuild;\n [someOtherProperty: string]: unknown;\n};\n\nexport type Unstable_ServerEntry = {\n fetch: (req: Request, ...args: any[]) => Response | Promise<Response>;\n build: (\n utils: {\n emitFile: Unstable_EmitFile;\n },\n ...args: any[]\n ) => Promise<void>;\n buildOptions?: Record<string, unknown>;\n buildEnhancers?: string[]; // enhancer module ids\n defaultExport?: unknown;\n [someOtherProperty: string]: unknown;\n};\n\nexport type Unstable_ProcessRequest = (\n
|
|
1
|
+
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { Config } from '../config.js';\n\ntype Elements = Record<string, unknown>;\n\nexport type Unstable_RenderRsc = (\n elements: Elements,\n options?: {\n value?: unknown;\n unstable_clientModuleCallback?: (ids: string[]) => void;\n },\n) => Promise<ReadableStream>;\n\nexport type Unstable_ParseRsc = (\n rscStream: ReadableStream,\n) => Promise<Elements>;\n\nexport type Unstable_RenderHtml = (\n elementsStream: ReadableStream,\n html: ReactNode,\n options: {\n rscPath: string;\n formState?: unknown;\n status?: number;\n nonce?: string;\n unstable_extraScriptContent?: string;\n },\n) => Promise<Response>;\n\nexport type Unstable_EmitFile = (\n filePath: string,\n body: ReadableStream,\n) => Promise<void>;\n\nexport type Unstable_HandleRequest = (\n input: (\n | { type: 'component'; rscPath: string; rscParams: unknown }\n | {\n type: 'function';\n fn: (...args: unknown[]) => Promise<unknown>;\n args: unknown[];\n }\n | {\n type: 'action';\n fn: () => Promise<unknown>;\n }\n | { type: 'custom' }\n ) & {\n pathname: string;\n req: Request;\n },\n utils: {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n loadBuildMetadata: (key: string) => Promise<string | undefined>;\n },\n) => Promise<ReadableStream | Response | 'fallback' | null | undefined>;\n\nexport type Unstable_HandleBuild = (utils: {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n rscPath2pathname: (rscPath: string) => string;\n saveBuildMetadata: (key: string, value: string) => Promise<void>;\n withRequest: <T>(req: Request, fn: () => T) => T;\n generateFile: (\n fileName: string,\n body: ReadableStream | string,\n ) => Promise<void>;\n generateDefaultHtml: (fileName: string) => Promise<void>;\n unstable_registerPrunableFile: (srcPath: string) => void;\n}) => Promise<void>;\n\nexport type Unstable_Handlers = {\n handleRequest: Unstable_HandleRequest;\n handleBuild: Unstable_HandleBuild;\n [someOtherProperty: string]: unknown;\n};\n\nexport type Unstable_ServerEntry = {\n fetch: (req: Request, ...args: any[]) => Response | Promise<Response>;\n build: (\n utils: {\n emitFile: Unstable_EmitFile;\n unstable_registerPrunableFile: (srcPath: string) => void;\n },\n ...args: any[]\n ) => Promise<void>;\n buildOptions?: Record<string, unknown>;\n buildEnhancers?: string[]; // enhancer module ids\n defaultExport?: unknown;\n [someOtherProperty: string]: unknown;\n};\n\nexport type Unstable_ProcessRequest = (\n arg: Parameters<Unstable_ServerEntry['fetch']>[0],\n) => Promise<Response | null>;\n\nexport type Unstable_ProcessBuild = (\n arg: Parameters<Unstable_ServerEntry['build']>[0],\n) => Promise<void>;\n\nexport type Unstable_CreateServerEntryAdapter = <Options>(\n fn: (\n args: {\n handlers: Unstable_Handlers;\n processRequest: Unstable_ProcessRequest;\n processBuild: Unstable_ProcessBuild;\n setAllEnv: (newEnv: Readonly<Record<string, string>>) => void;\n config: Omit<Required<Config>, 'vite'>;\n isBuild: boolean;\n notFoundHtml: string;\n },\n options?: Options,\n ) => Unstable_ServerEntry,\n) => (handlers: Unstable_Handlers, options?: Options) => Unstable_ServerEntry;\n"],"names":[],"mappings":"AAuGA,WAa8E"}
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import { EXTENSIONS, SRC_MIDDLEWARE, SRC_PAGES } from '../constants.js';
|
|
2
2
|
export const getManagedServerEntry = (srcDir)=>{
|
|
3
|
-
const globBase = `/${srcDir}/${SRC_PAGES}`;
|
|
4
3
|
const exts = EXTENSIONS.map((ext)=>ext.slice(1)).join(',');
|
|
5
|
-
const globPattern =
|
|
4
|
+
const globPattern = `/${srcDir}/${SRC_PAGES}/**/*.{${exts}}`;
|
|
5
|
+
const srcDirPrefix = `/${srcDir}/`;
|
|
6
6
|
const middlewareGlob = [
|
|
7
7
|
`/${srcDir}/${SRC_MIDDLEWARE}/*.{${exts}}`,
|
|
8
8
|
`!/${srcDir}/${SRC_MIDDLEWARE}/*.{test,spec}.{${exts}}`
|
|
9
9
|
];
|
|
10
|
+
// Strip srcDir prefix from glob keys so fsRouter's default `pagesDir: 'pages'` applies.
|
|
10
11
|
return `
|
|
11
12
|
import { fsRouter } from 'waku';
|
|
12
13
|
import adapter from 'waku/adapters/default';
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
${JSON.stringify(globPattern)},
|
|
18
|
-
{ base: ${JSON.stringify(globBase)} }
|
|
19
|
-
)
|
|
15
|
+
const modules = Object.fromEntries(
|
|
16
|
+
Object.entries(import.meta.glob(${JSON.stringify(globPattern)})).map(
|
|
17
|
+
([k, v]) => [k.slice(${srcDirPrefix.length}), v],
|
|
20
18
|
),
|
|
21
|
-
{
|
|
22
|
-
middlewareModules: import.meta.glob(${JSON.stringify(middlewareGlob)}),
|
|
23
|
-
},
|
|
24
19
|
);
|
|
20
|
+
|
|
21
|
+
export default adapter(fsRouter(modules), {
|
|
22
|
+
middlewareModules: import.meta.glob(${JSON.stringify(middlewareGlob)}),
|
|
23
|
+
});
|
|
25
24
|
`;
|
|
26
25
|
};
|
|
27
26
|
export const getManagedClientEntry = ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils/managed.ts"],"sourcesContent":["import { EXTENSIONS, SRC_MIDDLEWARE, SRC_PAGES } from '../constants.js';\n\nexport const getManagedServerEntry = (srcDir: string) => {\n const
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/managed.ts"],"sourcesContent":["import { EXTENSIONS, SRC_MIDDLEWARE, SRC_PAGES } from '../constants.js';\n\nexport const getManagedServerEntry = (srcDir: string) => {\n const exts = EXTENSIONS.map((ext) => ext.slice(1)).join(',');\n const globPattern = `/${srcDir}/${SRC_PAGES}/**/*.{${exts}}`;\n const srcDirPrefix = `/${srcDir}/`;\n const middlewareGlob = [\n `/${srcDir}/${SRC_MIDDLEWARE}/*.{${exts}}`,\n `!/${srcDir}/${SRC_MIDDLEWARE}/*.{test,spec}.{${exts}}`,\n ];\n // Strip srcDir prefix from glob keys so fsRouter's default `pagesDir: 'pages'` applies.\n return `\nimport { fsRouter } from 'waku';\nimport adapter from 'waku/adapters/default';\n\nconst modules = Object.fromEntries(\n Object.entries(import.meta.glob(${JSON.stringify(globPattern)})).map(\n ([k, v]) => [k.slice(${srcDirPrefix.length}), v],\n ),\n);\n\nexport default adapter(fsRouter(modules), {\n middlewareModules: import.meta.glob(${JSON.stringify(middlewareGlob)}),\n});\n`;\n};\n\nexport const getManagedClientEntry = () => {\n return `\nimport { StrictMode, createElement } from 'react';\nimport { createRoot, hydrateRoot } from 'react-dom/client';\nimport { unstable_defaultRootOptions as defaultRootOptions } from 'waku/client';\nimport { Router } from 'waku/router/client';\n\nconst rootElement = createElement(StrictMode, null, createElement(Router));\n\nif (globalThis.__WAKU_HYDRATE__) {\n hydrateRoot(document, rootElement, defaultRootOptions);\n} else {\n createRoot(document, defaultRootOptions).render(rootElement);\n}\n`;\n};\n"],"names":["EXTENSIONS","SRC_MIDDLEWARE","SRC_PAGES","getManagedServerEntry","srcDir","exts","map","ext","slice","join","globPattern","srcDirPrefix","middlewareGlob","JSON","stringify","length","getManagedClientEntry"],"mappings":"AAAA,SAASA,UAAU,EAAEC,cAAc,EAAEC,SAAS,QAAQ,kBAAkB;AAExE,OAAO,MAAMC,wBAAwB,CAACC;IACpC,MAAMC,OAAOL,WAAWM,GAAG,CAAC,CAACC,MAAQA,IAAIC,KAAK,CAAC,IAAIC,IAAI,CAAC;IACxD,MAAMC,cAAc,CAAC,CAAC,EAAEN,OAAO,CAAC,EAAEF,UAAU,OAAO,EAAEG,KAAK,CAAC,CAAC;IAC5D,MAAMM,eAAe,CAAC,CAAC,EAAEP,OAAO,CAAC,CAAC;IAClC,MAAMQ,iBAAiB;QACrB,CAAC,CAAC,EAAER,OAAO,CAAC,EAAEH,eAAe,IAAI,EAAEI,KAAK,CAAC,CAAC;QAC1C,CAAC,EAAE,EAAED,OAAO,CAAC,EAAEH,eAAe,gBAAgB,EAAEI,KAAK,CAAC,CAAC;KACxD;IACD,wFAAwF;IACxF,OAAO,CAAC;;;;;kCAKwB,EAAEQ,KAAKC,SAAS,CAACJ,aAAa;yBACvC,EAAEC,aAAaI,MAAM,CAAC;;;;;sCAKT,EAAEF,KAAKC,SAAS,CAACF,gBAAgB;;AAEvE,CAAC;AACD,EAAE;AAEF,OAAO,MAAMI,wBAAwB;IACnC,OAAO,CAAC;;;;;;;;;;;;;AAaV,CAAC;AACD,EAAE"}
|
package/dist/lib/utils/path.js
CHANGED
|
@@ -90,15 +90,16 @@ export const parseExactPath = (path)=>path.split('/').filter(Boolean).map((name)
|
|
|
90
90
|
type: 'literal',
|
|
91
91
|
name
|
|
92
92
|
}));
|
|
93
|
+
const escapeRegExp = (s)=>s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
|
|
93
94
|
/**
|
|
94
95
|
* Transform a path spec to a regular expression.
|
|
95
96
|
*/ export const path2regexp = (path)=>{
|
|
96
97
|
const parts = path.map((item)=>{
|
|
97
98
|
if (item.type === 'literal') {
|
|
98
|
-
return item.name;
|
|
99
|
+
return escapeRegExp(item.name);
|
|
99
100
|
} else if (item.type === 'group') {
|
|
100
|
-
const prefix = item.prefix ?? '';
|
|
101
|
-
const suffix = item.suffix ?? '';
|
|
101
|
+
const prefix = escapeRegExp(item.prefix ?? '');
|
|
102
|
+
const suffix = escapeRegExp(item.suffix ?? '');
|
|
102
103
|
return `${prefix}([^/]+)${suffix}`;
|
|
103
104
|
} else {
|
|
104
105
|
return `(.*)`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils/path.ts"],"sourcesContent":["// Terminology:\n// - filePath: posix-like file path, e.g. `/foo/bar.js` or `c:/foo/bar.js`\n// This is used by Vite.\n// - fileURL: file URL, e.g. `file:///foo/bar.js` or `file:///c:/foo/bar.js`\n// This is used by import().\n// - osPath: os dependent path, e.g. `/foo/bar.js` or `c:\\foo\\bar.js`\n// This is used by node:fs.\n\nconst ABSOLUTE_WIN32_PATH_REGEXP = /^\\/[a-zA-Z]:\\//;\n\nexport const encodeFilePathToAbsolute = (filePath: string) => {\n if (ABSOLUTE_WIN32_PATH_REGEXP.test(filePath)) {\n throw new Error('Unsupported absolute file path: ' + filePath);\n }\n if (filePath.startsWith('/')) {\n return filePath;\n }\n return '/' + filePath;\n};\n\nexport const decodeFilePathFromAbsolute = (filePath: string) => {\n if (ABSOLUTE_WIN32_PATH_REGEXP.test(filePath)) {\n return filePath.slice(1);\n }\n return filePath;\n};\n\nexport const filePathToFileURL = (filePath: string) =>\n 'file://' + encodeURI(filePath);\n\nexport const fileURLToFilePath = (fileURL: string) => {\n if (!fileURL.startsWith('file://')) {\n throw new Error('Not a file URL');\n }\n return decodeURI(fileURL.slice('file://'.length));\n};\n\n// for filePath\nexport const joinPath = (...paths: string[]) => {\n const isAbsolute = paths[0]?.startsWith('/');\n const items = ([] as string[]).concat(\n ...paths.map((path) => path.split('/')),\n );\n const stack: string[] = [];\n for (const item of items) {\n if (item === '..') {\n if (stack.length && stack[stack.length - 1] !== '..') {\n stack.pop();\n } else if (!isAbsolute) {\n stack.push('..');\n }\n } else if (item && item !== '.') {\n stack.push(item);\n }\n }\n return (isAbsolute ? '/' : '') + stack.join('/') || '.';\n};\n\nexport const extname = (filePath: string) => {\n const index = filePath.lastIndexOf('.');\n if (index <= 0) {\n return '';\n }\n if (['/', '.'].includes(filePath[index - 1]!)) {\n return '';\n }\n return filePath.slice(index);\n};\n\nexport type PathSpecItem =\n | { type: 'literal'; name: string }\n | { type: 'group'; name?: string; prefix?: string; suffix?: string }\n | { type: 'wildcard'; name?: string };\nexport type PathSpec = readonly PathSpecItem[];\n\nconst SLUG_PATTERN = /^(.*?)\\[([^\\]]+)\\](.*)$/;\n\nexport const parsePathWithSlug = (path: string): PathSpec =>\n path\n .split('/')\n .filter(Boolean)\n .map((name) => {\n const match = SLUG_PATTERN.exec(name);\n if (!match) {\n return { type: 'literal' as const, name };\n }\n const [, prefix, inner, suffix] = match;\n if (inner!.startsWith('...')) {\n return {\n type: 'wildcard' as const,\n name: inner!.slice(3),\n };\n }\n return {\n type: 'group' as const,\n name: inner!,\n ...(prefix ? { prefix } : {}),\n ...(suffix ? { suffix } : {}),\n };\n });\n\nexport const parseExactPath = (path: string): PathSpec =>\n path\n .split('/')\n .filter(Boolean)\n .map((name) => ({ type: 'literal', name }));\n\n/**\n * Transform a path spec to a regular expression.\n */\nexport const path2regexp = (path: PathSpec) => {\n const parts = path.map((item) => {\n if (item.type === 'literal') {\n return item.name;\n } else if (item.type === 'group') {\n const prefix = item.prefix ?? '';\n const suffix = item.suffix ?? '';\n return `${prefix}([^/]+)${suffix}`;\n } else {\n return `(.*)`;\n }\n });\n return `^/${parts.join('/')}$`;\n};\n\n/** Convert a path spec to a string for the path */\nexport const pathSpecAsString = (path: PathSpec) => {\n return (\n '/' +\n path\n .map((item) => {\n if (item.type === 'literal') {\n return item.name;\n } else if (item.type === 'group') {\n const prefix = item.prefix ?? '';\n const suffix = item.suffix ?? '';\n return `${prefix}[${item.name}]${suffix}`;\n } else {\n return `[...${item.name}]`;\n }\n })\n .join('/')\n );\n};\n\n/**\n * Helper function to get the path mapping from the path spec and the pathname.\n *\n * @param pathSpec\n * @param pathname - route as a string\n * @example\n * getPathMapping(\n * [\n * { type: 'literal', name: 'foo' },\n * { type: 'group', name: 'a' },\n * ],\n * '/foo/bar',\n * );\n * // => { a: 'bar' }\n */\nexport const getPathMapping = (\n pathSpec: PathSpec,\n pathname: string,\n): Record<string, string | string[]> | null => {\n const actual = pathname.split('/').filter(Boolean);\n if (pathSpec.length > actual.length) {\n const wildcardIndex = pathSpec.findIndex(\n (spec) => spec.type === 'wildcard',\n );\n if (wildcardIndex === -1) {\n return null;\n }\n const isTerminalWildcard = wildcardIndex === pathSpec.length - 1;\n if (isTerminalWildcard) {\n // Terminal wildcards only pass through with zero actual segments\n // (handled by the root-wildcard special case below)\n if (actual.length > 0) {\n return null;\n }\n } else if (actual.length < pathSpec.length - 1) {\n // Non-terminal wildcards can match zero segments; just need enough\n // actual segments for every non-wildcard spec in the pathSpec\n return null;\n }\n }\n const mapping: Record<string, string | string[]> = {};\n let wildcardStartIndex = -1;\n for (let i = 0; i < pathSpec.length; i++) {\n const spec = pathSpec[i]!;\n if (spec.type === 'literal') {\n if (spec.name !== actual[i]) {\n return null;\n }\n } else if (spec.type === 'wildcard') {\n wildcardStartIndex = i;\n break;\n } else {\n const segment = actual[i];\n if (segment === undefined) {\n return null;\n }\n const prefix = spec.prefix ?? '';\n const suffix = spec.suffix ?? '';\n if (prefix || suffix) {\n if (!segment.startsWith(prefix) || !segment.endsWith(suffix || '')) {\n return null;\n }\n const value = segment.slice(\n prefix.length,\n suffix ? -suffix.length : undefined,\n );\n if (!value) {\n return null;\n }\n if (spec.name) {\n mapping[spec.name] = value;\n }\n } else if (spec.name) {\n mapping[spec.name] = segment;\n }\n }\n }\n if (wildcardStartIndex === -1) {\n if (pathSpec.length !== actual.length) {\n return null;\n }\n return mapping;\n }\n\n if (wildcardStartIndex === 0 && actual.length === 0) {\n const wildcardName = pathSpec[wildcardStartIndex]!.name;\n if (wildcardName) {\n mapping[wildcardName] = [];\n }\n return mapping;\n }\n\n let wildcardEndIndex = -1;\n for (let i = 0; i < pathSpec.length; i++) {\n const spec = pathSpec[pathSpec.length - i - 1]!;\n if (spec.type === 'literal') {\n if (spec.name !== actual[actual.length - i - 1]) {\n return null;\n }\n } else if (spec.type === 'wildcard') {\n wildcardEndIndex = actual.length - i - 1;\n break;\n } else {\n const segment = actual[actual.length - i - 1];\n if (segment === undefined) {\n return null;\n }\n const prefix = spec.prefix ?? '';\n const suffix = spec.suffix ?? '';\n if (prefix || suffix) {\n if (!segment.startsWith(prefix) || !segment.endsWith(suffix || '')) {\n return null;\n }\n const value = segment.slice(\n prefix.length,\n suffix ? -suffix.length : undefined,\n );\n if (!value) {\n return null;\n }\n if (spec.name) {\n mapping[spec.name] = value;\n }\n } else if (spec.name) {\n mapping[spec.name] = segment;\n }\n }\n }\n if (wildcardStartIndex === -1) {\n throw new Error('Invalid wildcard path');\n }\n const wildcardName = pathSpec[wildcardStartIndex]!.name;\n if (wildcardName) {\n mapping[wildcardName] = actual.slice(\n wildcardStartIndex,\n wildcardEndIndex + 1,\n );\n }\n return mapping;\n};\n\n// basePath config is ensured to have trailing slash (see plugin)\nexport function removeBase(url: string, base: string) {\n if (base !== '/') {\n if (!url.startsWith(base)) {\n throw new Error('pathname must start with basePath: ' + url);\n }\n return url.slice(base.length - 1);\n }\n return url;\n}\n\nexport function addBase(url: string, base: string) {\n if (base !== '/' && url.startsWith('/')) {\n return base.slice(0, -1) + url;\n }\n return url;\n}\n\nexport function countSlugsAndWildcards(pathSpec: PathSpec) {\n let numSlugs = 0;\n let numWildcards = 0;\n for (const slug of pathSpec) {\n if (slug.type !== 'literal') {\n numSlugs++;\n }\n if (slug.type === 'wildcard') {\n numWildcards++;\n }\n }\n return { numSlugs, numWildcards };\n}\n"],"names":["ABSOLUTE_WIN32_PATH_REGEXP","encodeFilePathToAbsolute","filePath","test","Error","startsWith","decodeFilePathFromAbsolute","slice","filePathToFileURL","encodeURI","fileURLToFilePath","fileURL","decodeURI","length","joinPath","paths","isAbsolute","items","concat","map","path","split","stack","item","pop","push","join","extname","index","lastIndexOf","includes","SLUG_PATTERN","parsePathWithSlug","filter","Boolean","name","match","exec","type","prefix","inner","suffix","parseExactPath","path2regexp","parts","pathSpecAsString","getPathMapping","pathSpec","pathname","actual","wildcardIndex","findIndex","spec","isTerminalWildcard","mapping","wildcardStartIndex","i","segment","undefined","endsWith","value","wildcardName","wildcardEndIndex","removeBase","url","base","addBase","countSlugsAndWildcards","numSlugs","numWildcards","slug"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/path.ts"],"sourcesContent":["// Terminology:\n// - filePath: posix-like file path, e.g. `/foo/bar.js` or `c:/foo/bar.js`\n// This is used by Vite.\n// - fileURL: file URL, e.g. `file:///foo/bar.js` or `file:///c:/foo/bar.js`\n// This is used by import().\n// - osPath: os dependent path, e.g. `/foo/bar.js` or `c:\\foo\\bar.js`\n// This is used by node:fs.\n\nconst ABSOLUTE_WIN32_PATH_REGEXP = /^\\/[a-zA-Z]:\\//;\n\nexport const encodeFilePathToAbsolute = (filePath: string) => {\n if (ABSOLUTE_WIN32_PATH_REGEXP.test(filePath)) {\n throw new Error('Unsupported absolute file path: ' + filePath);\n }\n if (filePath.startsWith('/')) {\n return filePath;\n }\n return '/' + filePath;\n};\n\nexport const decodeFilePathFromAbsolute = (filePath: string) => {\n if (ABSOLUTE_WIN32_PATH_REGEXP.test(filePath)) {\n return filePath.slice(1);\n }\n return filePath;\n};\n\nexport const filePathToFileURL = (filePath: string) =>\n 'file://' + encodeURI(filePath);\n\nexport const fileURLToFilePath = (fileURL: string) => {\n if (!fileURL.startsWith('file://')) {\n throw new Error('Not a file URL');\n }\n return decodeURI(fileURL.slice('file://'.length));\n};\n\n// for filePath\nexport const joinPath = (...paths: string[]) => {\n const isAbsolute = paths[0]?.startsWith('/');\n const items = ([] as string[]).concat(\n ...paths.map((path) => path.split('/')),\n );\n const stack: string[] = [];\n for (const item of items) {\n if (item === '..') {\n if (stack.length && stack[stack.length - 1] !== '..') {\n stack.pop();\n } else if (!isAbsolute) {\n stack.push('..');\n }\n } else if (item && item !== '.') {\n stack.push(item);\n }\n }\n return (isAbsolute ? '/' : '') + stack.join('/') || '.';\n};\n\nexport const extname = (filePath: string) => {\n const index = filePath.lastIndexOf('.');\n if (index <= 0) {\n return '';\n }\n if (['/', '.'].includes(filePath[index - 1]!)) {\n return '';\n }\n return filePath.slice(index);\n};\n\nexport type PathSpecItem =\n | { type: 'literal'; name: string }\n | { type: 'group'; name?: string; prefix?: string; suffix?: string }\n | { type: 'wildcard'; name?: string };\nexport type PathSpec = readonly PathSpecItem[];\n\nconst SLUG_PATTERN = /^(.*?)\\[([^\\]]+)\\](.*)$/;\n\nexport const parsePathWithSlug = (path: string): PathSpec =>\n path\n .split('/')\n .filter(Boolean)\n .map((name) => {\n const match = SLUG_PATTERN.exec(name);\n if (!match) {\n return { type: 'literal' as const, name };\n }\n const [, prefix, inner, suffix] = match;\n if (inner!.startsWith('...')) {\n return {\n type: 'wildcard' as const,\n name: inner!.slice(3),\n };\n }\n return {\n type: 'group' as const,\n name: inner!,\n ...(prefix ? { prefix } : {}),\n ...(suffix ? { suffix } : {}),\n };\n });\n\nexport const parseExactPath = (path: string): PathSpec =>\n path\n .split('/')\n .filter(Boolean)\n .map((name) => ({ type: 'literal', name }));\n\nconst escapeRegExp = (s: string) => s.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n\n/**\n * Transform a path spec to a regular expression.\n */\nexport const path2regexp = (path: PathSpec) => {\n const parts = path.map((item) => {\n if (item.type === 'literal') {\n return escapeRegExp(item.name);\n } else if (item.type === 'group') {\n const prefix = escapeRegExp(item.prefix ?? '');\n const suffix = escapeRegExp(item.suffix ?? '');\n return `${prefix}([^/]+)${suffix}`;\n } else {\n return `(.*)`;\n }\n });\n return `^/${parts.join('/')}$`;\n};\n\n/** Convert a path spec to a string for the path */\nexport const pathSpecAsString = (path: PathSpec) => {\n return (\n '/' +\n path\n .map((item) => {\n if (item.type === 'literal') {\n return item.name;\n } else if (item.type === 'group') {\n const prefix = item.prefix ?? '';\n const suffix = item.suffix ?? '';\n return `${prefix}[${item.name}]${suffix}`;\n } else {\n return `[...${item.name}]`;\n }\n })\n .join('/')\n );\n};\n\n/**\n * Helper function to get the path mapping from the path spec and the pathname.\n *\n * @param pathSpec\n * @param pathname - route as a string\n * @example\n * getPathMapping(\n * [\n * { type: 'literal', name: 'foo' },\n * { type: 'group', name: 'a' },\n * ],\n * '/foo/bar',\n * );\n * // => { a: 'bar' }\n */\nexport const getPathMapping = (\n pathSpec: PathSpec,\n pathname: string,\n): Record<string, string | string[]> | null => {\n const actual = pathname.split('/').filter(Boolean);\n if (pathSpec.length > actual.length) {\n const wildcardIndex = pathSpec.findIndex(\n (spec) => spec.type === 'wildcard',\n );\n if (wildcardIndex === -1) {\n return null;\n }\n const isTerminalWildcard = wildcardIndex === pathSpec.length - 1;\n if (isTerminalWildcard) {\n // Terminal wildcards only pass through with zero actual segments\n // (handled by the root-wildcard special case below)\n if (actual.length > 0) {\n return null;\n }\n } else if (actual.length < pathSpec.length - 1) {\n // Non-terminal wildcards can match zero segments; just need enough\n // actual segments for every non-wildcard spec in the pathSpec\n return null;\n }\n }\n const mapping: Record<string, string | string[]> = {};\n let wildcardStartIndex = -1;\n for (let i = 0; i < pathSpec.length; i++) {\n const spec = pathSpec[i]!;\n if (spec.type === 'literal') {\n if (spec.name !== actual[i]) {\n return null;\n }\n } else if (spec.type === 'wildcard') {\n wildcardStartIndex = i;\n break;\n } else {\n const segment = actual[i];\n if (segment === undefined) {\n return null;\n }\n const prefix = spec.prefix ?? '';\n const suffix = spec.suffix ?? '';\n if (prefix || suffix) {\n if (!segment.startsWith(prefix) || !segment.endsWith(suffix || '')) {\n return null;\n }\n const value = segment.slice(\n prefix.length,\n suffix ? -suffix.length : undefined,\n );\n if (!value) {\n return null;\n }\n if (spec.name) {\n mapping[spec.name] = value;\n }\n } else if (spec.name) {\n mapping[spec.name] = segment;\n }\n }\n }\n if (wildcardStartIndex === -1) {\n if (pathSpec.length !== actual.length) {\n return null;\n }\n return mapping;\n }\n\n if (wildcardStartIndex === 0 && actual.length === 0) {\n const wildcardName = pathSpec[wildcardStartIndex]!.name;\n if (wildcardName) {\n mapping[wildcardName] = [];\n }\n return mapping;\n }\n\n let wildcardEndIndex = -1;\n for (let i = 0; i < pathSpec.length; i++) {\n const spec = pathSpec[pathSpec.length - i - 1]!;\n if (spec.type === 'literal') {\n if (spec.name !== actual[actual.length - i - 1]) {\n return null;\n }\n } else if (spec.type === 'wildcard') {\n wildcardEndIndex = actual.length - i - 1;\n break;\n } else {\n const segment = actual[actual.length - i - 1];\n if (segment === undefined) {\n return null;\n }\n const prefix = spec.prefix ?? '';\n const suffix = spec.suffix ?? '';\n if (prefix || suffix) {\n if (!segment.startsWith(prefix) || !segment.endsWith(suffix || '')) {\n return null;\n }\n const value = segment.slice(\n prefix.length,\n suffix ? -suffix.length : undefined,\n );\n if (!value) {\n return null;\n }\n if (spec.name) {\n mapping[spec.name] = value;\n }\n } else if (spec.name) {\n mapping[spec.name] = segment;\n }\n }\n }\n if (wildcardStartIndex === -1) {\n throw new Error('Invalid wildcard path');\n }\n const wildcardName = pathSpec[wildcardStartIndex]!.name;\n if (wildcardName) {\n mapping[wildcardName] = actual.slice(\n wildcardStartIndex,\n wildcardEndIndex + 1,\n );\n }\n return mapping;\n};\n\n// basePath config is ensured to have trailing slash (see plugin)\nexport function removeBase(url: string, base: string) {\n if (base !== '/') {\n if (!url.startsWith(base)) {\n throw new Error('pathname must start with basePath: ' + url);\n }\n return url.slice(base.length - 1);\n }\n return url;\n}\n\nexport function addBase(url: string, base: string) {\n if (base !== '/' && url.startsWith('/')) {\n return base.slice(0, -1) + url;\n }\n return url;\n}\n\nexport function countSlugsAndWildcards(pathSpec: PathSpec) {\n let numSlugs = 0;\n let numWildcards = 0;\n for (const slug of pathSpec) {\n if (slug.type !== 'literal') {\n numSlugs++;\n }\n if (slug.type === 'wildcard') {\n numWildcards++;\n }\n }\n return { numSlugs, numWildcards };\n}\n"],"names":["ABSOLUTE_WIN32_PATH_REGEXP","encodeFilePathToAbsolute","filePath","test","Error","startsWith","decodeFilePathFromAbsolute","slice","filePathToFileURL","encodeURI","fileURLToFilePath","fileURL","decodeURI","length","joinPath","paths","isAbsolute","items","concat","map","path","split","stack","item","pop","push","join","extname","index","lastIndexOf","includes","SLUG_PATTERN","parsePathWithSlug","filter","Boolean","name","match","exec","type","prefix","inner","suffix","parseExactPath","escapeRegExp","s","replace","path2regexp","parts","pathSpecAsString","getPathMapping","pathSpec","pathname","actual","wildcardIndex","findIndex","spec","isTerminalWildcard","mapping","wildcardStartIndex","i","segment","undefined","endsWith","value","wildcardName","wildcardEndIndex","removeBase","url","base","addBase","countSlugsAndWildcards","numSlugs","numWildcards","slug"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const KEY_RSC_PATH = "p";
|
|
2
|
+
declare const KEY_RESPONSE = "r";
|
|
3
|
+
declare const KEY_CLOSE = "x";
|
|
4
|
+
declare const KEY_RSC_PARAMS = "q";
|
|
5
|
+
declare const KEY_TEMPORARY_REFERENCES = "t";
|
|
6
|
+
declare const KEY_DEBUG_ID = "d";
|
|
7
|
+
export type INTERNAL_PrefetchedEntry = {
|
|
8
|
+
[KEY_RSC_PATH]: string;
|
|
9
|
+
[KEY_RESPONSE]: Promise<Response>;
|
|
10
|
+
[KEY_CLOSE]?: () => void;
|
|
11
|
+
[KEY_RSC_PARAMS]?: unknown;
|
|
12
|
+
[KEY_TEMPORARY_REFERENCES]?: unknown;
|
|
13
|
+
[KEY_DEBUG_ID]?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const createPrefetchedEntry: (rscPath: string, response: Promise<Response>, rscParams?: unknown, temporaryReferences?: unknown) => INTERNAL_PrefetchedEntry;
|
|
16
|
+
export declare const getPrefetchedRscPath: (entry: INTERNAL_PrefetchedEntry) => string;
|
|
17
|
+
export declare const getPrefetchedResponse: (entry: INTERNAL_PrefetchedEntry) => Promise<Response>;
|
|
18
|
+
export declare const getPrefetchedClose: (entry: INTERNAL_PrefetchedEntry) => (() => void) | undefined;
|
|
19
|
+
export declare const getPrefetchedRscParams: (entry: INTERNAL_PrefetchedEntry) => unknown;
|
|
20
|
+
export declare const getPrefetchedTemporaryReferences: <T>(entry: INTERNAL_PrefetchedEntry) => T | undefined;
|
|
21
|
+
export declare const getPrefetchedDebugId: (entry: INTERNAL_PrefetchedEntry) => string | undefined;
|
|
22
|
+
export declare const createInitialPrefetchedEntryCode: (rscPath: string, debugId: string | undefined) => string;
|
|
23
|
+
export {};
|