waku 1.0.0-beta.7 → 1.0.0-beta.8
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 +1 -1
- package/dist/lib/types.d.ts +10 -9
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils/react-debug-channel.js +7 -0
- package/dist/lib/utils/react-debug-channel.js.map +1 -1
- package/dist/lib/utils/render.d.ts +2 -3
- package/dist/lib/utils/render.js +1 -4
- package/dist/lib/utils/render.js.map +1 -1
- package/dist/lib/utils/request.d.ts +10 -6
- package/dist/lib/utils/request.js +24 -19
- package/dist/lib/utils/request.js.map +1 -1
- package/dist/lib/vite-plugins/patch-rsdw.js +8 -2
- package/dist/lib/vite-plugins/patch-rsdw.js.map +1 -1
- package/dist/lib/vite-rsc/cmd-dev.js +11 -8
- package/dist/lib/vite-rsc/cmd-dev.js.map +1 -1
- package/dist/lib/vite-rsc/cmd-start.js +2 -1
- package/dist/lib/vite-rsc/cmd-start.js.map +1 -1
- package/dist/lib/vite-rsc/handler.js +3 -4
- package/dist/lib/vite-rsc/handler.js.map +1 -1
- package/dist/minimal/client.d.ts +3 -0
- package/dist/minimal/client.js +38 -18
- package/dist/minimal/client.js.map +1 -1
- package/dist/router/base-types.d.ts +2 -1
- package/dist/router/base-types.js.map +1 -1
- package/dist/router/client-utils/elements-meta.d.ts +6 -0
- package/dist/router/client-utils/elements-meta.js +21 -0
- package/dist/router/client-utils/elements-meta.js.map +1 -0
- package/dist/router/client-utils/navigate.d.ts +11 -5
- package/dist/router/client-utils/navigate.js +29 -12
- package/dist/router/client-utils/navigate.js.map +1 -1
- package/dist/router/client-utils/prefetch-cache.d.ts +21 -0
- package/dist/router/{prefetch-cache.js → client-utils/prefetch-cache.js} +18 -4
- package/dist/router/client-utils/prefetch-cache.js.map +1 -0
- package/dist/router/client.d.ts +4 -3
- package/dist/router/client.js +233 -235
- package/dist/router/client.js.map +1 -1
- package/dist/router/create-pages-utils/inferred-path-types.d.ts +1 -14
- package/dist/router/create-pages-utils/inferred-path-types.js.map +1 -1
- package/dist/router/create-pages.d.ts +3 -60
- package/dist/router/create-pages.js.map +1 -1
- package/dist/router/define-router-utils/build-handler.d.ts +11 -0
- package/dist/router/define-router-utils/build-handler.js +234 -0
- package/dist/router/define-router-utils/build-handler.js.map +1 -0
- package/dist/router/define-router-utils/build-metadata.d.ts +5 -0
- package/dist/router/define-router-utils/build-metadata.js +7 -0
- package/dist/router/define-router-utils/build-metadata.js.map +1 -0
- package/dist/router/define-router-utils/client-code.d.ts +3 -0
- package/dist/router/define-router-utils/client-code.js +51 -0
- package/dist/router/define-router-utils/client-code.js.map +1 -0
- package/dist/router/define-router-utils/config-registry.d.ts +18 -0
- package/dist/router/define-router-utils/config-registry.js +100 -0
- package/dist/router/define-router-utils/config-registry.js.map +1 -0
- package/dist/router/define-router-utils/config-serialization.d.ts +5 -0
- package/dist/router/define-router-utils/config-serialization.js +140 -0
- package/dist/router/define-router-utils/config-serialization.js.map +1 -0
- package/dist/router/define-router-utils/config-types.d.ts +65 -0
- package/dist/router/define-router-utils/config-types.js +3 -0
- package/dist/router/define-router-utils/config-types.js.map +1 -0
- package/dist/router/define-router-utils/element-cache.d.ts +14 -0
- package/dist/router/define-router-utils/element-cache.js +42 -0
- package/dist/router/define-router-utils/element-cache.js.map +1 -0
- package/dist/router/define-router-utils/request-handler.d.ts +10 -0
- package/dist/router/define-router-utils/request-handler.js +210 -0
- package/dist/router/define-router-utils/request-handler.js.map +1 -0
- package/dist/router/define-router-utils/request-store.d.ts +32 -0
- package/dist/router/define-router-utils/request-store.js +62 -0
- package/dist/router/define-router-utils/request-store.js.map +1 -0
- package/dist/router/define-router-utils/route-entries.d.ts +15 -0
- package/dist/router/define-router-utils/route-entries.js +130 -0
- package/dist/router/define-router-utils/route-entries.js.map +1 -0
- package/dist/router/define-router.d.ts +4 -73
- package/dist/router/define-router.js +25 -879
- package/dist/router/define-router.js.map +1 -1
- package/dist/router/fs-router.d.ts +1 -60
- package/dist/router/fs-router.js.map +1 -1
- package/dist/router/isomorphic-utils/build-route-href.d.ts +2 -1
- package/dist/router/isomorphic-utils/build-route-href.js.map +1 -1
- package/dist/router/isomorphic-utils/route-path.d.ts +4 -0
- package/dist/router/isomorphic-utils/route-path.js +6 -0
- package/dist/router/isomorphic-utils/route-path.js.map +1 -1
- package/dist/router/isomorphic-utils/search-codec-registry.d.ts +14 -1
- package/dist/router/isomorphic-utils/search-codec-registry.js +9 -1
- package/dist/router/isomorphic-utils/search-codec-registry.js.map +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/package.json +8 -8
- package/dist/router/prefetch-cache.d.ts +0 -22
- package/dist/router/prefetch-cache.js.map +0 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ While there's a bit of a learning curve to modern React rendering, it introduces
|
|
|
39
39
|
|
|
40
40
|
So please don't be intimidated by the `'use client'` directive! Once you get the hang of it, you'll appreciate how awesome it is to flexibly move server-client boundaries with a single line of code as your full-stack React codebase evolves over time. It's way simpler than maintaining separate codebases for your backend and frontend.
|
|
41
41
|
|
|
42
|
-
And please don't fret about client components! Even if you only lightly optimize towards server components, your client bundle size will be smaller than
|
|
42
|
+
And please don't fret about client components! Even if you only lightly optimize towards server components, your client bundle size will be smaller than that of a fully client-rendered React app.
|
|
43
43
|
|
|
44
44
|
> Future versions of Waku may provide additional opt-in APIs to abstract some of the complexity away for an improved developer experience.
|
|
45
45
|
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -7,7 +7,6 @@ export type Unstable_RenderRsc = (elements: Elements, options?: {
|
|
|
7
7
|
etags?: Etags;
|
|
8
8
|
unstable_clientModuleCallback?: (ids: string[]) => void;
|
|
9
9
|
}) => Promise<ReadableStream>;
|
|
10
|
-
export type Unstable_ParseRsc = (rscStream: ReadableStream) => Promise<Elements>;
|
|
11
10
|
export type Unstable_RenderHtml = (elementsStream: ReadableStream, html: ReactNode, options: {
|
|
12
11
|
rscPath: string;
|
|
13
12
|
formState?: unknown;
|
|
@@ -17,31 +16,33 @@ export type Unstable_RenderHtml = (elementsStream: ReadableStream, html: ReactNo
|
|
|
17
16
|
}) => Promise<Response>;
|
|
18
17
|
export type Unstable_EmitFile = (filePath: string, body: ReadableStream) => Promise<void>;
|
|
19
18
|
export type Unstable_HandleRequest = (input: ({
|
|
20
|
-
type: '
|
|
19
|
+
type: 'rsc';
|
|
21
20
|
rscPath: string;
|
|
22
21
|
rscParams: unknown;
|
|
23
22
|
} | {
|
|
24
|
-
type: '
|
|
23
|
+
type: 'call';
|
|
25
24
|
fn: (...args: unknown[]) => Promise<unknown>;
|
|
26
25
|
args: unknown[];
|
|
27
26
|
} | {
|
|
28
|
-
type: '
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
type: 'http';
|
|
28
|
+
tryAction?: () => Promise<{
|
|
29
|
+
action: true;
|
|
30
|
+
formState: unknown;
|
|
31
|
+
} | {
|
|
32
|
+
action: false;
|
|
33
|
+
formData: FormData;
|
|
34
|
+
}>;
|
|
32
35
|
}) & {
|
|
33
36
|
pathname: string;
|
|
34
37
|
req: Request;
|
|
35
38
|
etags?: Etags;
|
|
36
39
|
}, utils: {
|
|
37
40
|
renderRsc: Unstable_RenderRsc;
|
|
38
|
-
parseRsc: Unstable_ParseRsc;
|
|
39
41
|
renderHtml: Unstable_RenderHtml;
|
|
40
42
|
loadBuildMetadata: (key: string) => Promise<string | undefined>;
|
|
41
43
|
}) => Promise<ReadableStream | Response | 'fallback' | null | undefined>;
|
|
42
44
|
export type Unstable_HandleBuild = (utils: {
|
|
43
45
|
renderRsc: Unstable_RenderRsc;
|
|
44
|
-
parseRsc: Unstable_ParseRsc;
|
|
45
46
|
renderHtml: Unstable_RenderHtml;
|
|
46
47
|
rscPath2pathname: (rscPath: string) => string;
|
|
47
48
|
saveBuildMetadata: (key: string, value: string) => Promise<void>;
|
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';\nimport type { Etags } from './utils/etags.js';\n\ntype Elements = Record<string, unknown>;\n\nexport type Unstable_RenderRsc = (\n elements: Elements,\n options?: {\n value?: unknown;\n etags?: Etags;\n unstable_clientModuleCallback?: (ids: string[]) => void;\n },\n) => Promise<ReadableStream>;\n\nexport type
|
|
1
|
+
{"version":3,"sources":["../../src/lib/types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type { Config } from '../config.js';\nimport type { Etags } from './utils/etags.js';\n\ntype Elements = Record<string, unknown>;\n\nexport type Unstable_RenderRsc = (\n elements: Elements,\n options?: {\n value?: unknown;\n etags?: Etags;\n unstable_clientModuleCallback?: (ids: string[]) => void;\n },\n) => Promise<ReadableStream>;\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: 'rsc'; rscPath: string; rscParams: unknown }\n | {\n type: 'call';\n fn: (...args: unknown[]) => Promise<unknown>;\n args: unknown[];\n }\n | {\n type: 'http';\n tryAction?: () => Promise<\n | { action: true; formState: unknown }\n | { action: false; formData: FormData }\n >;\n }\n ) & {\n pathname: string;\n req: Request;\n etags?: Etags;\n },\n utils: {\n renderRsc: Unstable_RenderRsc;\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 renderHtml: Unstable_RenderHtml;\n rscPath2pathname: (rscPath: string) => string;\n saveBuildMetadata: (key: string, value: string) => Promise<void>;\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, unknown>>) => 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":"AAqGA,WAa8E"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
// This file should not include Node specific code.
|
|
2
|
+
// TODO: this WS debug channel keeps dev payloads lean by offloading React's
|
|
3
|
+
// Server Components debug info (component stacks, timing, console, async
|
|
4
|
+
// metadata) out of the main Flight stream. Our transport is bespoke: paired
|
|
5
|
+
// HMR events here plus the debug-id header hack in rsc-devtools.ts. Waku is
|
|
6
|
+
// cited as prior art for a shared @vitejs/plugin-rsc debug-channel example
|
|
7
|
+
// (https://github.com/vitejs/vite-plugin-react/issues/1306). Once that lands,
|
|
8
|
+
// consider adopting it so we can delete our own transport and rsc-devtools.ts.
|
|
2
9
|
import { base64ToBytes, bytesToBase64 } from './base64-web.js';
|
|
3
10
|
export const DEBUG_ID_HEADER = 'X-Waku-Debug-Id';
|
|
4
11
|
export const DEBUG_CMD_EVENT = 'waku:debug-cmd';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils/react-debug-channel.ts"],"sourcesContent":["// This file should not include Node specific code.\n\nimport { base64ToBytes, bytesToBase64 } from './base64-web.js';\n\nexport const DEBUG_ID_HEADER = 'X-Waku-Debug-Id';\nexport const DEBUG_CMD_EVENT = 'waku:debug-cmd';\nexport const DEBUG_DATA_EVENT = 'waku:debug-data';\n\ntype DebugCmdEventReadyPayload = {\n i: string; // debugId\n};\ntype DebugCmdEventChunkPayload = {\n i: string; // debugId\n b: string; // base64 encoded chunk\n};\ntype DebugCmdEventDonePayload = {\n i: string; // debugId\n d: true; // done flag\n};\ntype DebugDataEventChunkPayload = {\n i: string; // debugId\n b: string; // base64 encoded chunk\n};\ntype DebugDataEventDonePayload = {\n i: string; // debugId\n d: true; // done flag\n};\nexport type DebugEventPayload =\n | DebugCmdEventReadyPayload\n | DebugCmdEventChunkPayload\n | DebugCmdEventDonePayload\n | DebugDataEventChunkPayload\n | DebugDataEventDonePayload;\n\nexport function assertIsDebugEventPayload(\n payload: unknown,\n): asserts payload is DebugEventPayload {\n if (\n !payload ||\n typeof payload !== 'object' ||\n typeof (payload as { i?: unknown }).i !== 'string' ||\n ('b' in payload && typeof (payload as { b?: unknown }).b !== 'string') ||\n ('d' in payload && (payload as { d?: unknown }).d !== true)\n ) {\n throw new Error('Invalid debug event payload');\n }\n}\n\nconst createWsDebugChannel = (debugId: string) => {\n const hot = import.meta.hot!;\n let closed = false;\n let onDataEvent: ((payload: unknown) => void) | undefined;\n\n const cleanup = (notify?: boolean) => {\n if (closed) {\n return;\n }\n closed = true;\n if (onDataEvent) {\n hot.off(DEBUG_DATA_EVENT, onDataEvent);\n }\n if (notify) {\n hot.send(DEBUG_CMD_EVENT, {\n i: debugId,\n d: true,\n } satisfies DebugEventPayload);\n }\n };\n\n const readable = new ReadableStream<Uint8Array>({\n start(controller) {\n onDataEvent = (payload: unknown) => {\n assertIsDebugEventPayload(payload);\n if (closed || payload.i !== debugId) {\n return;\n }\n if ('b' in payload) {\n // chunk\n controller.enqueue(base64ToBytes(payload.b));\n }\n if ('d' in payload) {\n // done\n cleanup();\n controller.close();\n }\n };\n hot.on(DEBUG_DATA_EVENT, onDataEvent);\n hot.send(DEBUG_CMD_EVENT, { i: debugId } satisfies DebugEventPayload);\n },\n cancel() {\n cleanup(true);\n },\n });\n\n const writable = new WritableStream<Uint8Array>({\n write(chunk) {\n if (closed) {\n throw new Error('Channel is closed');\n }\n hot.send(DEBUG_CMD_EVENT, {\n i: debugId,\n b: bytesToBase64(chunk),\n } satisfies DebugEventPayload);\n },\n close() {\n cleanup(true);\n },\n abort() {\n cleanup(true);\n },\n });\n\n return { readable, writable };\n};\n\nexport const setupDebugChannel = (\n baseFetchFn: typeof fetch,\n prefetched: boolean,\n debugId?: string,\n) => {\n if (prefetched) {\n if (debugId) {\n const debugChannel = createWsDebugChannel(debugId);\n return { debugChannel };\n }\n return {};\n }\n\n const newDebugId = crypto.randomUUID();\n const debugChannel = createWsDebugChannel(newDebugId);\n const fetchFn = ((input: RequestInfo | URL, init?: RequestInit) => {\n const headers = new Headers(init?.headers);\n headers.set(DEBUG_ID_HEADER, newDebugId);\n return baseFetchFn(input, {\n ...init,\n headers,\n });\n }) as typeof fetch;\n return { fetchFn, debugChannel };\n};\n"],"names":["base64ToBytes","bytesToBase64","DEBUG_ID_HEADER","DEBUG_CMD_EVENT","DEBUG_DATA_EVENT","assertIsDebugEventPayload","payload","i","b","d","Error","createWsDebugChannel","debugId","hot","closed","onDataEvent","cleanup","notify","off","send","readable","ReadableStream","start","controller","enqueue","close","on","cancel","writable","WritableStream","write","chunk","abort","setupDebugChannel","baseFetchFn","prefetched","debugChannel","newDebugId","crypto","randomUUID","fetchFn","input","init","headers","Headers","set"],"mappings":"AAAA,mDAAmD;AAEnD,SAASA,aAAa,EAAEC,aAAa,QAAQ,kBAAkB;AAE/D,OAAO,MAAMC,kBAAkB,kBAAkB;AACjD,OAAO,MAAMC,kBAAkB,iBAAiB;AAChD,OAAO,MAAMC,mBAAmB,kBAAkB;AA4BlD,OAAO,SAASC,0BACdC,OAAgB;IAEhB,IACE,CAACA,WACD,OAAOA,YAAY,YACnB,OAAO,AAACA,QAA4BC,CAAC,KAAK,YACzC,OAAOD,WAAW,OAAO,AAACA,QAA4BE,CAAC,KAAK,YAC5D,OAAOF,WAAW,AAACA,QAA4BG,CAAC,KAAK,MACtD;QACA,MAAM,IAAIC,MAAM;IAClB;AACF;AAEA,MAAMC,uBAAuB,CAACC;IAC5B,MAAMC,MAAM,YAAYA,GAAG;IAC3B,IAAIC,SAAS;IACb,IAAIC;IAEJ,MAAMC,UAAU,CAACC;QACf,IAAIH,QAAQ;YACV;QACF;QACAA,SAAS;QACT,IAAIC,aAAa;YACfF,IAAIK,GAAG,CAACd,kBAAkBW;QAC5B;QACA,IAAIE,QAAQ;YACVJ,IAAIM,IAAI,CAAChB,iBAAiB;gBACxBI,GAAGK;gBACHH,GAAG;YACL;QACF;IACF;IAEA,MAAMW,WAAW,IAAIC,eAA2B;QAC9CC,OAAMC,UAAU;YACdR,cAAc,CAACT;gBACbD,0BAA0BC;gBAC1B,IAAIQ,UAAUR,QAAQC,CAAC,KAAKK,SAAS;oBACnC;gBACF;gBACA,IAAI,OAAON,SAAS;oBAClB,QAAQ;oBACRiB,WAAWC,OAAO,CAACxB,cAAcM,QAAQE,CAAC;gBAC5C;gBACA,IAAI,OAAOF,SAAS;oBAClB,OAAO;oBACPU;oBACAO,WAAWE,KAAK;gBAClB;YACF;YACAZ,IAAIa,EAAE,CAACtB,kBAAkBW;YACzBF,IAAIM,IAAI,CAAChB,iBAAiB;gBAAEI,GAAGK;YAAQ;QACzC;QACAe;YACEX,QAAQ;QACV;IACF;IAEA,MAAMY,WAAW,IAAIC,eAA2B;QAC9CC,OAAMC,KAAK;YACT,IAAIjB,QAAQ;gBACV,MAAM,IAAIJ,MAAM;YAClB;YACAG,IAAIM,IAAI,CAAChB,iBAAiB;gBACxBI,GAAGK;gBACHJ,GAAGP,cAAc8B;YACnB;QACF;QACAN;YACET,QAAQ;QACV;QACAgB;YACEhB,QAAQ;QACV;IACF;IAEA,OAAO;QAAEI;QAAUQ;IAAS;AAC9B;AAEA,OAAO,MAAMK,oBAAoB,CAC/BC,aACAC,YACAvB;IAEA,IAAIuB,YAAY;QACd,IAAIvB,SAAS;YACX,MAAMwB,eAAezB,qBAAqBC;YAC1C,OAAO;gBAAEwB;YAAa;QACxB;QACA,OAAO,CAAC;IACV;IAEA,MAAMC,aAAaC,OAAOC,UAAU;IACpC,MAAMH,eAAezB,qBAAqB0B;IAC1C,MAAMG,UAAW,CAACC,OAA0BC;QAC1C,MAAMC,UAAU,IAAIC,QAAQF,MAAMC;QAClCA,QAAQE,GAAG,CAAC3C,iBAAiBmC;QAC7B,OAAOH,YAAYO,OAAO;YACxB,GAAGC,IAAI;YACPC;QACF;IACF;IACA,OAAO;QAAEH;QAASJ;IAAa;AACjC,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/react-debug-channel.ts"],"sourcesContent":["// This file should not include Node specific code.\n\n// TODO: this WS debug channel keeps dev payloads lean by offloading React's\n// Server Components debug info (component stacks, timing, console, async\n// metadata) out of the main Flight stream. Our transport is bespoke: paired\n// HMR events here plus the debug-id header hack in rsc-devtools.ts. Waku is\n// cited as prior art for a shared @vitejs/plugin-rsc debug-channel example\n// (https://github.com/vitejs/vite-plugin-react/issues/1306). Once that lands,\n// consider adopting it so we can delete our own transport and rsc-devtools.ts.\n\nimport { base64ToBytes, bytesToBase64 } from './base64-web.js';\n\nexport const DEBUG_ID_HEADER = 'X-Waku-Debug-Id';\nexport const DEBUG_CMD_EVENT = 'waku:debug-cmd';\nexport const DEBUG_DATA_EVENT = 'waku:debug-data';\n\ntype DebugCmdEventReadyPayload = {\n i: string; // debugId\n};\ntype DebugCmdEventChunkPayload = {\n i: string; // debugId\n b: string; // base64 encoded chunk\n};\ntype DebugCmdEventDonePayload = {\n i: string; // debugId\n d: true; // done flag\n};\ntype DebugDataEventChunkPayload = {\n i: string; // debugId\n b: string; // base64 encoded chunk\n};\ntype DebugDataEventDonePayload = {\n i: string; // debugId\n d: true; // done flag\n};\nexport type DebugEventPayload =\n | DebugCmdEventReadyPayload\n | DebugCmdEventChunkPayload\n | DebugCmdEventDonePayload\n | DebugDataEventChunkPayload\n | DebugDataEventDonePayload;\n\nexport function assertIsDebugEventPayload(\n payload: unknown,\n): asserts payload is DebugEventPayload {\n if (\n !payload ||\n typeof payload !== 'object' ||\n typeof (payload as { i?: unknown }).i !== 'string' ||\n ('b' in payload && typeof (payload as { b?: unknown }).b !== 'string') ||\n ('d' in payload && (payload as { d?: unknown }).d !== true)\n ) {\n throw new Error('Invalid debug event payload');\n }\n}\n\nconst createWsDebugChannel = (debugId: string) => {\n const hot = import.meta.hot!;\n let closed = false;\n let onDataEvent: ((payload: unknown) => void) | undefined;\n\n const cleanup = (notify?: boolean) => {\n if (closed) {\n return;\n }\n closed = true;\n if (onDataEvent) {\n hot.off(DEBUG_DATA_EVENT, onDataEvent);\n }\n if (notify) {\n hot.send(DEBUG_CMD_EVENT, {\n i: debugId,\n d: true,\n } satisfies DebugEventPayload);\n }\n };\n\n const readable = new ReadableStream<Uint8Array>({\n start(controller) {\n onDataEvent = (payload: unknown) => {\n assertIsDebugEventPayload(payload);\n if (closed || payload.i !== debugId) {\n return;\n }\n if ('b' in payload) {\n // chunk\n controller.enqueue(base64ToBytes(payload.b));\n }\n if ('d' in payload) {\n // done\n cleanup();\n controller.close();\n }\n };\n hot.on(DEBUG_DATA_EVENT, onDataEvent);\n hot.send(DEBUG_CMD_EVENT, { i: debugId } satisfies DebugEventPayload);\n },\n cancel() {\n cleanup(true);\n },\n });\n\n const writable = new WritableStream<Uint8Array>({\n write(chunk) {\n if (closed) {\n throw new Error('Channel is closed');\n }\n hot.send(DEBUG_CMD_EVENT, {\n i: debugId,\n b: bytesToBase64(chunk),\n } satisfies DebugEventPayload);\n },\n close() {\n cleanup(true);\n },\n abort() {\n cleanup(true);\n },\n });\n\n return { readable, writable };\n};\n\nexport const setupDebugChannel = (\n baseFetchFn: typeof fetch,\n prefetched: boolean,\n debugId?: string,\n) => {\n if (prefetched) {\n if (debugId) {\n const debugChannel = createWsDebugChannel(debugId);\n return { debugChannel };\n }\n return {};\n }\n\n const newDebugId = crypto.randomUUID();\n const debugChannel = createWsDebugChannel(newDebugId);\n const fetchFn = ((input: RequestInfo | URL, init?: RequestInit) => {\n const headers = new Headers(init?.headers);\n headers.set(DEBUG_ID_HEADER, newDebugId);\n return baseFetchFn(input, {\n ...init,\n headers,\n });\n }) as typeof fetch;\n return { fetchFn, debugChannel };\n};\n"],"names":["base64ToBytes","bytesToBase64","DEBUG_ID_HEADER","DEBUG_CMD_EVENT","DEBUG_DATA_EVENT","assertIsDebugEventPayload","payload","i","b","d","Error","createWsDebugChannel","debugId","hot","closed","onDataEvent","cleanup","notify","off","send","readable","ReadableStream","start","controller","enqueue","close","on","cancel","writable","WritableStream","write","chunk","abort","setupDebugChannel","baseFetchFn","prefetched","debugChannel","newDebugId","crypto","randomUUID","fetchFn","input","init","headers","Headers","set"],"mappings":"AAAA,mDAAmD;AAEnD,4EAA4E;AAC5E,yEAAyE;AACzE,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,+EAA+E;AAE/E,SAASA,aAAa,EAAEC,aAAa,QAAQ,kBAAkB;AAE/D,OAAO,MAAMC,kBAAkB,kBAAkB;AACjD,OAAO,MAAMC,kBAAkB,iBAAiB;AAChD,OAAO,MAAMC,mBAAmB,kBAAkB;AA4BlD,OAAO,SAASC,0BACdC,OAAgB;IAEhB,IACE,CAACA,WACD,OAAOA,YAAY,YACnB,OAAO,AAACA,QAA4BC,CAAC,KAAK,YACzC,OAAOD,WAAW,OAAO,AAACA,QAA4BE,CAAC,KAAK,YAC5D,OAAOF,WAAW,AAACA,QAA4BG,CAAC,KAAK,MACtD;QACA,MAAM,IAAIC,MAAM;IAClB;AACF;AAEA,MAAMC,uBAAuB,CAACC;IAC5B,MAAMC,MAAM,YAAYA,GAAG;IAC3B,IAAIC,SAAS;IACb,IAAIC;IAEJ,MAAMC,UAAU,CAACC;QACf,IAAIH,QAAQ;YACV;QACF;QACAA,SAAS;QACT,IAAIC,aAAa;YACfF,IAAIK,GAAG,CAACd,kBAAkBW;QAC5B;QACA,IAAIE,QAAQ;YACVJ,IAAIM,IAAI,CAAChB,iBAAiB;gBACxBI,GAAGK;gBACHH,GAAG;YACL;QACF;IACF;IAEA,MAAMW,WAAW,IAAIC,eAA2B;QAC9CC,OAAMC,UAAU;YACdR,cAAc,CAACT;gBACbD,0BAA0BC;gBAC1B,IAAIQ,UAAUR,QAAQC,CAAC,KAAKK,SAAS;oBACnC;gBACF;gBACA,IAAI,OAAON,SAAS;oBAClB,QAAQ;oBACRiB,WAAWC,OAAO,CAACxB,cAAcM,QAAQE,CAAC;gBAC5C;gBACA,IAAI,OAAOF,SAAS;oBAClB,OAAO;oBACPU;oBACAO,WAAWE,KAAK;gBAClB;YACF;YACAZ,IAAIa,EAAE,CAACtB,kBAAkBW;YACzBF,IAAIM,IAAI,CAAChB,iBAAiB;gBAAEI,GAAGK;YAAQ;QACzC;QACAe;YACEX,QAAQ;QACV;IACF;IAEA,MAAMY,WAAW,IAAIC,eAA2B;QAC9CC,OAAMC,KAAK;YACT,IAAIjB,QAAQ;gBACV,MAAM,IAAIJ,MAAM;YAClB;YACAG,IAAIM,IAAI,CAAChB,iBAAiB;gBACxBI,GAAGK;gBACHJ,GAAGP,cAAc8B;YACnB;QACF;QACAN;YACET,QAAQ;QACV;QACAgB;YACEhB,QAAQ;QACV;IACF;IAEA,OAAO;QAAEI;QAAUQ;IAAS;AAC9B;AAEA,OAAO,MAAMK,oBAAoB,CAC/BC,aACAC,YACAvB;IAEA,IAAIuB,YAAY;QACd,IAAIvB,SAAS;YACX,MAAMwB,eAAezB,qBAAqBC;YAC1C,OAAO;gBAAEwB;YAAa;QACxB;QACA,OAAO,CAAC;IACV;IAEA,MAAMC,aAAaC,OAAOC,UAAU;IACpC,MAAMH,eAAezB,qBAAqB0B;IAC1C,MAAMG,UAAW,CAACC,OAA0BC;QAC1C,MAAMC,UAAU,IAAIC,QAAQF,MAAMC;QAClCA,QAAQE,GAAG,CAAC3C,iBAAiBmC;QAC7B,OAAOH,YAAYO,OAAO;YACxB,GAAGC,IAAI;YACPC;QACF;IACF;IACA,OAAO;QAAEH;QAASJ;IAAa;AACjC,EAAE"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function createRenderUtils(temporaryReferences: unknown, renderToReadableStream: (data: unknown, options?: object, extraOptions?: object) => ReadableStream,
|
|
1
|
+
import type { Unstable_RenderHtml, Unstable_RenderRsc } from '../types.js';
|
|
2
|
+
export declare function createRenderUtils(temporaryReferences: unknown, renderToReadableStream: (data: unknown, options?: object, extraOptions?: object) => ReadableStream, loadSsrEntryModule: () => Promise<typeof import('../vite-entries/entry.ssr.js')>, buildId: string, debugChannel?: {
|
|
3
3
|
readable?: ReadableStream;
|
|
4
4
|
writable?: WritableStream;
|
|
5
5
|
}, debugId?: string): {
|
|
6
6
|
renderRsc: Unstable_RenderRsc;
|
|
7
|
-
parseRsc: Unstable_ParseRsc;
|
|
8
7
|
renderHtml: Unstable_RenderHtml;
|
|
9
8
|
};
|
package/dist/lib/utils/render.js
CHANGED
|
@@ -7,7 +7,7 @@ const validateRscElementIds = (elements)=>{
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
|
-
export function createRenderUtils(temporaryReferences, renderToReadableStream,
|
|
10
|
+
export function createRenderUtils(temporaryReferences, renderToReadableStream, loadSsrEntryModule, buildId, debugChannel, debugId) {
|
|
11
11
|
const onError = (e)=>{
|
|
12
12
|
if (e && typeof e === 'object' && 'digest' in e && typeof e.digest === 'string') {
|
|
13
13
|
return e.digest;
|
|
@@ -41,9 +41,6 @@ export function createRenderUtils(temporaryReferences, renderToReadableStream, c
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
},
|
|
44
|
-
async parseRsc (stream) {
|
|
45
|
-
return createFromReadableStream(stream, {});
|
|
46
|
-
},
|
|
47
44
|
async renderHtml (elementsStream, html, options) {
|
|
48
45
|
const { INTERNAL_renderHtmlStream: renderHtmlStream } = await loadSsrEntryModule();
|
|
49
46
|
const rscHtmlStream = renderToReadableStream(html, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils/render.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/render.ts"],"sourcesContent":["import type { Unstable_RenderHtml, Unstable_RenderRsc } from '../types.js';\nimport { ETAG_ID_PREFIX } from './etags.js';\nimport { sanitizeLog } from './log.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 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 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:', sanitizeLog(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 if (options?.etags) {\n for (const [slotId, etag] of Object.entries(options.etags)) {\n data[ETAG_ID_PREFIX + slotId] = etag;\n }\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 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":["ETAG_ID_PREFIX","sanitizeLog","validateRscElementIds","elements","id","Object","keys","startsWith","Error","createRenderUtils","temporaryReferences","renderToReadableStream","loadSsrEntryModule","buildId","debugChannel","debugId","onError","e","digest","console","error","renderRsc","options","data","_buildId","_value","value","etags","slotId","etag","entries","onClientReference","metadata","unstable_clientModuleCallback","deps","js","renderHtml","elementsStream","html","INTERNAL_renderHtmlStream","renderHtmlStream","rscHtmlStream","htmlResult","rscPath","formState","nonce","extraScriptContent","unstable_extraScriptContent","Response","stream","status","headers"],"mappings":"AACA,SAASA,cAAc,QAAQ,aAAa;AAC5C,SAASC,WAAW,QAAQ,WAAW;AAEvC,MAAMC,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,kBAEC,EACDC,OAAe,EACfC,YAAuE,EACvEC,OAAgB;IAKhB,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,2BAA2BnB,YAAYgB;IACvD;IAEA,OAAO;QACL,MAAMI,WAAUlB,QAAQ,EAAEmB,OAAO;YAC/BpB,sBAAsBC;YACtB,MAAMoB,OAAgCV,UAClC;gBAAE,GAAGV,QAAQ;gBAAEqB,UAAUX;YAAQ,IACjC;gBAAE,GAAGV,QAAQ;YAAC;YAClB,IAAImB,WAAW,WAAWA,SAAS;gBACjCC,KAAKE,MAAM,GAAGH,QAAQI,KAAK;YAC7B;YACA,IAAIJ,SAASK,OAAO;gBAClB,KAAK,MAAM,CAACC,QAAQC,KAAK,IAAIxB,OAAOyB,OAAO,CAACR,QAAQK,KAAK,EAAG;oBAC1DJ,IAAI,CAACvB,iBAAiB4B,OAAO,GAAGC;gBAClC;YACF;YACA,OAAOlB,uBACLY,MACA;gBACEb;gBACAM;gBACAF;YACF,GACA;gBACEiB,mBAAkBC,QAIjB;oBACCV,SAASW,gCAAgCD,SAASE,IAAI,CAACC,EAAE;gBAC3D;YACF;QAEJ;QACA,MAAMC,YAAWC,cAAc,EAAEC,IAAI,EAAEhB,OAAO;YAC5C,MAAM,EAAEiB,2BAA2BC,gBAAgB,EAAE,GACnD,MAAM5B;YAER,MAAM6B,gBAAgB9B,uBAAuB2B,MAAM;gBACjDtB;YACF;YACA,MAAM0B,aAAa,MAAMF,iBAAiBH,gBAAgBI,eAAe;gBACvEE,SAASrB,QAAQqB,OAAO;gBACxBC,WAAWtB,QAAQsB,SAAS;gBAC5BC,OAAOvB,QAAQuB,KAAK;gBACpBC,oBAAoBxB,QAAQyB,2BAA2B;gBACvDhC;YACF;YACA,OAAO,IAAIiC,SAASN,WAAWO,MAAM,EAAE;gBACrCC,QAAQR,WAAWQ,MAAM,IAAI5B,QAAQ4B,MAAM,IAAI;gBAC/CC,SAAS;oBAAE,gBAAgB;gBAA2B;YACxD;QACF;IACF;AACF"}
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import type { ReactFormState } from 'react-dom/client';
|
|
2
2
|
import type { Config } from '../../config.js';
|
|
3
3
|
export declare function getInput(req: Request, config: Omit<Required<Config>, 'vite'>, temporaryReferences: unknown, decodeReply: (body: string | FormData, options?: object) => Promise<unknown[]>, decodeAction: (body: FormData) => Promise<() => Promise<void>> | null, decodeFormState: (actionResult: unknown, body: FormData) => Promise<ReactFormState | undefined>, loadServerAction: (id: string) => Promise<unknown>): Promise<({
|
|
4
|
-
type: "
|
|
4
|
+
type: "rsc";
|
|
5
5
|
rscPath: string;
|
|
6
6
|
rscParams: unknown;
|
|
7
7
|
} | {
|
|
8
|
-
type: "
|
|
8
|
+
type: "call";
|
|
9
9
|
fn: (...args: unknown[]) => Promise<unknown>;
|
|
10
10
|
args: unknown[];
|
|
11
11
|
} | {
|
|
12
|
-
type: "
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
type: "http";
|
|
13
|
+
tryAction?: () => Promise<{
|
|
14
|
+
action: true;
|
|
15
|
+
formState: unknown;
|
|
16
|
+
} | {
|
|
17
|
+
action: false;
|
|
18
|
+
formData: FormData;
|
|
19
|
+
}>;
|
|
16
20
|
}) & {
|
|
17
21
|
pathname: string;
|
|
18
22
|
req: Request;
|
|
@@ -21,7 +21,7 @@ export async function getInput(req, config, temporaryReferences, decodeReply, de
|
|
|
21
21
|
});
|
|
22
22
|
const action = await loadServerAction(actionId);
|
|
23
23
|
input = {
|
|
24
|
-
type: '
|
|
24
|
+
type: 'call',
|
|
25
25
|
fn: action,
|
|
26
26
|
args,
|
|
27
27
|
pathname,
|
|
@@ -39,7 +39,7 @@ export async function getInput(req, config, temporaryReferences, decodeReply, de
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
input = {
|
|
42
|
-
type: '
|
|
42
|
+
type: 'rsc',
|
|
43
43
|
rscPath,
|
|
44
44
|
rscParams,
|
|
45
45
|
pathname,
|
|
@@ -50,22 +50,27 @@ export async function getInput(req, config, temporaryReferences, decodeReply, de
|
|
|
50
50
|
} else if (req.method === 'POST') {
|
|
51
51
|
const contentType = req.headers.get('content-type');
|
|
52
52
|
if (typeof contentType === 'string' && contentType.startsWith('multipart/form-data')) {
|
|
53
|
-
// server action
|
|
54
|
-
|
|
53
|
+
// possibly a no-js server action submission (progressive enhancement)
|
|
54
|
+
let parsing;
|
|
55
55
|
input = {
|
|
56
|
-
type: '
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
56
|
+
type: 'http',
|
|
57
|
+
tryAction: ()=>parsing ??= (async ()=>{
|
|
58
|
+
const formData = await getActionBody(req);
|
|
59
|
+
const decodedAction = await decodeAction(formData);
|
|
60
|
+
if (typeof decodedAction !== 'function') {
|
|
61
|
+
return {
|
|
62
|
+
action: false,
|
|
63
|
+
formData
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
validateServerActionRequest(req);
|
|
67
|
+
const result = await decodedAction();
|
|
68
|
+
const formState = await decodeFormState(result, formData);
|
|
69
|
+
return {
|
|
70
|
+
action: true,
|
|
71
|
+
formState
|
|
72
|
+
};
|
|
73
|
+
})(),
|
|
69
74
|
pathname,
|
|
70
75
|
req,
|
|
71
76
|
etags
|
|
@@ -73,7 +78,7 @@ export async function getInput(req, config, temporaryReferences, decodeReply, de
|
|
|
73
78
|
} else {
|
|
74
79
|
// POST API request
|
|
75
80
|
input = {
|
|
76
|
-
type: '
|
|
81
|
+
type: 'http',
|
|
77
82
|
pathname,
|
|
78
83
|
req,
|
|
79
84
|
etags
|
|
@@ -82,7 +87,7 @@ export async function getInput(req, config, temporaryReferences, decodeReply, de
|
|
|
82
87
|
} else {
|
|
83
88
|
// SSR
|
|
84
89
|
input = {
|
|
85
|
-
type: '
|
|
90
|
+
type: 'http',
|
|
86
91
|
pathname,
|
|
87
92
|
req,
|
|
88
93
|
etags
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils/request.ts"],"sourcesContent":["import type { ReactFormState } from 'react-dom/client';\nimport type { Config } from '../../config.js';\nimport type { Unstable_HandleRequest as HandleRequest } from '../types.js';\nimport { decodeFuncId, decodeRscPath } from '../utils/rsc-path.js';\nimport { createCustomError } from './custom-errors.js';\nimport { ETAGS_HEADER, parseClientEtags } from './etags.js';\nimport { removeBase } from './path.js';\n\ntype HandleRequestInput = Parameters<HandleRequest>[0];\n\nexport async function getInput(\n req: Request,\n config: Omit<Required<Config>, 'vite'>,\n temporaryReferences: unknown,\n decodeReply: (\n body: string | FormData,\n options?: object,\n ) => Promise<unknown[]>,\n decodeAction: (body: FormData) => Promise<() => Promise<void>> | null,\n decodeFormState: (\n actionResult: unknown,\n body: FormData,\n ) => Promise<ReactFormState | undefined>,\n loadServerAction: (id: string) => Promise<unknown>,\n) {\n const url = new URL(req.url);\n const pathname = removeBase(url.pathname, config.basePath);\n const rscPathPrefix = '/' + config.rscBase + '/';\n const etags = parseClientEtags(req.headers.get(ETAGS_HEADER));\n let rscPath: string | undefined;\n let input: HandleRequestInput;\n if (pathname.startsWith(rscPathPrefix)) {\n rscPath = decodeRscPath(pathname.slice(rscPathPrefix.length));\n // server action: js\n const actionId = decodeFuncId(rscPath);\n if (actionId) {\n validateServerActionRequest(req);\n const body = await getActionBody(req);\n const args = await decodeReply(body, { temporaryReferences });\n const action = await loadServerAction(actionId);\n input = {\n type: '
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils/request.ts"],"sourcesContent":["import type { ReactFormState } from 'react-dom/client';\nimport type { Config } from '../../config.js';\nimport type { Unstable_HandleRequest as HandleRequest } from '../types.js';\nimport { decodeFuncId, decodeRscPath } from '../utils/rsc-path.js';\nimport { createCustomError } from './custom-errors.js';\nimport { ETAGS_HEADER, parseClientEtags } from './etags.js';\nimport { removeBase } from './path.js';\n\ntype HandleRequestInput = Parameters<HandleRequest>[0];\n\nexport async function getInput(\n req: Request,\n config: Omit<Required<Config>, 'vite'>,\n temporaryReferences: unknown,\n decodeReply: (\n body: string | FormData,\n options?: object,\n ) => Promise<unknown[]>,\n decodeAction: (body: FormData) => Promise<() => Promise<void>> | null,\n decodeFormState: (\n actionResult: unknown,\n body: FormData,\n ) => Promise<ReactFormState | undefined>,\n loadServerAction: (id: string) => Promise<unknown>,\n) {\n const url = new URL(req.url);\n const pathname = removeBase(url.pathname, config.basePath);\n const rscPathPrefix = '/' + config.rscBase + '/';\n const etags = parseClientEtags(req.headers.get(ETAGS_HEADER));\n let rscPath: string | undefined;\n let input: HandleRequestInput;\n if (pathname.startsWith(rscPathPrefix)) {\n rscPath = decodeRscPath(pathname.slice(rscPathPrefix.length));\n // server action: js\n const actionId = decodeFuncId(rscPath);\n if (actionId) {\n validateServerActionRequest(req);\n const body = await getActionBody(req);\n const args = await decodeReply(body, { temporaryReferences });\n const action = await loadServerAction(actionId);\n input = {\n type: 'call',\n fn: action as never,\n args,\n pathname,\n req,\n etags,\n };\n } else {\n // client RSC request\n let rscParams: unknown = url.searchParams;\n if (req.body) {\n validateServerActionRequest(req);\n const body = await getActionBody(req);\n rscParams = await decodeReply(body, {\n temporaryReferences,\n });\n }\n input = {\n type: 'rsc',\n rscPath,\n rscParams,\n pathname,\n req,\n etags,\n };\n }\n } else if (req.method === 'POST') {\n const contentType = req.headers.get('content-type');\n if (\n typeof contentType === 'string' &&\n contentType.startsWith('multipart/form-data')\n ) {\n // possibly a no-js server action submission (progressive enhancement)\n let parsing:\n | Promise<\n | { action: true; formState: unknown }\n | { action: false; formData: FormData }\n >\n | undefined;\n input = {\n type: 'http',\n tryAction: () =>\n (parsing ??= (async () => {\n const formData = (await getActionBody(req)) as FormData;\n const decodedAction = await decodeAction(formData);\n if (typeof decodedAction !== 'function') {\n return { action: false as const, formData };\n }\n validateServerActionRequest(req);\n const result = await decodedAction();\n const formState = await decodeFormState(result, formData);\n return { action: true as const, formState };\n })()),\n pathname,\n req,\n etags,\n };\n } else {\n // POST API request\n input = {\n type: 'http',\n pathname,\n req,\n etags,\n };\n }\n } else {\n // SSR\n input = {\n type: 'http',\n pathname,\n req,\n etags,\n };\n }\n return input;\n}\n\nfunction validateServerActionRequest(req: Request) {\n if (req.method !== 'POST') {\n throw createCustomError('Method Not Allowed', { status: 405 });\n }\n const origin = req.headers.get('origin');\n if (origin) {\n if (origin === 'null') {\n throw createCustomError('Forbidden', { status: 403 });\n }\n const requestOrigin = new URL(req.url).origin;\n let originUrl: URL;\n try {\n originUrl = new URL(origin);\n } catch {\n throw createCustomError('Forbidden', { status: 403 });\n }\n if (originUrl.origin !== requestOrigin) {\n throw createCustomError('Forbidden', { status: 403 });\n }\n } else if (req.headers.get('sec-fetch-site') === 'cross-site') {\n throw createCustomError('Forbidden', { status: 403 });\n }\n}\n\nasync function getActionBody(req: Request) {\n if (!req.body) {\n throw new Error('missing request body for server function');\n }\n const contentType = req.headers.get('content-type');\n if (contentType?.startsWith('multipart/form-data')) {\n return req.formData();\n } else {\n return req.text();\n }\n}\n"],"names":["decodeFuncId","decodeRscPath","createCustomError","ETAGS_HEADER","parseClientEtags","removeBase","getInput","req","config","temporaryReferences","decodeReply","decodeAction","decodeFormState","loadServerAction","url","URL","pathname","basePath","rscPathPrefix","rscBase","etags","headers","get","rscPath","input","startsWith","slice","length","actionId","validateServerActionRequest","body","getActionBody","args","action","type","fn","rscParams","searchParams","method","contentType","parsing","tryAction","formData","decodedAction","result","formState","status","origin","requestOrigin","originUrl","Error","text"],"mappings":"AAGA,SAASA,YAAY,EAAEC,aAAa,QAAQ,uBAAuB;AACnE,SAASC,iBAAiB,QAAQ,qBAAqB;AACvD,SAASC,YAAY,EAAEC,gBAAgB,QAAQ,aAAa;AAC5D,SAASC,UAAU,QAAQ,YAAY;AAIvC,OAAO,eAAeC,SACpBC,GAAY,EACZC,MAAsC,EACtCC,mBAA4B,EAC5BC,WAGuB,EACvBC,YAAqE,EACrEC,eAGwC,EACxCC,gBAAkD;IAElD,MAAMC,MAAM,IAAIC,IAAIR,IAAIO,GAAG;IAC3B,MAAME,WAAWX,WAAWS,IAAIE,QAAQ,EAAER,OAAOS,QAAQ;IACzD,MAAMC,gBAAgB,MAAMV,OAAOW,OAAO,GAAG;IAC7C,MAAMC,QAAQhB,iBAAiBG,IAAIc,OAAO,CAACC,GAAG,CAACnB;IAC/C,IAAIoB;IACJ,IAAIC;IACJ,IAAIR,SAASS,UAAU,CAACP,gBAAgB;QACtCK,UAAUtB,cAAce,SAASU,KAAK,CAACR,cAAcS,MAAM;QAC3D,oBAAoB;QACpB,MAAMC,WAAW5B,aAAauB;QAC9B,IAAIK,UAAU;YACZC,4BAA4BtB;YAC5B,MAAMuB,OAAO,MAAMC,cAAcxB;YACjC,MAAMyB,OAAO,MAAMtB,YAAYoB,MAAM;gBAAErB;YAAoB;YAC3D,MAAMwB,SAAS,MAAMpB,iBAAiBe;YACtCJ,QAAQ;gBACNU,MAAM;gBACNC,IAAIF;gBACJD;gBACAhB;gBACAT;gBACAa;YACF;QACF,OAAO;YACL,qBAAqB;YACrB,IAAIgB,YAAqBtB,IAAIuB,YAAY;YACzC,IAAI9B,IAAIuB,IAAI,EAAE;gBACZD,4BAA4BtB;gBAC5B,MAAMuB,OAAO,MAAMC,cAAcxB;gBACjC6B,YAAY,MAAM1B,YAAYoB,MAAM;oBAClCrB;gBACF;YACF;YACAe,QAAQ;gBACNU,MAAM;gBACNX;gBACAa;gBACApB;gBACAT;gBACAa;YACF;QACF;IACF,OAAO,IAAIb,IAAI+B,MAAM,KAAK,QAAQ;QAChC,MAAMC,cAAchC,IAAIc,OAAO,CAACC,GAAG,CAAC;QACpC,IACE,OAAOiB,gBAAgB,YACvBA,YAAYd,UAAU,CAAC,wBACvB;YACA,sEAAsE;YACtE,IAAIe;YAMJhB,QAAQ;gBACNU,MAAM;gBACNO,WAAW,IACRD,YAAY,AAAC,CAAA;wBACZ,MAAME,WAAY,MAAMX,cAAcxB;wBACtC,MAAMoC,gBAAgB,MAAMhC,aAAa+B;wBACzC,IAAI,OAAOC,kBAAkB,YAAY;4BACvC,OAAO;gCAAEV,QAAQ;gCAAgBS;4BAAS;wBAC5C;wBACAb,4BAA4BtB;wBAC5B,MAAMqC,SAAS,MAAMD;wBACrB,MAAME,YAAY,MAAMjC,gBAAgBgC,QAAQF;wBAChD,OAAO;4BAAET,QAAQ;4BAAeY;wBAAU;oBAC5C,CAAA;gBACF7B;gBACAT;gBACAa;YACF;QACF,OAAO;YACL,mBAAmB;YACnBI,QAAQ;gBACNU,MAAM;gBACNlB;gBACAT;gBACAa;YACF;QACF;IACF,OAAO;QACL,MAAM;QACNI,QAAQ;YACNU,MAAM;YACNlB;YACAT;YACAa;QACF;IACF;IACA,OAAOI;AACT;AAEA,SAASK,4BAA4BtB,GAAY;IAC/C,IAAIA,IAAI+B,MAAM,KAAK,QAAQ;QACzB,MAAMpC,kBAAkB,sBAAsB;YAAE4C,QAAQ;QAAI;IAC9D;IACA,MAAMC,SAASxC,IAAIc,OAAO,CAACC,GAAG,CAAC;IAC/B,IAAIyB,QAAQ;QACV,IAAIA,WAAW,QAAQ;YACrB,MAAM7C,kBAAkB,aAAa;gBAAE4C,QAAQ;YAAI;QACrD;QACA,MAAME,gBAAgB,IAAIjC,IAAIR,IAAIO,GAAG,EAAEiC,MAAM;QAC7C,IAAIE;QACJ,IAAI;YACFA,YAAY,IAAIlC,IAAIgC;QACtB,EAAE,OAAM;YACN,MAAM7C,kBAAkB,aAAa;gBAAE4C,QAAQ;YAAI;QACrD;QACA,IAAIG,UAAUF,MAAM,KAAKC,eAAe;YACtC,MAAM9C,kBAAkB,aAAa;gBAAE4C,QAAQ;YAAI;QACrD;IACF,OAAO,IAAIvC,IAAIc,OAAO,CAACC,GAAG,CAAC,sBAAsB,cAAc;QAC7D,MAAMpB,kBAAkB,aAAa;YAAE4C,QAAQ;QAAI;IACrD;AACF;AAEA,eAAef,cAAcxB,GAAY;IACvC,IAAI,CAACA,IAAIuB,IAAI,EAAE;QACb,MAAM,IAAIoB,MAAM;IAClB;IACA,MAAMX,cAAchC,IAAIc,OAAO,CAACC,GAAG,CAAC;IACpC,IAAIiB,aAAad,WAAW,wBAAwB;QAClD,OAAOlB,IAAImC,QAAQ;IACrB,OAAO;QACL,OAAOnC,IAAI4C,IAAI;IACjB;AACF"}
|
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
// objects. This transform relaxes that restriction so _debugInfo is recovered
|
|
7
7
|
// from any object, which is needed for Waku's plain-object payloads to show
|
|
8
8
|
// the "Server Components" track in Chrome DevTools Performance tab.
|
|
9
|
+
//
|
|
10
|
+
// TODO(react-19.3): once React 19.3 is the minimum, revisit whether reshaping
|
|
11
|
+
// the RSC payload root into a value React's built-in recovery accepts (array,
|
|
12
|
+
// async iterable, element, or lazy — see above) lets us delete this transform.
|
|
13
|
+
// A thin wrapper like `[elements]` is unverified; confirm against React's
|
|
14
|
+
// recovery logic first. Context: https://github.com/vitejs/vite-plugin-react/pull/1304
|
|
9
15
|
const SEARCH = 'debugInfo = root._debugInfo;';
|
|
10
16
|
const REPLACE = `
|
|
11
17
|
${SEARCH}
|
|
@@ -46,7 +52,7 @@ export function patchRsdwPlugin() {
|
|
|
46
52
|
if (id === virtualId(RSDW_CLIENT_EDGE_ID)) {
|
|
47
53
|
if (this.environment.name === 'rsc') {
|
|
48
54
|
return `
|
|
49
|
-
import { createFromReadableStream as createFromReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc'))};
|
|
55
|
+
import { createFromReadableStream as createFromReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc/client'))};
|
|
50
56
|
export function createFromReadableStream(stream) {
|
|
51
57
|
return createFromReadableStreamBase(stream);
|
|
52
58
|
}
|
|
@@ -57,7 +63,7 @@ export function patchRsdwPlugin() {
|
|
|
57
63
|
if (id === virtualId(RSDW_SERVER_EDGE_ID)) {
|
|
58
64
|
if (this.environment.name === 'rsc') {
|
|
59
65
|
return `
|
|
60
|
-
import { renderToReadableStream as renderToReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc'))};
|
|
66
|
+
import { renderToReadableStream as renderToReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc/server'))};
|
|
61
67
|
export function renderToReadableStream(model, _webpackMap, options) {
|
|
62
68
|
return renderToReadableStreamBase(model, options);
|
|
63
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/vite-plugins/patch-rsdw.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\n// Waku sends RSC payloads as plain objects (Record<string, unknown>).\n// In React's flushComponentPerformance, moveDebugInfoFromChunkToInnerValue\n// uses splice(0) which empties chunk._debugInfo after resolution. React main\n// has a fallback that recovers _debugInfo from the resolved value, but only\n// for arrays, async iterables, React elements, and lazy types — not plain\n// objects. This transform relaxes that restriction so _debugInfo is recovered\n// from any object, which is needed for Waku's plain-object payloads to show\n// the \"Server Components\" track in Chrome DevTools Performance tab.\nconst SEARCH = 'debugInfo = root._debugInfo;';\nconst REPLACE = `\n${SEARCH}\nif (debugInfo && 0 === debugInfo.length && \"fulfilled\" === root.status) {\n var _resolved = typeof resolveLazy === \"function\" ? resolveLazy(root.value) : root.value;\n if (\"object\" === typeof _resolved && null !== _resolved && isArrayImpl(_resolved._debugInfo)) {\n debugInfo = _resolved._debugInfo;\n }\n}\n`;\n\nconst RSDW_CLIENT_ID = 'react-server-dom-webpack/client';\nconst RSDW_CLIENT_EDGE_ID = 'react-server-dom-webpack/client.edge';\nconst RSDW_SERVER_EDGE_ID = 'react-server-dom-webpack/server.edge';\n\nconst virtualId = (source: string) => '\\0' + source;\n\nconst isVitePluginRscImporter = (importer?: string) =>\n /(^|[/\\\\])@vitejs[/\\\\]plugin-rsc[/\\\\]/.test(importer || '');\n\nexport function patchRsdwPlugin(): Plugin {\n return {\n name: 'waku:vite-plugins:patch-rsdw',\n enforce: 'pre',\n resolveId(source, importer, _options) {\n if (source === RSDW_CLIENT_ID) {\n return virtualId(source);\n }\n if (\n (source === RSDW_CLIENT_EDGE_ID || source === RSDW_SERVER_EDGE_ID) &&\n !isVitePluginRscImporter(importer)\n ) {\n return virtualId(source);\n }\n },\n load(id) {\n if (id === virtualId(RSDW_CLIENT_ID)) {\n if (this.environment.name === 'client') {\n return `\n import * as ReactClient from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/browser'))};\n export default ReactClient;\n `;\n }\n return `export default {}`;\n }\n if (id === virtualId(RSDW_CLIENT_EDGE_ID)) {\n if (this.environment.name === 'rsc') {\n return `\n import { createFromReadableStream as createFromReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc'))};\n export function createFromReadableStream(stream) {\n return createFromReadableStreamBase(stream);\n }\n `;\n }\n return `export {}`;\n }\n if (id === virtualId(RSDW_SERVER_EDGE_ID)) {\n if (this.environment.name === 'rsc') {\n return `\n import { renderToReadableStream as renderToReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc'))};\n export function renderToReadableStream(model, _webpackMap, options) {\n return renderToReadableStreamBase(model, options);\n }\n `;\n }\n return `export {}`;\n }\n },\n transform(code, id) {\n const [file] = id.split('?');\n if (\n ![\n '/react-server-dom-webpack-client.browser.development.js',\n '/react-server-dom-webpack_client__browser.js',\n ].some((suffix) => file!.endsWith(suffix))\n ) {\n return;\n }\n const patched = code.replace(SEARCH, REPLACE);\n if (patched === code) {\n return;\n }\n return patched;\n },\n };\n}\n"],"names":["SEARCH","REPLACE","RSDW_CLIENT_ID","RSDW_CLIENT_EDGE_ID","RSDW_SERVER_EDGE_ID","virtualId","source","isVitePluginRscImporter","importer","test","patchRsdwPlugin","name","enforce","resolveId","_options","load","id","environment","JSON","stringify","resolve","transform","code","file","split","some","suffix","endsWith","patched","replace"],"mappings":"AAEA,sEAAsE;AACtE,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,oEAAoE;AACpE,MAAMA,SAAS;AACf,MAAMC,UAAU,CAAC;AACjB,EAAED,OAAO;;;;;;;AAOT,CAAC;AAED,MAAME,iBAAiB;AACvB,MAAMC,sBAAsB;AAC5B,MAAMC,sBAAsB;AAE5B,MAAMC,YAAY,CAACC,SAAmB,OAAOA;AAE7C,MAAMC,0BAA0B,CAACC,WAC/B,uCAAuCC,IAAI,CAACD,YAAY;AAE1D,OAAO,SAASE;IACd,OAAO;QACLC,MAAM;QACNC,SAAS;QACTC,WAAUP,MAAM,EAAEE,QAAQ,EAAEM,QAAQ;YAClC,IAAIR,WAAWJ,gBAAgB;gBAC7B,OAAOG,UAAUC;YACnB;YACA,IACE,AAACA,CAAAA,WAAWH,uBAAuBG,WAAWF,mBAAkB,KAChE,CAACG,wBAAwBC,WACzB;gBACA,OAAOH,UAAUC;YACnB;QACF;QACAS,MAAKC,EAAE;YACL,IAAIA,OAAOX,UAAUH,iBAAiB;gBACpC,IAAI,IAAI,CAACe,WAAW,CAACN,IAAI,KAAK,UAAU;oBACtC,OAAO,CAAC;2CACyB,EAAEO,KAAKC,SAAS,CAAC,YAAYC,OAAO,CAAC,+BAA+B;;YAEnG,CAAC;gBACL;gBACA,OAAO,CAAC,iBAAiB,CAAC;YAC5B;YACA,IAAIJ,OAAOX,UAAUF,sBAAsB;gBACzC,IAAI,IAAI,CAACc,WAAW,CAACN,IAAI,KAAK,OAAO;oBACnC,OAAO,CAAC;qFACmE,EAAEO,KAAKC,SAAS,CAAC,YAAYC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/vite-plugins/patch-rsdw.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\n// Waku sends RSC payloads as plain objects (Record<string, unknown>).\n// In React's flushComponentPerformance, moveDebugInfoFromChunkToInnerValue\n// uses splice(0) which empties chunk._debugInfo after resolution. React main\n// has a fallback that recovers _debugInfo from the resolved value, but only\n// for arrays, async iterables, React elements, and lazy types — not plain\n// objects. This transform relaxes that restriction so _debugInfo is recovered\n// from any object, which is needed for Waku's plain-object payloads to show\n// the \"Server Components\" track in Chrome DevTools Performance tab.\n//\n// TODO(react-19.3): once React 19.3 is the minimum, revisit whether reshaping\n// the RSC payload root into a value React's built-in recovery accepts (array,\n// async iterable, element, or lazy — see above) lets us delete this transform.\n// A thin wrapper like `[elements]` is unverified; confirm against React's\n// recovery logic first. Context: https://github.com/vitejs/vite-plugin-react/pull/1304\nconst SEARCH = 'debugInfo = root._debugInfo;';\nconst REPLACE = `\n${SEARCH}\nif (debugInfo && 0 === debugInfo.length && \"fulfilled\" === root.status) {\n var _resolved = typeof resolveLazy === \"function\" ? resolveLazy(root.value) : root.value;\n if (\"object\" === typeof _resolved && null !== _resolved && isArrayImpl(_resolved._debugInfo)) {\n debugInfo = _resolved._debugInfo;\n }\n}\n`;\n\nconst RSDW_CLIENT_ID = 'react-server-dom-webpack/client';\nconst RSDW_CLIENT_EDGE_ID = 'react-server-dom-webpack/client.edge';\nconst RSDW_SERVER_EDGE_ID = 'react-server-dom-webpack/server.edge';\n\nconst virtualId = (source: string) => '\\0' + source;\n\nconst isVitePluginRscImporter = (importer?: string) =>\n /(^|[/\\\\])@vitejs[/\\\\]plugin-rsc[/\\\\]/.test(importer || '');\n\nexport function patchRsdwPlugin(): Plugin {\n return {\n name: 'waku:vite-plugins:patch-rsdw',\n enforce: 'pre',\n resolveId(source, importer, _options) {\n if (source === RSDW_CLIENT_ID) {\n return virtualId(source);\n }\n if (\n (source === RSDW_CLIENT_EDGE_ID || source === RSDW_SERVER_EDGE_ID) &&\n !isVitePluginRscImporter(importer)\n ) {\n return virtualId(source);\n }\n },\n load(id) {\n if (id === virtualId(RSDW_CLIENT_ID)) {\n if (this.environment.name === 'client') {\n return `\n import * as ReactClient from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/browser'))};\n export default ReactClient;\n `;\n }\n return `export default {}`;\n }\n if (id === virtualId(RSDW_CLIENT_EDGE_ID)) {\n if (this.environment.name === 'rsc') {\n return `\n import { createFromReadableStream as createFromReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc/client'))};\n export function createFromReadableStream(stream) {\n return createFromReadableStreamBase(stream);\n }\n `;\n }\n return `export {}`;\n }\n if (id === virtualId(RSDW_SERVER_EDGE_ID)) {\n if (this.environment.name === 'rsc') {\n return `\n import { renderToReadableStream as renderToReadableStreamBase } from ${JSON.stringify(import.meta.resolve('@vitejs/plugin-rsc/react/rsc/server'))};\n export function renderToReadableStream(model, _webpackMap, options) {\n return renderToReadableStreamBase(model, options);\n }\n `;\n }\n return `export {}`;\n }\n },\n transform(code, id) {\n const [file] = id.split('?');\n if (\n ![\n '/react-server-dom-webpack-client.browser.development.js',\n '/react-server-dom-webpack_client__browser.js',\n ].some((suffix) => file!.endsWith(suffix))\n ) {\n return;\n }\n const patched = code.replace(SEARCH, REPLACE);\n if (patched === code) {\n return;\n }\n return patched;\n },\n };\n}\n"],"names":["SEARCH","REPLACE","RSDW_CLIENT_ID","RSDW_CLIENT_EDGE_ID","RSDW_SERVER_EDGE_ID","virtualId","source","isVitePluginRscImporter","importer","test","patchRsdwPlugin","name","enforce","resolveId","_options","load","id","environment","JSON","stringify","resolve","transform","code","file","split","some","suffix","endsWith","patched","replace"],"mappings":"AAEA,sEAAsE;AACtE,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,oEAAoE;AACpE,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,0EAA0E;AAC1E,uFAAuF;AACvF,MAAMA,SAAS;AACf,MAAMC,UAAU,CAAC;AACjB,EAAED,OAAO;;;;;;;AAOT,CAAC;AAED,MAAME,iBAAiB;AACvB,MAAMC,sBAAsB;AAC5B,MAAMC,sBAAsB;AAE5B,MAAMC,YAAY,CAACC,SAAmB,OAAOA;AAE7C,MAAMC,0BAA0B,CAACC,WAC/B,uCAAuCC,IAAI,CAACD,YAAY;AAE1D,OAAO,SAASE;IACd,OAAO;QACLC,MAAM;QACNC,SAAS;QACTC,WAAUP,MAAM,EAAEE,QAAQ,EAAEM,QAAQ;YAClC,IAAIR,WAAWJ,gBAAgB;gBAC7B,OAAOG,UAAUC;YACnB;YACA,IACE,AAACA,CAAAA,WAAWH,uBAAuBG,WAAWF,mBAAkB,KAChE,CAACG,wBAAwBC,WACzB;gBACA,OAAOH,UAAUC;YACnB;QACF;QACAS,MAAKC,EAAE;YACL,IAAIA,OAAOX,UAAUH,iBAAiB;gBACpC,IAAI,IAAI,CAACe,WAAW,CAACN,IAAI,KAAK,UAAU;oBACtC,OAAO,CAAC;2CACyB,EAAEO,KAAKC,SAAS,CAAC,YAAYC,OAAO,CAAC,+BAA+B;;YAEnG,CAAC;gBACL;gBACA,OAAO,CAAC,iBAAiB,CAAC;YAC5B;YACA,IAAIJ,OAAOX,UAAUF,sBAAsB;gBACzC,IAAI,IAAI,CAACc,WAAW,CAACN,IAAI,KAAK,OAAO;oBACnC,OAAO,CAAC;qFACmE,EAAEO,KAAKC,SAAS,CAAC,YAAYC,OAAO,CAAC,wCAAwC;;;;UAIxJ,CAAC;gBACH;gBACA,OAAO,CAAC,SAAS,CAAC;YACpB;YACA,IAAIJ,OAAOX,UAAUD,sBAAsB;gBACzC,IAAI,IAAI,CAACa,WAAW,CAACN,IAAI,KAAK,OAAO;oBACnC,OAAO,CAAC;iFAC+D,EAAEO,KAAKC,SAAS,CAAC,YAAYC,OAAO,CAAC,wCAAwC;;;;UAIpJ,CAAC;gBACH;gBACA,OAAO,CAAC,SAAS,CAAC;YACpB;QACF;QACAC,WAAUC,IAAI,EAAEN,EAAE;YAChB,MAAM,CAACO,KAAK,GAAGP,GAAGQ,KAAK,CAAC;YACxB,IACE,CAAC;gBACC;gBACA;aACD,CAACC,IAAI,CAAC,CAACC,SAAWH,KAAMI,QAAQ,CAACD,UAClC;gBACA;YACF;YACA,MAAME,UAAUN,KAAKO,OAAO,CAAC7B,QAAQC;YACrC,IAAI2B,YAAYN,MAAM;gBACpB;YACF;YACA,OAAOM;QACT;IACF;AACF"}
|
|
@@ -3,7 +3,7 @@ import * as vite from 'vite';
|
|
|
3
3
|
import { combinedPlugins } from '../vite-plugins/combined-plugins.js';
|
|
4
4
|
import { loadConfig, loadDotEnv } from './loader.js';
|
|
5
5
|
loadDotEnv();
|
|
6
|
-
function createServerRestartHandler() {
|
|
6
|
+
function createServerRestartHandler(strictPort) {
|
|
7
7
|
let restartInFlight = false;
|
|
8
8
|
return async (host, port, server)=>{
|
|
9
9
|
if (restartInFlight) {
|
|
@@ -16,7 +16,7 @@ function createServerRestartHandler() {
|
|
|
16
16
|
const previousUrls = server.resolvedUrls;
|
|
17
17
|
await server.close();
|
|
18
18
|
const freshConfig = await loadConfig();
|
|
19
|
-
const newServer = await startDevServer(host, port, freshConfig, true);
|
|
19
|
+
const newServer = await startDevServer(host, port, freshConfig, strictPort, true);
|
|
20
20
|
if (previousUrls) {
|
|
21
21
|
server.resolvedUrls = newServer.resolvedUrls;
|
|
22
22
|
}
|
|
@@ -25,7 +25,7 @@ function createServerRestartHandler() {
|
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
async function startDevServer(host, port, config, isRestart) {
|
|
28
|
+
async function startDevServer(host, port, config, strictPort, isRestart) {
|
|
29
29
|
if (isRestart) {
|
|
30
30
|
loadDotEnv();
|
|
31
31
|
}
|
|
@@ -36,12 +36,14 @@ async function startDevServer(host, port, config, isRestart) {
|
|
|
36
36
|
],
|
|
37
37
|
server: host ? {
|
|
38
38
|
host,
|
|
39
|
-
port
|
|
39
|
+
port,
|
|
40
|
+
strictPort
|
|
40
41
|
} : {
|
|
41
|
-
port
|
|
42
|
+
port,
|
|
43
|
+
strictPort
|
|
42
44
|
}
|
|
43
45
|
});
|
|
44
|
-
const handleServerRestart = createServerRestartHandler();
|
|
46
|
+
const handleServerRestart = createServerRestartHandler(strictPort);
|
|
45
47
|
// Override Vite's restart to intercept automatic restarts (.env, tsconfig, etc.)
|
|
46
48
|
server.restart = async ()=>{
|
|
47
49
|
console.log('Vite server restart intercepted, reloading Waku plugins...');
|
|
@@ -69,8 +71,9 @@ export async function runDev(flags) {
|
|
|
69
71
|
process.env.NODE_ENV ??= 'development';
|
|
70
72
|
const config = await loadConfig();
|
|
71
73
|
const host = flags.host;
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
+
const configuredPort = flags.port ?? process.env.PORT;
|
|
75
|
+
const port = parseInt(configuredPort ?? '3000', 10);
|
|
76
|
+
await startDevServer(host, port, config, configuredPort !== undefined);
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
//# sourceMappingURL=cmd-dev.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/vite-rsc/cmd-dev.ts"],"sourcesContent":["import path from 'node:path';\nimport * as vite from 'vite';\nimport type { Config } from '../../config.js';\nimport { combinedPlugins } from '../vite-plugins/combined-plugins.js';\nimport { loadConfig, loadDotEnv } from './loader.js';\n\nloadDotEnv();\n\nfunction createServerRestartHandler() {\n let restartInFlight = false;\n\n return async (\n host: string | undefined,\n port: number,\n server: vite.ViteDevServer,\n ) => {\n if (restartInFlight) {\n console.log('Server restart already in progress, skipping...');\n return;\n }\n restartInFlight = true;\n try {\n console.log('Restarting server with fresh plugin configuration...');\n const previousUrls = server.resolvedUrls;\n await server.close();\n const freshConfig = await loadConfig();\n const newServer = await startDevServer(host
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/vite-rsc/cmd-dev.ts"],"sourcesContent":["import path from 'node:path';\nimport * as vite from 'vite';\nimport type { Config } from '../../config.js';\nimport { combinedPlugins } from '../vite-plugins/combined-plugins.js';\nimport { loadConfig, loadDotEnv } from './loader.js';\n\nloadDotEnv();\n\nfunction createServerRestartHandler(strictPort: boolean) {\n let restartInFlight = false;\n\n return async (\n host: string | undefined,\n port: number,\n server: vite.ViteDevServer,\n ) => {\n if (restartInFlight) {\n console.log('Server restart already in progress, skipping...');\n return;\n }\n restartInFlight = true;\n try {\n console.log('Restarting server with fresh plugin configuration...');\n const previousUrls = server.resolvedUrls;\n await server.close();\n const freshConfig = await loadConfig();\n const newServer = await startDevServer(\n host,\n port,\n freshConfig,\n strictPort,\n true,\n );\n if (previousUrls) {\n server.resolvedUrls = newServer.resolvedUrls;\n }\n } finally {\n restartInFlight = false;\n }\n };\n}\n\nasync function startDevServer(\n host: string | undefined,\n port: number,\n config: Required<Config>,\n strictPort: boolean,\n isRestart?: boolean,\n) {\n if (isRestart) {\n loadDotEnv();\n }\n const server = await vite.createServer({\n configFile: false,\n plugins: [combinedPlugins(config)],\n server: host ? { host, port, strictPort } : { port, strictPort },\n });\n const handleServerRestart = createServerRestartHandler(strictPort);\n // Override Vite's restart to intercept automatic restarts (.env, tsconfig, etc.)\n server.restart = async () => {\n console.log('Vite server restart intercepted, reloading Waku plugins...');\n await handleServerRestart(host, port, server);\n };\n await server.listen();\n const url =\n server.resolvedUrls?.network?.[0] ?? server.resolvedUrls?.local?.[0];\n console.log(`ready: Listening on ${url}`);\n const watcher = server.watcher;\n watcher.on('change', handleConfigChange);\n watcher.on('unlink', handleConfigChange);\n watcher.on('add', handleConfigChange);\n\n async function handleConfigChange(changedFile: string) {\n const dirname = path.dirname(changedFile);\n const filename = path.basename(changedFile);\n if (\n dirname === process.cwd() &&\n (filename === 'waku.config.ts' || filename === 'waku.config.js')\n ) {\n console.log(`Waku configuration file changed, restarting server...`);\n await handleServerRestart(host, port, server);\n }\n }\n\n return server;\n}\n\nexport async function runDev(flags: { host?: string; port?: string }) {\n // set NODE_ENV before vite.runnerImport: https://github.com/vitejs/vite/issues/20299\n process.env.NODE_ENV ??= 'development';\n const config = await loadConfig();\n const host = flags.host;\n const configuredPort = flags.port ?? process.env.PORT;\n const port = parseInt(configuredPort ?? '3000', 10);\n await startDevServer(host, port, config, configuredPort !== undefined);\n}\n"],"names":["path","vite","combinedPlugins","loadConfig","loadDotEnv","createServerRestartHandler","strictPort","restartInFlight","host","port","server","console","log","previousUrls","resolvedUrls","close","freshConfig","newServer","startDevServer","config","isRestart","createServer","configFile","plugins","handleServerRestart","restart","listen","url","network","local","watcher","on","handleConfigChange","changedFile","dirname","filename","basename","process","cwd","runDev","flags","env","NODE_ENV","configuredPort","PORT","parseInt","undefined"],"mappings":"AAAA,OAAOA,UAAU,YAAY;AAC7B,YAAYC,UAAU,OAAO;AAE7B,SAASC,eAAe,QAAQ,sCAAsC;AACtE,SAASC,UAAU,EAAEC,UAAU,QAAQ,cAAc;AAErDA;AAEA,SAASC,2BAA2BC,UAAmB;IACrD,IAAIC,kBAAkB;IAEtB,OAAO,OACLC,MACAC,MACAC;QAEA,IAAIH,iBAAiB;YACnBI,QAAQC,GAAG,CAAC;YACZ;QACF;QACAL,kBAAkB;QAClB,IAAI;YACFI,QAAQC,GAAG,CAAC;YACZ,MAAMC,eAAeH,OAAOI,YAAY;YACxC,MAAMJ,OAAOK,KAAK;YAClB,MAAMC,cAAc,MAAMb;YAC1B,MAAMc,YAAY,MAAMC,eACtBV,MACAC,MACAO,aACAV,YACA;YAEF,IAAIO,cAAc;gBAChBH,OAAOI,YAAY,GAAGG,UAAUH,YAAY;YAC9C;QACF,SAAU;YACRP,kBAAkB;QACpB;IACF;AACF;AAEA,eAAeW,eACbV,IAAwB,EACxBC,IAAY,EACZU,MAAwB,EACxBb,UAAmB,EACnBc,SAAmB;IAEnB,IAAIA,WAAW;QACbhB;IACF;IACA,MAAMM,SAAS,MAAMT,KAAKoB,YAAY,CAAC;QACrCC,YAAY;QACZC,SAAS;YAACrB,gBAAgBiB;SAAQ;QAClCT,QAAQF,OAAO;YAAEA;YAAMC;YAAMH;QAAW,IAAI;YAAEG;YAAMH;QAAW;IACjE;IACA,MAAMkB,sBAAsBnB,2BAA2BC;IACvD,iFAAiF;IACjFI,OAAOe,OAAO,GAAG;QACfd,QAAQC,GAAG,CAAC;QACZ,MAAMY,oBAAoBhB,MAAMC,MAAMC;IACxC;IACA,MAAMA,OAAOgB,MAAM;IACnB,MAAMC,MACJjB,OAAOI,YAAY,EAAEc,SAAS,CAAC,EAAE,IAAIlB,OAAOI,YAAY,EAAEe,OAAO,CAAC,EAAE;IACtElB,QAAQC,GAAG,CAAC,CAAC,oBAAoB,EAAEe,KAAK;IACxC,MAAMG,UAAUpB,OAAOoB,OAAO;IAC9BA,QAAQC,EAAE,CAAC,UAAUC;IACrBF,QAAQC,EAAE,CAAC,UAAUC;IACrBF,QAAQC,EAAE,CAAC,OAAOC;IAElB,eAAeA,mBAAmBC,WAAmB;QACnD,MAAMC,UAAUlC,KAAKkC,OAAO,CAACD;QAC7B,MAAME,WAAWnC,KAAKoC,QAAQ,CAACH;QAC/B,IACEC,YAAYG,QAAQC,GAAG,MACtBH,CAAAA,aAAa,oBAAoBA,aAAa,gBAAe,GAC9D;YACAxB,QAAQC,GAAG,CAAC,CAAC,qDAAqD,CAAC;YACnE,MAAMY,oBAAoBhB,MAAMC,MAAMC;QACxC;IACF;IAEA,OAAOA;AACT;AAEA,OAAO,eAAe6B,OAAOC,KAAuC;IAClE,qFAAqF;IACrFH,QAAQI,GAAG,CAACC,QAAQ,KAAK;IACzB,MAAMvB,SAAS,MAAMhB;IACrB,MAAMK,OAAOgC,MAAMhC,IAAI;IACvB,MAAMmC,iBAAiBH,MAAM/B,IAAI,IAAI4B,QAAQI,GAAG,CAACG,IAAI;IACrD,MAAMnC,OAAOoC,SAASF,kBAAkB,QAAQ;IAChD,MAAMzB,eAAeV,MAAMC,MAAMU,QAAQwB,mBAAmBG;AAC9D"}
|
|
@@ -8,7 +8,8 @@ export async function runStart(flags) {
|
|
|
8
8
|
process.env.NODE_ENV ??= 'production';
|
|
9
9
|
const config = await loadConfig();
|
|
10
10
|
const host = flags.host;
|
|
11
|
-
const
|
|
11
|
+
const configuredPort = flags.port ?? process.env.PORT;
|
|
12
|
+
const port = configuredPort === undefined ? await getFreePort(8080) : parseInt(configuredPort, 10);
|
|
12
13
|
const distDir = config?.distDir ?? 'dist';
|
|
13
14
|
const serveFileUrl = pathToFileURL(path.resolve(distDir, 'serve-node.js')).href;
|
|
14
15
|
if (host) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/vite-rsc/cmd-start.ts"],"sourcesContent":["import net from 'node:net';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { loadConfig, loadDotEnv } from './loader.js';\n\nloadDotEnv();\n\nexport async function runStart(flags: { host?: string; port?: string }) {\n // set NODE_ENV before vite.runnerImport: https://github.com/vitejs/vite/issues/20299\n process.env.NODE_ENV ??= 'production';\n const config = await loadConfig();\n const host = flags.host;\n const
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/vite-rsc/cmd-start.ts"],"sourcesContent":["import net from 'node:net';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { loadConfig, loadDotEnv } from './loader.js';\n\nloadDotEnv();\n\nexport async function runStart(flags: { host?: string; port?: string }) {\n // set NODE_ENV before vite.runnerImport: https://github.com/vitejs/vite/issues/20299\n process.env.NODE_ENV ??= 'production';\n const config = await loadConfig();\n const host = flags.host;\n const configuredPort = flags.port ?? process.env.PORT;\n const port =\n configuredPort === undefined\n ? await getFreePort(8080)\n : parseInt(configuredPort, 10);\n const distDir = config?.distDir ?? 'dist';\n const serveFileUrl = pathToFileURL(\n path.resolve(distDir, 'serve-node.js'),\n ).href;\n if (host) {\n process.env.HOST = host;\n } else {\n delete process.env.HOST;\n }\n process.env.PORT = String(port);\n await import(serveFileUrl);\n // Defaulting '0.0.0.0' seems heuristic, and not useful.\n // Ref: https://github.com/wakujs/waku/pull/1987\n console.log(`ready: Listening on http://${host || '0.0.0.0'}:${port}/`);\n}\n\nasync function getFreePort(startPort: number): Promise<number> {\n for (let port = startPort; ; port++) {\n try {\n await new Promise<void>((resolve, reject) => {\n const srv = net\n .createServer()\n .once('error', reject)\n .once('listening', () => srv.close(() => resolve()))\n .listen(port);\n });\n return port;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'EADDRINUSE') {\n throw err;\n }\n }\n }\n}\n"],"names":["net","path","pathToFileURL","loadConfig","loadDotEnv","runStart","flags","process","env","NODE_ENV","config","host","configuredPort","port","PORT","undefined","getFreePort","parseInt","distDir","serveFileUrl","resolve","href","HOST","String","console","log","startPort","Promise","reject","srv","createServer","once","close","listen","err","code"],"mappings":"AAAA,OAAOA,SAAS,WAAW;AAC3B,OAAOC,UAAU,YAAY;AAC7B,SAASC,aAAa,QAAQ,WAAW;AACzC,SAASC,UAAU,EAAEC,UAAU,QAAQ,cAAc;AAErDA;AAEA,OAAO,eAAeC,SAASC,KAAuC;IACpE,qFAAqF;IACrFC,QAAQC,GAAG,CAACC,QAAQ,KAAK;IACzB,MAAMC,SAAS,MAAMP;IACrB,MAAMQ,OAAOL,MAAMK,IAAI;IACvB,MAAMC,iBAAiBN,MAAMO,IAAI,IAAIN,QAAQC,GAAG,CAACM,IAAI;IACrD,MAAMD,OACJD,mBAAmBG,YACf,MAAMC,YAAY,QAClBC,SAASL,gBAAgB;IAC/B,MAAMM,UAAUR,QAAQQ,WAAW;IACnC,MAAMC,eAAejB,cACnBD,KAAKmB,OAAO,CAACF,SAAS,kBACtBG,IAAI;IACN,IAAIV,MAAM;QACRJ,QAAQC,GAAG,CAACc,IAAI,GAAGX;IACrB,OAAO;QACL,OAAOJ,QAAQC,GAAG,CAACc,IAAI;IACzB;IACAf,QAAQC,GAAG,CAACM,IAAI,GAAGS,OAAOV;IAC1B,MAAM,MAAM,CAACM;IACb,wDAAwD;IACxD,gDAAgD;IAChDK,QAAQC,GAAG,CAAC,CAAC,2BAA2B,EAAEd,QAAQ,UAAU,CAAC,EAAEE,KAAK,CAAC,CAAC;AACxE;AAEA,eAAeG,YAAYU,SAAiB;IAC1C,IAAK,IAAIb,OAAOa,YAAab,OAAQ;QACnC,IAAI;YACF,MAAM,IAAIc,QAAc,CAACP,SAASQ;gBAChC,MAAMC,MAAM7B,IACT8B,YAAY,GACZC,IAAI,CAAC,SAASH,QACdG,IAAI,CAAC,aAAa,IAAMF,IAAIG,KAAK,CAAC,IAAMZ,YACxCa,MAAM,CAACpB;YACZ;YACA,OAAOA;QACT,EAAE,OAAOqB,KAAK;YACZ,IAAI,AAACA,IAA8BC,IAAI,KAAK,cAAc;gBACxD,MAAMD;YACR;QACF;IACF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction, renderToReadableStream } from '@vitejs/plugin-rsc/rsc/server';
|
|
2
2
|
import { buildMetadata } from 'virtual:vite-rsc-waku/build-metadata';
|
|
3
3
|
import { config, isBuild } from 'virtual:vite-rsc-waku/config';
|
|
4
4
|
import notFoundHtml from 'virtual:vite-rsc-waku/not-found';
|
|
@@ -26,7 +26,7 @@ const toProcessRequest = (handleRequest)=>async (req)=>{
|
|
|
26
26
|
if (debugId) {
|
|
27
27
|
debugChannels?.delete(debugId);
|
|
28
28
|
}
|
|
29
|
-
const renderUtils = createRenderUtils(temporaryReferences, renderToReadableStream,
|
|
29
|
+
const renderUtils = createRenderUtils(temporaryReferences, renderToReadableStream, loadSsrEntryModule, import.meta.env.WAKU_BUILD_ID ?? '', debugChannel, debugId);
|
|
30
30
|
let res;
|
|
31
31
|
try {
|
|
32
32
|
res = await handleRequest(input, {
|
|
@@ -73,7 +73,7 @@ const toProcessRequest = (handleRequest)=>async (req)=>{
|
|
|
73
73
|
return null;
|
|
74
74
|
};
|
|
75
75
|
const toProcessBuild = (handleBuild)=>async ({ emitFile, unstable_registerPrunableFile })=>{
|
|
76
|
-
const renderUtils = createRenderUtils(undefined, renderToReadableStream,
|
|
76
|
+
const renderUtils = createRenderUtils(undefined, renderToReadableStream, loadSsrEntryModule, import.meta.env.WAKU_BUILD_ID ?? '');
|
|
77
77
|
let fallbackHtml;
|
|
78
78
|
const getFallbackHtml = async ()=>{
|
|
79
79
|
if (!fallbackHtml) {
|
|
@@ -91,7 +91,6 @@ const toProcessBuild = (handleBuild)=>async ({ emitFile, unstable_registerPrunab
|
|
|
91
91
|
};
|
|
92
92
|
await handleBuild({
|
|
93
93
|
renderRsc: renderUtils.renderRsc,
|
|
94
|
-
parseRsc: renderUtils.parseRsc,
|
|
95
94
|
renderHtml: renderUtils.renderHtml,
|
|
96
95
|
rscPath2pathname: (rscPath)=>joinPath(config.rscBase, encodeRscPath(rscPath)),
|
|
97
96
|
saveBuildMetadata: async (key, value)=>{
|