waku 1.0.0-alpha.9 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +35 -22
  2. package/dist/adapters/cloudflare.js +21 -13
  3. package/dist/adapters/cloudflare.js.map +1 -1
  4. package/dist/lib/types.d.ts +5 -4
  5. package/dist/lib/types.js.map +1 -1
  6. package/dist/lib/utils/managed.js +10 -11
  7. package/dist/lib/utils/managed.js.map +1 -1
  8. package/dist/lib/utils/prune-build.d.ts +29 -0
  9. package/dist/lib/utils/prune-build.js +96 -0
  10. package/dist/lib/utils/prune-build.js.map +1 -0
  11. package/dist/lib/utils/render.d.ts +1 -1
  12. package/dist/lib/utils/render.js +20 -3
  13. package/dist/lib/utils/render.js.map +1 -1
  14. package/dist/lib/vite-entries/entry.browser.js +5 -0
  15. package/dist/lib/vite-entries/entry.browser.js.map +1 -1
  16. package/dist/lib/vite-entries/entry.build.d.ts +3 -1
  17. package/dist/lib/vite-entries/entry.build.js +11 -4
  18. package/dist/lib/vite-entries/entry.build.js.map +1 -1
  19. package/dist/lib/vite-plugins/adapter-alias.d.ts +4 -0
  20. package/dist/lib/vite-plugins/{default-adapter.js → adapter-alias.js} +3 -3
  21. package/dist/lib/vite-plugins/adapter-alias.js.map +1 -0
  22. package/dist/lib/vite-plugins/{user-entries.d.ts → app-entries.d.ts} +1 -1
  23. package/dist/lib/vite-plugins/{user-entries.js → app-entries.js} +3 -3
  24. package/dist/lib/vite-plugins/app-entries.js.map +1 -0
  25. package/dist/lib/vite-plugins/build-id.d.ts +2 -0
  26. package/dist/lib/vite-plugins/build-id.js +20 -0
  27. package/dist/lib/vite-plugins/build-id.js.map +1 -0
  28. package/dist/lib/vite-plugins/combined-plugins.js +14 -12
  29. package/dist/lib/vite-plugins/combined-plugins.js.map +1 -1
  30. package/dist/lib/vite-plugins/{main.d.ts → environments.d.ts} +1 -1
  31. package/dist/lib/vite-plugins/{main.js → environments.js} +3 -3
  32. package/dist/lib/vite-plugins/environments.js.map +1 -0
  33. package/dist/lib/vite-plugins/html-shell.d.ts +2 -0
  34. package/dist/lib/vite-plugins/{fallback-html.js → html-shell.js} +5 -5
  35. package/dist/lib/vite-plugins/html-shell.js.map +1 -0
  36. package/dist/lib/vite-plugins/rsc-devtools.d.ts +2 -0
  37. package/dist/lib/vite-plugins/{react-debug.js → rsc-devtools.js} +3 -3
  38. package/dist/lib/vite-plugins/rsc-devtools.js.map +1 -0
  39. package/dist/lib/vite-plugins/static-build.d.ts +5 -0
  40. package/dist/lib/vite-plugins/{build-static-files.js → static-build.js} +21 -4
  41. package/dist/lib/vite-plugins/static-build.js.map +1 -0
  42. package/dist/lib/vite-rsc/handler.js +5 -4
  43. package/dist/lib/vite-rsc/handler.js.map +1 -1
  44. package/dist/lib/vite-rsc/ssr.js +2 -2
  45. package/dist/lib/vite-rsc/ssr.js.map +1 -1
  46. package/dist/minimal/client.d.ts +3 -0
  47. package/dist/minimal/client.js +13 -1
  48. package/dist/minimal/client.js.map +1 -1
  49. package/dist/router/client.js +6 -2
  50. package/dist/router/client.js.map +1 -1
  51. package/dist/router/create-pages.d.ts +36 -2
  52. package/dist/router/create-pages.js +318 -321
  53. package/dist/router/create-pages.js.map +1 -1
  54. package/dist/router/define-router.d.ts +4 -0
  55. package/dist/router/define-router.js +142 -70
  56. package/dist/router/define-router.js.map +1 -1
  57. package/dist/router/fs-router.d.ts +18 -6
  58. package/dist/router/fs-router.js +28 -25
  59. package/dist/router/fs-router.js.map +1 -1
  60. package/dist/router/server.d.ts +1 -0
  61. package/dist/router/server.js.map +1 -1
  62. package/dist/vite-plugins.d.ts +5 -5
  63. package/dist/vite-plugins.js +5 -5
  64. package/dist/vite-plugins.js.map +1 -1
  65. package/package.json +7 -7
  66. package/dist/lib/vite-plugins/build-static-files.d.ts +0 -4
  67. package/dist/lib/vite-plugins/build-static-files.js.map +0 -1
  68. package/dist/lib/vite-plugins/default-adapter.d.ts +0 -4
  69. package/dist/lib/vite-plugins/default-adapter.js.map +0 -1
  70. package/dist/lib/vite-plugins/fallback-html.d.ts +0 -2
  71. package/dist/lib/vite-plugins/fallback-html.js.map +0 -1
  72. package/dist/lib/vite-plugins/main.js.map +0 -1
  73. package/dist/lib/vite-plugins/react-debug.d.ts +0 -2
  74. package/dist/lib/vite-plugins/react-debug.js.map +0 -1
  75. package/dist/lib/vite-plugins/user-entries.js.map +0 -1
package/README.md CHANGED
@@ -31,7 +31,7 @@ npm create waku@latest
31
31
  - `waku build` to generate a production build
32
32
  - `waku start` to serve the production build locally
33
33
 
34
- **Node.js version requirement:** `^24.0.0` or `^22.12.0` or `^20.19.0`
34
+ **Node.js version requirement:** `^26.0.0` or `^24.0.0` or `^22.12.0`
35
35
 
36
36
  ## Rendering
37
37
 
@@ -761,7 +761,7 @@ This allows you to have a `dynamic` slice component while keeping the rest of th
761
761
 
762
762
  ### Link
763
763
 
764
- The `<Link />` component should be used for internal links. It accepts a `to` prop for the destination, which is automatically prefetched ahead of the navigation.
764
+ 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
765
 
766
766
  ```tsx
767
767
  // ./src/pages/index.tsx
@@ -1027,6 +1027,26 @@ export const getConfig = async () => {
1027
1027
  };
1028
1028
  ```
1029
1029
 
1030
+ ## Middleware
1031
+
1032
+ 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`.
1033
+
1034
+ ```ts
1035
+ // ./src/middleware/logger.ts
1036
+ import type { MiddlewareHandler } from 'hono';
1037
+
1038
+ const logger = (): MiddlewareHandler => {
1039
+ return async (c, next) => {
1040
+ console.log(c.req.method, c.req.path);
1041
+ await next();
1042
+ };
1043
+ };
1044
+
1045
+ export default logger;
1046
+ ```
1047
+
1048
+ If you provide a custom `./src/waku.server.tsx`, pass middleware through the adapter options with `middlewareModules` or `middlewareFns`.
1049
+
1030
1050
  ## Data fetching
1031
1051
 
1032
1052
  ### Server
@@ -1454,10 +1474,9 @@ For advanced users who want to avoid deploying functions, use the server entry f
1454
1474
  import { fsRouter } from 'waku';
1455
1475
  import adapter from 'waku/adapters/vercel';
1456
1476
 
1457
- export default adapter(
1458
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1459
- { static: true },
1460
- );
1477
+ export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
1478
+ static: true,
1479
+ });
1461
1480
  ```
1462
1481
 
1463
1482
  ### Netlify
@@ -1479,10 +1498,9 @@ For advanced users who want to avoid deploying functions, use the server entry f
1479
1498
  import { fsRouter } from 'waku';
1480
1499
  import adapter from 'waku/adapters/netlify';
1481
1500
 
1482
- export default adapter(
1483
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1484
- { static: true },
1485
- );
1501
+ export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
1502
+ static: true,
1503
+ });
1486
1504
  ```
1487
1505
 
1488
1506
  ### Cloudflare Workers
@@ -1502,10 +1520,9 @@ wrangler deploy
1502
1520
  import { fsRouter } from 'waku';
1503
1521
  import adapter from 'waku/adapters/cloudflare';
1504
1522
 
1505
- export default adapter(
1506
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1507
- { static: true },
1508
- );
1523
+ export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')), {
1524
+ static: true,
1525
+ });
1509
1526
  ```
1510
1527
 
1511
1528
  ### Deno Deploy (experimental)
@@ -1516,9 +1533,7 @@ export default adapter(
1516
1533
  import { fsRouter } from 'waku';
1517
1534
  import adapter from 'waku/adapters/deno';
1518
1535
 
1519
- export default adapter(
1520
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1521
- );
1536
+ export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')));
1522
1537
  ```
1523
1538
 
1524
1539
  ```sh
@@ -1534,9 +1549,7 @@ deployctl deploy --prod dist/serve-deno.js --exclude node_modules
1534
1549
  import { fsRouter } from 'waku';
1535
1550
  import adapter from 'waku/adapters/bun';
1536
1551
 
1537
- export default adapter(
1538
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1539
- );
1552
+ export default adapter(fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')));
1540
1553
  ```
1541
1554
 
1542
1555
  ```sh
@@ -1552,8 +1565,8 @@ import { fsRouter } from 'waku';
1552
1565
  import adapter from 'waku/adapters/aws-lambda';
1553
1566
 
1554
1567
  export default adapter(
1555
- fsRouter(import.meta.glob('./**/*.{tsx,ts}', { base: './pages' })),
1556
- streaming: false, // optional, default is false
1568
+ fsRouter(import.meta.glob('./pages/**/*.{tsx,ts}')),
1569
+ { streaming: false }, // optional, default is false
1557
1570
  );
1558
1571
  ```
1559
1572
 
@@ -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
- const body = produceMultiplexedStream(async (emitFile)=>{
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,19 @@ 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
- const body = produceMultiplexedStream(async (emitFile)=>{
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
103
  const response = await fetch(server.baseUrl + internalPathToBuildStaticFiles);
102
- await consumeMultiplexedStream(response.body, utils.emitFile);
104
+ await consumeMultiplexedStream(response.body, async (key, stream)=>{
105
+ if (key.startsWith(PRUNABLE_KEY_PREFIX)) {
106
+ utils.unstable_registerPrunableFile(key.slice(PRUNABLE_KEY_PREFIX.length));
107
+ return;
108
+ }
109
+ await utils.emitFile(key, stream);
110
+ });
103
111
  await server.close();
104
112
  },
105
113
  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":"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"}
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 );\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 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","key","stream","startsWith","slice","length","buildEnhancers","defaultExport","handlers"],"mappings":"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"}
@@ -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 = (req: Request) => Promise<Response | null>;
64
- export type Unstable_ProcessBuild = (utils: {
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;
@@ -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 req: Request,\n) => Promise<Response | null>;\n\nexport type Unstable_ProcessBuild = (utils: {\n emitFile: Unstable_EmitFile;\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":"AAoGA,WAa8E"}
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 = `${globBase}/**/*.{${exts}}`;
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
- export default adapter(
15
- fsRouter(
16
- import.meta.glob(
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 globBase = `/${srcDir}/${SRC_PAGES}`;\n const exts = EXTENSIONS.map((ext) => ext.slice(1)).join(',');\n const globPattern = `${globBase}/**/*.{${exts}}`;\n const middlewareGlob = [\n `/${srcDir}/${SRC_MIDDLEWARE}/*.{${exts}}`,\n `!/${srcDir}/${SRC_MIDDLEWARE}/*.{test,spec}.{${exts}}`,\n ];\n return `\nimport { fsRouter } from 'waku';\nimport adapter from 'waku/adapters/default';\n\nexport default adapter(\n fsRouter(\n import.meta.glob(\n ${JSON.stringify(globPattern)},\n { base: ${JSON.stringify(globBase)} }\n )\n ),\n {\n middlewareModules: import.meta.glob(${JSON.stringify(middlewareGlob)}),\n },\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","globBase","exts","map","ext","slice","join","globPattern","middlewareGlob","JSON","stringify","getManagedClientEntry"],"mappings":"AAAA,SAASA,UAAU,EAAEC,cAAc,EAAEC,SAAS,QAAQ,kBAAkB;AAExE,OAAO,MAAMC,wBAAwB,CAACC;IACpC,MAAMC,WAAW,CAAC,CAAC,EAAED,OAAO,CAAC,EAAEF,WAAW;IAC1C,MAAMI,OAAON,WAAWO,GAAG,CAAC,CAACC,MAAQA,IAAIC,KAAK,CAAC,IAAIC,IAAI,CAAC;IACxD,MAAMC,cAAc,GAAGN,SAAS,OAAO,EAAEC,KAAK,CAAC,CAAC;IAChD,MAAMM,iBAAiB;QACrB,CAAC,CAAC,EAAER,OAAO,CAAC,EAAEH,eAAe,IAAI,EAAEK,KAAK,CAAC,CAAC;QAC1C,CAAC,EAAE,EAAEF,OAAO,CAAC,EAAEH,eAAe,gBAAgB,EAAEK,KAAK,CAAC,CAAC;KACxD;IACD,OAAO,CAAC;;;;;;;MAOJ,EAAEO,KAAKC,SAAS,CAACH,aAAa;cACtB,EAAEE,KAAKC,SAAS,CAACT,UAAU;;;;wCAID,EAAEQ,KAAKC,SAAS,CAACF,gBAAgB;;;AAGzE,CAAC;AACD,EAAE;AAEF,OAAO,MAAMG,wBAAwB;IACnC,OAAO,CAAC;;;;;;;;;;;;;AAaV,CAAC;AACD,EAAE"}
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"}
@@ -0,0 +1,29 @@
1
+ type Chunk = {
2
+ type: 'chunk';
3
+ fileName: string;
4
+ imports: string[];
5
+ dynamicImports: string[];
6
+ facadeModuleId: string | null;
7
+ isDynamicEntry: boolean;
8
+ isEntry: boolean;
9
+ name: string;
10
+ viteMetadata?: {
11
+ importedAssets?: Set<string>;
12
+ importedCss?: Set<string>;
13
+ };
14
+ };
15
+ type Asset = {
16
+ type: 'asset';
17
+ fileName: string;
18
+ };
19
+ export declare const pruneBuildOutput: ({ rootDir, srcDir, distDir, rscBundle, prunableFiles, }: {
20
+ rootDir: string;
21
+ srcDir: string;
22
+ distDir: string;
23
+ rscBundle: Record<string, Chunk | Asset>;
24
+ prunableFiles: string[];
25
+ }) => Promise<{
26
+ stubbedChunks: string[];
27
+ deletedAssets: string[];
28
+ }>;
29
+ export {};
@@ -0,0 +1,96 @@
1
+ import { rm, writeFile } from 'node:fs/promises';
2
+ import { DIST_SERVER } from '../constants.js';
3
+ import { joinPath } from './path.js';
4
+ // Removes server-bundle files unreachable except via `prunableFiles`:
5
+ // - chunks: stubbed (so dynamic imports still resolve)
6
+ // - emitted assets (CSS, fonts, wasm, ...): deleted
7
+ // Reachability roots are bundle entries plus non-pruned dynamic-entry chunks.
8
+ export const pruneBuildOutput = async ({ rootDir, srcDir, distDir, rscBundle, prunableFiles })=>{
9
+ if (prunableFiles.length === 0) {
10
+ return {
11
+ stubbedChunks: [],
12
+ deletedAssets: []
13
+ };
14
+ }
15
+ const prunableModuleIds = new Set(prunableFiles.map((p)=>joinPath(rootDir, srcDir, p)));
16
+ const chunks = [];
17
+ const assets = [];
18
+ for (const item of Object.values(rscBundle)){
19
+ if (item.type === 'chunk') {
20
+ chunks.push(item);
21
+ } else {
22
+ assets.push(item);
23
+ }
24
+ }
25
+ const chunkMap = new Map(chunks.map((c)=>[
26
+ c.fileName,
27
+ c
28
+ ]));
29
+ const viteAssetsOf = (chunk)=>[
30
+ ...chunk.viteMetadata?.importedAssets ?? [],
31
+ ...chunk.viteMetadata?.importedCss ?? []
32
+ ];
33
+ // Standalone assets (e.g. `wrangler.json` from @cloudflare/vite-plugin)
34
+ // aren't ours to manage.
35
+ const chunkImportedAssets = new Set();
36
+ for (const chunk of chunks){
37
+ for (const a of viteAssetsOf(chunk)){
38
+ chunkImportedAssets.add(a);
39
+ }
40
+ }
41
+ const allDynamicEntryFiles = new Set();
42
+ const keepRoots = [];
43
+ for (const chunk of chunks){
44
+ if (chunk.isDynamicEntry) {
45
+ allDynamicEntryFiles.add(chunk.fileName);
46
+ const isPrunable = chunk.facadeModuleId && prunableModuleIds.has(chunk.facadeModuleId);
47
+ if (!isPrunable) {
48
+ keepRoots.push(chunk.fileName);
49
+ }
50
+ }
51
+ // The 'build' entry is the SSG runner, not part of the runtime bundle.
52
+ if (chunk.isEntry && chunk.name !== 'build') {
53
+ keepRoots.push(chunk.fileName);
54
+ }
55
+ }
56
+ // Each page subtree is evaluated independently - don't follow dynamic
57
+ // imports across other dynamic-entry chunks.
58
+ const keepFiles = new Set();
59
+ const visit = (fileName)=>{
60
+ if (keepFiles.has(fileName)) {
61
+ return;
62
+ }
63
+ keepFiles.add(fileName);
64
+ const chunk = chunkMap.get(fileName);
65
+ if (!chunk) {
66
+ return;
67
+ }
68
+ for (const imp of chunk.imports){
69
+ visit(imp);
70
+ }
71
+ for (const dyn of chunk.dynamicImports){
72
+ if (!allDynamicEntryFiles.has(dyn)) {
73
+ visit(dyn);
74
+ }
75
+ }
76
+ for (const a of viteAssetsOf(chunk)){
77
+ keepFiles.add(a);
78
+ }
79
+ };
80
+ keepRoots.forEach(visit);
81
+ const serverDir = joinPath(rootDir, distDir, DIST_SERVER);
82
+ const stubbedChunks = chunks.map((c)=>c.fileName).filter((f)=>!keepFiles.has(f));
83
+ const deletedAssets = assets.map((a)=>a.fileName).filter((f)=>chunkImportedAssets.has(f) && !keepFiles.has(f));
84
+ await Promise.all([
85
+ ...stubbedChunks.map((f)=>writeFile(joinPath(serverDir, f), '// Pruned by Waku - content cached at build time.\n')),
86
+ ...deletedAssets.map((f)=>rm(joinPath(serverDir, f), {
87
+ force: true
88
+ }))
89
+ ]);
90
+ return {
91
+ stubbedChunks,
92
+ deletedAssets
93
+ };
94
+ };
95
+
96
+ //# sourceMappingURL=prune-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils/prune-build.ts"],"sourcesContent":["import { rm, writeFile } from 'node:fs/promises';\nimport { DIST_SERVER } from '../constants.js';\nimport { joinPath } from './path.js';\n\ntype Chunk = {\n type: 'chunk';\n fileName: string;\n imports: string[];\n dynamicImports: string[];\n facadeModuleId: string | null;\n isDynamicEntry: boolean;\n isEntry: boolean;\n name: string;\n viteMetadata?: {\n importedAssets?: Set<string>;\n importedCss?: Set<string>;\n };\n};\ntype Asset = {\n type: 'asset';\n fileName: string;\n};\n\n// Removes server-bundle files unreachable except via `prunableFiles`:\n// - chunks: stubbed (so dynamic imports still resolve)\n// - emitted assets (CSS, fonts, wasm, ...): deleted\n// Reachability roots are bundle entries plus non-pruned dynamic-entry chunks.\nexport const pruneBuildOutput = async ({\n rootDir,\n srcDir,\n distDir,\n rscBundle,\n prunableFiles,\n}: {\n rootDir: string;\n srcDir: string;\n distDir: string;\n rscBundle: Record<string, Chunk | Asset>;\n prunableFiles: string[];\n}): Promise<{ stubbedChunks: string[]; deletedAssets: string[] }> => {\n if (prunableFiles.length === 0) {\n return { stubbedChunks: [], deletedAssets: [] };\n }\n const prunableModuleIds = new Set(\n prunableFiles.map((p) => joinPath(rootDir, srcDir, p)),\n );\n\n const chunks: Chunk[] = [];\n const assets: Asset[] = [];\n for (const item of Object.values(rscBundle)) {\n if (item.type === 'chunk') {\n chunks.push(item);\n } else {\n assets.push(item);\n }\n }\n const chunkMap = new Map(chunks.map((c) => [c.fileName, c]));\n\n const viteAssetsOf = (chunk: Chunk) => [\n ...(chunk.viteMetadata?.importedAssets ?? []),\n ...(chunk.viteMetadata?.importedCss ?? []),\n ];\n\n // Standalone assets (e.g. `wrangler.json` from @cloudflare/vite-plugin)\n // aren't ours to manage.\n const chunkImportedAssets = new Set<string>();\n for (const chunk of chunks) {\n for (const a of viteAssetsOf(chunk)) {\n chunkImportedAssets.add(a);\n }\n }\n\n const allDynamicEntryFiles = new Set<string>();\n const keepRoots: string[] = [];\n for (const chunk of chunks) {\n if (chunk.isDynamicEntry) {\n allDynamicEntryFiles.add(chunk.fileName);\n const isPrunable =\n chunk.facadeModuleId && prunableModuleIds.has(chunk.facadeModuleId);\n if (!isPrunable) {\n keepRoots.push(chunk.fileName);\n }\n }\n // The 'build' entry is the SSG runner, not part of the runtime bundle.\n if (chunk.isEntry && chunk.name !== 'build') {\n keepRoots.push(chunk.fileName);\n }\n }\n\n // Each page subtree is evaluated independently - don't follow dynamic\n // imports across other dynamic-entry chunks.\n const keepFiles = new Set<string>();\n const visit = (fileName: string) => {\n if (keepFiles.has(fileName)) {\n return;\n }\n keepFiles.add(fileName);\n const chunk = chunkMap.get(fileName);\n if (!chunk) {\n return;\n }\n for (const imp of chunk.imports) {\n visit(imp);\n }\n for (const dyn of chunk.dynamicImports) {\n if (!allDynamicEntryFiles.has(dyn)) {\n visit(dyn);\n }\n }\n for (const a of viteAssetsOf(chunk)) {\n keepFiles.add(a);\n }\n };\n keepRoots.forEach(visit);\n\n const serverDir = joinPath(rootDir, distDir, DIST_SERVER);\n const stubbedChunks = chunks\n .map((c) => c.fileName)\n .filter((f) => !keepFiles.has(f));\n const deletedAssets = assets\n .map((a) => a.fileName)\n .filter((f) => chunkImportedAssets.has(f) && !keepFiles.has(f));\n\n await Promise.all([\n ...stubbedChunks.map((f) =>\n writeFile(\n joinPath(serverDir, f),\n '// Pruned by Waku - content cached at build time.\\n',\n ),\n ),\n ...deletedAssets.map((f) => rm(joinPath(serverDir, f), { force: true })),\n ]);\n\n return { stubbedChunks, deletedAssets };\n};\n"],"names":["rm","writeFile","DIST_SERVER","joinPath","pruneBuildOutput","rootDir","srcDir","distDir","rscBundle","prunableFiles","length","stubbedChunks","deletedAssets","prunableModuleIds","Set","map","p","chunks","assets","item","Object","values","type","push","chunkMap","Map","c","fileName","viteAssetsOf","chunk","viteMetadata","importedAssets","importedCss","chunkImportedAssets","a","add","allDynamicEntryFiles","keepRoots","isDynamicEntry","isPrunable","facadeModuleId","has","isEntry","name","keepFiles","visit","get","imp","imports","dyn","dynamicImports","forEach","serverDir","filter","f","Promise","all","force"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { Unstable_ParseRsc, Unstable_RenderHtml, Unstable_RenderRsc } from '../types.js';
2
- export declare function createRenderUtils(temporaryReferences: unknown, renderToReadableStream: (data: unknown, options?: object, extraOptions?: object) => ReadableStream, createFromReadableStream: (stream: ReadableStream, options?: object) => Promise<unknown>, loadSsrEntryModule: () => Promise<typeof import('../vite-entries/entry.ssr.js')>, debugChannel?: {
2
+ export declare function createRenderUtils(temporaryReferences: unknown, renderToReadableStream: (data: unknown, options?: object, extraOptions?: object) => ReadableStream, createFromReadableStream: (stream: ReadableStream, options?: object) => Promise<unknown>, loadSsrEntryModule: () => Promise<typeof import('../vite-entries/entry.ssr.js')>, buildId: string, debugChannel?: {
3
3
  readable?: ReadableStream;
4
4
  writable?: WritableStream;
5
5
  }, debugId?: string): {
@@ -1,4 +1,11 @@
1
- export function createRenderUtils(temporaryReferences, renderToReadableStream, createFromReadableStream, loadSsrEntryModule, debugChannel, debugId) {
1
+ const validateRscElementIds = (elements)=>{
2
+ for (const id of Object.keys(elements)){
3
+ if (id.startsWith('_')) {
4
+ throw new Error(`RSC element IDs starting with "_" are reserved for Waku internals: ${id}`);
5
+ }
6
+ }
7
+ };
8
+ export function createRenderUtils(temporaryReferences, renderToReadableStream, createFromReadableStream, loadSsrEntryModule, buildId, debugChannel, debugId) {
2
9
  const onError = (e)=>{
3
10
  if (e && typeof e === 'object' && 'digest' in e && typeof e.digest === 'string') {
4
11
  return e.digest;
@@ -7,7 +14,17 @@ export function createRenderUtils(temporaryReferences, renderToReadableStream, c
7
14
  };
8
15
  return {
9
16
  async renderRsc (elements, options) {
10
- return renderToReadableStream(elements, {
17
+ validateRscElementIds(elements);
18
+ const data = buildId ? {
19
+ ...elements,
20
+ _buildId: buildId
21
+ } : {
22
+ ...elements
23
+ };
24
+ if (options && 'value' in options) {
25
+ data._value = options.value;
26
+ }
27
+ return renderToReadableStream(data, {
11
28
  temporaryReferences,
12
29
  onError,
13
30
  debugChannel
@@ -35,7 +52,7 @@ export function createRenderUtils(temporaryReferences, renderToReadableStream, c
35
52
  return new Response(htmlResult.stream, {
36
53
  status: htmlResult.status || options.status || 200,
37
54
  headers: {
38
- 'content-type': 'text/html'
55
+ 'content-type': 'text/html; charset=utf-8'
39
56
  }
40
57
  });
41
58
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/utils/render.ts"],"sourcesContent":["import type {\n Unstable_ParseRsc,\n Unstable_RenderHtml,\n Unstable_RenderRsc,\n} from '../types.js';\n\nexport function createRenderUtils(\n temporaryReferences: unknown,\n renderToReadableStream: (\n data: unknown,\n options?: object,\n extraOptions?: object,\n ) => ReadableStream,\n createFromReadableStream: (\n stream: ReadableStream,\n options?: object,\n ) => Promise<unknown>,\n loadSsrEntryModule: () => Promise<\n typeof import('../vite-entries/entry.ssr.js')\n >,\n debugChannel?: { readable?: ReadableStream; writable?: WritableStream },\n debugId?: string,\n): {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n} {\n const onError = (e: unknown) => {\n if (\n e &&\n typeof e === 'object' &&\n 'digest' in e &&\n typeof e.digest === 'string'\n ) {\n return e.digest;\n }\n console.error('Error during rendering:', e);\n };\n\n return {\n async renderRsc(elements, options) {\n return renderToReadableStream(\n elements,\n {\n temporaryReferences,\n onError,\n debugChannel,\n },\n {\n onClientReference(metadata: {\n id: string;\n name: string;\n deps: { js: string[]; css: string[] };\n }) {\n options?.unstable_clientModuleCallback?.(metadata.deps.js);\n },\n },\n );\n },\n async parseRsc(stream) {\n return createFromReadableStream(stream, {}) as Promise<\n Record<string, unknown>\n >;\n },\n async renderHtml(elementsStream, html, options) {\n const { INTERNAL_renderHtmlStream: renderHtmlStream } =\n await loadSsrEntryModule();\n\n const rscHtmlStream = renderToReadableStream(html, {\n onError,\n });\n const htmlResult = await renderHtmlStream(elementsStream, rscHtmlStream, {\n rscPath: options.rscPath,\n formState: options.formState as never,\n nonce: options.nonce,\n extraScriptContent: options.unstable_extraScriptContent,\n debugId,\n });\n return new Response(htmlResult.stream, {\n status: htmlResult.status || options.status || 200,\n headers: { 'content-type': 'text/html' },\n });\n },\n };\n}\n"],"names":["createRenderUtils","temporaryReferences","renderToReadableStream","createFromReadableStream","loadSsrEntryModule","debugChannel","debugId","onError","e","digest","console","error","renderRsc","elements","options","onClientReference","metadata","unstable_clientModuleCallback","deps","js","parseRsc","stream","renderHtml","elementsStream","html","INTERNAL_renderHtmlStream","renderHtmlStream","rscHtmlStream","htmlResult","rscPath","formState","nonce","extraScriptContent","unstable_extraScriptContent","Response","status","headers"],"mappings":"AAMA,OAAO,SAASA,kBACdC,mBAA4B,EAC5BC,sBAImB,EACnBC,wBAGqB,EACrBC,kBAEC,EACDC,YAAuE,EACvEC,OAAgB;IAMhB,MAAMC,UAAU,CAACC;QACf,IACEA,KACA,OAAOA,MAAM,YACb,YAAYA,KACZ,OAAOA,EAAEC,MAAM,KAAK,UACpB;YACA,OAAOD,EAAEC,MAAM;QACjB;QACAC,QAAQC,KAAK,CAAC,2BAA2BH;IAC3C;IAEA,OAAO;QACL,MAAMI,WAAUC,QAAQ,EAAEC,OAAO;YAC/B,OAAOZ,uBACLW,UACA;gBACEZ;gBACAM;gBACAF;YACF,GACA;gBACEU,mBAAkBC,QAIjB;oBACCF,SAASG,gCAAgCD,SAASE,IAAI,CAACC,EAAE;gBAC3D;YACF;QAEJ;QACA,MAAMC,UAASC,MAAM;YACnB,OAAOlB,yBAAyBkB,QAAQ,CAAC;QAG3C;QACA,MAAMC,YAAWC,cAAc,EAAEC,IAAI,EAAEV,OAAO;YAC5C,MAAM,EAAEW,2BAA2BC,gBAAgB,EAAE,GACnD,MAAMtB;YAER,MAAMuB,gBAAgBzB,uBAAuBsB,MAAM;gBACjDjB;YACF;YACA,MAAMqB,aAAa,MAAMF,iBAAiBH,gBAAgBI,eAAe;gBACvEE,SAASf,QAAQe,OAAO;gBACxBC,WAAWhB,QAAQgB,SAAS;gBAC5BC,OAAOjB,QAAQiB,KAAK;gBACpBC,oBAAoBlB,QAAQmB,2BAA2B;gBACvD3B;YACF;YACA,OAAO,IAAI4B,SAASN,WAAWP,MAAM,EAAE;gBACrCc,QAAQP,WAAWO,MAAM,IAAIrB,QAAQqB,MAAM,IAAI;gBAC/CC,SAAS;oBAAE,gBAAgB;gBAAY;YACzC;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/lib/utils/render.ts"],"sourcesContent":["import type {\n Unstable_ParseRsc,\n Unstable_RenderHtml,\n Unstable_RenderRsc,\n} from '../types.js';\n\nconst validateRscElementIds = (elements: Record<string, unknown>) => {\n for (const id of Object.keys(elements)) {\n if (id.startsWith('_')) {\n throw new Error(\n `RSC element IDs starting with \"_\" are reserved for Waku internals: ${id}`,\n );\n }\n }\n};\n\nexport function createRenderUtils(\n temporaryReferences: unknown,\n renderToReadableStream: (\n data: unknown,\n options?: object,\n extraOptions?: object,\n ) => ReadableStream,\n createFromReadableStream: (\n stream: ReadableStream,\n options?: object,\n ) => Promise<unknown>,\n loadSsrEntryModule: () => Promise<\n typeof import('../vite-entries/entry.ssr.js')\n >,\n buildId: string,\n debugChannel?: { readable?: ReadableStream; writable?: WritableStream },\n debugId?: string,\n): {\n renderRsc: Unstable_RenderRsc;\n parseRsc: Unstable_ParseRsc;\n renderHtml: Unstable_RenderHtml;\n} {\n const onError = (e: unknown) => {\n if (\n e &&\n typeof e === 'object' &&\n 'digest' in e &&\n typeof e.digest === 'string'\n ) {\n return e.digest;\n }\n console.error('Error during rendering:', e);\n };\n\n return {\n async renderRsc(elements, options) {\n validateRscElementIds(elements);\n const data: Record<string, unknown> = buildId\n ? { ...elements, _buildId: buildId }\n : { ...elements };\n if (options && 'value' in options) {\n data._value = options.value;\n }\n return renderToReadableStream(\n data,\n {\n temporaryReferences,\n onError,\n debugChannel,\n },\n {\n onClientReference(metadata: {\n id: string;\n name: string;\n deps: { js: string[]; css: string[] };\n }) {\n options?.unstable_clientModuleCallback?.(metadata.deps.js);\n },\n },\n );\n },\n async parseRsc(stream) {\n return createFromReadableStream(stream, {}) as Promise<\n Record<string, unknown>\n >;\n },\n async renderHtml(elementsStream, html, options) {\n const { INTERNAL_renderHtmlStream: renderHtmlStream } =\n await loadSsrEntryModule();\n\n const rscHtmlStream = renderToReadableStream(html, {\n onError,\n });\n const htmlResult = await renderHtmlStream(elementsStream, rscHtmlStream, {\n rscPath: options.rscPath,\n formState: options.formState as never,\n nonce: options.nonce,\n extraScriptContent: options.unstable_extraScriptContent,\n debugId,\n });\n return new Response(htmlResult.stream, {\n status: htmlResult.status || options.status || 200,\n headers: { 'content-type': 'text/html; charset=utf-8' },\n });\n },\n };\n}\n"],"names":["validateRscElementIds","elements","id","Object","keys","startsWith","Error","createRenderUtils","temporaryReferences","renderToReadableStream","createFromReadableStream","loadSsrEntryModule","buildId","debugChannel","debugId","onError","e","digest","console","error","renderRsc","options","data","_buildId","_value","value","onClientReference","metadata","unstable_clientModuleCallback","deps","js","parseRsc","stream","renderHtml","elementsStream","html","INTERNAL_renderHtmlStream","renderHtmlStream","rscHtmlStream","htmlResult","rscPath","formState","nonce","extraScriptContent","unstable_extraScriptContent","Response","status","headers"],"mappings":"AAMA,MAAMA,wBAAwB,CAACC;IAC7B,KAAK,MAAMC,MAAMC,OAAOC,IAAI,CAACH,UAAW;QACtC,IAAIC,GAAGG,UAAU,CAAC,MAAM;YACtB,MAAM,IAAIC,MACR,CAAC,mEAAmE,EAAEJ,IAAI;QAE9E;IACF;AACF;AAEA,OAAO,SAASK,kBACdC,mBAA4B,EAC5BC,sBAImB,EACnBC,wBAGqB,EACrBC,kBAEC,EACDC,OAAe,EACfC,YAAuE,EACvEC,OAAgB;IAMhB,MAAMC,UAAU,CAACC;QACf,IACEA,KACA,OAAOA,MAAM,YACb,YAAYA,KACZ,OAAOA,EAAEC,MAAM,KAAK,UACpB;YACA,OAAOD,EAAEC,MAAM;QACjB;QACAC,QAAQC,KAAK,CAAC,2BAA2BH;IAC3C;IAEA,OAAO;QACL,MAAMI,WAAUnB,QAAQ,EAAEoB,OAAO;YAC/BrB,sBAAsBC;YACtB,MAAMqB,OAAgCV,UAClC;gBAAE,GAAGX,QAAQ;gBAAEsB,UAAUX;YAAQ,IACjC;gBAAE,GAAGX,QAAQ;YAAC;YAClB,IAAIoB,WAAW,WAAWA,SAAS;gBACjCC,KAAKE,MAAM,GAAGH,QAAQI,KAAK;YAC7B;YACA,OAAOhB,uBACLa,MACA;gBACEd;gBACAO;gBACAF;YACF,GACA;gBACEa,mBAAkBC,QAIjB;oBACCN,SAASO,gCAAgCD,SAASE,IAAI,CAACC,EAAE;gBAC3D;YACF;QAEJ;QACA,MAAMC,UAASC,MAAM;YACnB,OAAOtB,yBAAyBsB,QAAQ,CAAC;QAG3C;QACA,MAAMC,YAAWC,cAAc,EAAEC,IAAI,EAAEd,OAAO;YAC5C,MAAM,EAAEe,2BAA2BC,gBAAgB,EAAE,GACnD,MAAM1B;YAER,MAAM2B,gBAAgB7B,uBAAuB0B,MAAM;gBACjDpB;YACF;YACA,MAAMwB,aAAa,MAAMF,iBAAiBH,gBAAgBI,eAAe;gBACvEE,SAASnB,QAAQmB,OAAO;gBACxBC,WAAWpB,QAAQoB,SAAS;gBAC5BC,OAAOrB,QAAQqB,KAAK;gBACpBC,oBAAoBtB,QAAQuB,2BAA2B;gBACvD9B;YACF;YACA,OAAO,IAAI+B,SAASN,WAAWP,MAAM,EAAE;gBACrCc,QAAQP,WAAWO,MAAM,IAAIzB,QAAQyB,MAAM,IAAI;gBAC/CC,SAAS;oBAAE,gBAAgB;gBAA2B;YACxD;QACF;IACF;AACF"}
@@ -7,6 +7,11 @@ if (import.meta.hot) {
7
7
  globalThis.__WAKU_RSC_RELOAD_LISTENERS__?.forEach((l)=>l());
8
8
  });
9
9
  }
10
+ if (import.meta.env.WAKU_BUILD_ID) {
11
+ window.addEventListener('vite:preloadError', ()=>{
12
+ window.location.reload();
13
+ });
14
+ }
10
15
  import 'virtual:vite-rsc-waku/client-entry';
11
16
 
12
17
  //# sourceMappingURL=entry.browser.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/vite-entries/entry.browser.tsx"],"sourcesContent":["import { setServerCallback } from '@vitejs/plugin-rsc/browser';\nimport { unstable_callServerRsc } from '../../minimal/client.js';\nsetServerCallback(unstable_callServerRsc);\n\nif (import.meta.hot) {\n import.meta.hot.on('rsc:update', (e) => {\n console.log('[rsc:update]', e);\n globalThis.__WAKU_RSC_RELOAD_LISTENERS__?.forEach((l) => l());\n });\n}\n\nimport 'virtual:vite-rsc-waku/client-entry';\n"],"names":["setServerCallback","unstable_callServerRsc","hot","on","e","console","log","globalThis","__WAKU_RSC_RELOAD_LISTENERS__","forEach","l"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,6BAA6B;AAC/D,SAASC,sBAAsB,QAAQ,0BAA0B;AACjED,kBAAkBC;AAElB,IAAI,YAAYC,GAAG,EAAE;IACnB,YAAYA,GAAG,CAACC,EAAE,CAAC,cAAc,CAACC;QAChCC,QAAQC,GAAG,CAAC,gBAAgBF;QAC5BG,WAAWC,6BAA6B,EAAEC,QAAQ,CAACC,IAAMA;IAC3D;AACF;AAEA,OAAO,qCAAqC"}
1
+ {"version":3,"sources":["../../../src/lib/vite-entries/entry.browser.tsx"],"sourcesContent":["import { setServerCallback } from '@vitejs/plugin-rsc/browser';\nimport { unstable_callServerRsc } from '../../minimal/client.js';\nsetServerCallback(unstable_callServerRsc);\n\nif (import.meta.hot) {\n import.meta.hot.on('rsc:update', (e) => {\n console.log('[rsc:update]', e);\n globalThis.__WAKU_RSC_RELOAD_LISTENERS__?.forEach((l) => l());\n });\n}\n\nif (import.meta.env.WAKU_BUILD_ID) {\n window.addEventListener('vite:preloadError', () => {\n window.location.reload();\n });\n}\n\nimport 'virtual:vite-rsc-waku/client-entry';\n"],"names":["setServerCallback","unstable_callServerRsc","hot","on","e","console","log","globalThis","__WAKU_RSC_RELOAD_LISTENERS__","forEach","l","env","WAKU_BUILD_ID","window","addEventListener","location","reload"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,6BAA6B;AAC/D,SAASC,sBAAsB,QAAQ,0BAA0B;AACjED,kBAAkBC;AAElB,IAAI,YAAYC,GAAG,EAAE;IACnB,YAAYA,GAAG,CAACC,EAAE,CAAC,cAAc,CAACC;QAChCC,QAAQC,GAAG,CAAC,gBAAgBF;QAC5BG,WAAWC,6BAA6B,EAAEC,QAAQ,CAACC,IAAMA;IAC3D;AACF;AAEA,IAAI,YAAYC,GAAG,CAACC,aAAa,EAAE;IACjCC,OAAOC,gBAAgB,CAAC,qBAAqB;QAC3CD,OAAOE,QAAQ,CAACC,MAAM;IACxB;AACF;AAEA,OAAO,qCAAqC"}
@@ -2,4 +2,6 @@ import type { Unstable_EmitFile } from '../types.js';
2
2
  export declare function INTERNAL_runBuild({ rootDir, emitFile, }: {
3
3
  rootDir: string;
4
4
  emitFile: Unstable_EmitFile;
5
- }): Promise<void>;
5
+ }): Promise<{
6
+ prunableFiles: string[];
7
+ }>;