vite-plugin-react-server 0.3.0 → 0.3.3
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 +73 -40
- package/dist/assertServerCondition.d.ts +2 -0
- package/dist/assertServerCondition.d.ts.map +1 -0
- package/dist/bin/patch.js +51 -0
- package/dist/bin/patch.js.map +1 -0
- package/dist/build/createBuildConfig.d.ts +7 -6
- package/dist/build/createBuildConfig.d.ts.map +1 -1
- package/dist/build/mergeInputs.d.ts +5 -0
- package/dist/build/mergeInputs.d.ts.map +1 -0
- package/dist/helpers/inputNormalizer.d.ts +6 -0
- package/dist/helpers/inputNormalizer.d.ts.map +1 -0
- package/dist/helpers/normalizedRelativePath.d.ts +3 -1
- package/dist/helpers/normalizedRelativePath.d.ts.map +1 -1
- package/dist/helpers/tryManifest.d.ts +10 -3
- package/dist/helpers/tryManifest.d.ts.map +1 -1
- package/dist/html/createPageLoader.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/options.d.ts +13 -8
- package/dist/options.d.ts.map +1 -1
- package/dist/plugin.d.ts +2 -7
- package/dist/plugin.d.ts.map +1 -1
- package/dist/react-client/plugin.js +1 -1
- package/dist/react-server/plugin.d.ts.map +1 -1
- package/dist/react-server/plugin.js +108 -61
- package/dist/react-server/plugin.js.map +1 -1
- package/dist/src/build/createBuildConfig.js +44 -0
- package/dist/src/build/createBuildConfig.js.map +1 -0
- package/dist/src/build/mergeInputs.js +16 -0
- package/dist/src/build/mergeInputs.js.map +1 -0
- package/dist/src/checkFilesExist.js.map +1 -0
- package/dist/src/collect-css-manifest.js.map +1 -0
- package/dist/src/components.js.map +1 -0
- package/dist/src/getEnv.js.map +1 -0
- package/dist/src/helpers/inputNormalizer.js +11 -0
- package/dist/src/helpers/inputNormalizer.js.map +1 -0
- package/dist/src/helpers/normalizedRelativePath.js +34 -0
- package/dist/src/helpers/normalizedRelativePath.js.map +1 -0
- package/dist/src/helpers/tryManifest.js +27 -0
- package/dist/src/helpers/tryManifest.js.map +1 -0
- package/dist/{html → src/html}/createPageLoader.js +3 -1
- package/dist/src/html/createPageLoader.js.map +1 -0
- package/dist/{options.js → src/options.js} +80 -24
- package/dist/src/options.js.map +1 -0
- package/dist/src/react-server/createHandler.js.map +1 -0
- package/dist/src/react-server/createRscStream.js.map +1 -0
- package/dist/src/resolvePage.js.map +1 -0
- package/dist/src/resolveProps.js.map +1 -0
- package/dist/src/worker/createHtmlStream.js +62 -0
- package/dist/src/worker/createHtmlStream.js.map +1 -0
- package/dist/{worker → src/worker}/createWorker.js +9 -8
- package/dist/src/worker/createWorker.js.map +1 -0
- package/dist/src/worker/renderPages.js.map +1 -0
- package/dist/types.d.ts +7 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/worker/createWorker.d.ts +8 -1
- package/dist/worker/createWorker.d.ts.map +1 -1
- package/dist/worker/loader.js +7 -0
- package/dist/worker/loader.js.map +1 -0
- package/dist/worker/worker.js +112 -0
- package/dist/worker/worker.js.map +1 -0
- package/package.json +108 -111
- package/patches/react-server-dom-esm+0.0.1.patch +14519 -0
- package/src/assertServerCondition.ts +13 -0
- package/src/build/createBuildConfig.ts +27 -44
- package/src/build/mergeInputs.ts +42 -0
- package/src/helpers/inputNormalizer.ts +22 -0
- package/src/helpers/normalizedRelativePath.ts +25 -25
- package/src/helpers/tryManifest.ts +19 -5
- package/src/html/createPageLoader.ts +2 -0
- package/src/options.ts +119 -47
- package/src/plugin.ts +4 -30
- package/src/react-server/createSsrHandler.ts +1 -1
- package/src/react-server/plugin.ts +116 -56
- package/src/types.ts +19 -1
- package/src/worker/createWorker.ts +12 -7
- package/tsconfig.json +2 -0
- package/dist/build/createBuildConfig.js +0 -55
- package/dist/build/createBuildConfig.js.map +0 -1
- package/dist/checkFilesExist.js.map +0 -1
- package/dist/collect-css-manifest.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/getEnv.js.map +0 -1
- package/dist/helpers/normalizedRelativePath.js +0 -31
- package/dist/helpers/normalizedRelativePath.js.map +0 -1
- package/dist/html/createPageLoader.js.map +0 -1
- package/dist/options.js.map +0 -1
- package/dist/plugin.js +0 -31
- package/dist/plugin.js.map +0 -1
- package/dist/react-server/createHandler.js.map +0 -1
- package/dist/react-server/createRscStream.js.map +0 -1
- package/dist/resolvePage.js.map +0 -1
- package/dist/resolveProps.js.map +0 -1
- package/dist/transformer/index.js +0 -54
- package/dist/transformer/index.js.map +0 -1
- package/dist/transformer/preserveDirectives.js +0 -72
- package/dist/transformer/preserveDirectives.js.map +0 -1
- package/dist/transformer/transformer.js +0 -80
- package/dist/transformer/transformer.js.map +0 -1
- package/dist/worker/createWorker.js.map +0 -1
- package/dist/worker/renderPages.js.map +0 -1
- /package/dist/{checkFilesExist.js → src/checkFilesExist.js} +0 -0
- /package/dist/{collect-css-manifest.js → src/collect-css-manifest.js} +0 -0
- /package/dist/{components.js → src/components.js} +0 -0
- /package/dist/{getEnv.js → src/getEnv.js} +0 -0
- /package/dist/{react-server → src/react-server}/createHandler.js +0 -0
- /package/dist/{react-server → src/react-server}/createRscStream.js +0 -0
- /package/dist/{resolvePage.js → src/resolvePage.js} +0 -0
- /package/dist/{resolveProps.js → src/resolveProps.js} +0 -0
- /package/dist/{worker → src/worker}/renderPages.js +0 -0
|
@@ -11,9 +11,9 @@ const DEFAULT_CONFIG = {
|
|
|
11
11
|
CLIENT_ENTRY: "/src/client.tsx",
|
|
12
12
|
PAGE_EXPORT: "Page",
|
|
13
13
|
PROPS_EXPORT: "props",
|
|
14
|
-
//
|
|
15
|
-
WORKER_PATH: "
|
|
16
|
-
LOADER_PATH: "
|
|
14
|
+
// Use package name paths instead of relative paths
|
|
15
|
+
WORKER_PATH: "vite-plugin-react-server/worker",
|
|
16
|
+
LOADER_PATH: "vite-plugin-react-server/loader",
|
|
17
17
|
RSC_EXTENSION: ".rsc",
|
|
18
18
|
HTML: ({ children }) => children,
|
|
19
19
|
COLLECT_CSS: true,
|
|
@@ -29,6 +29,10 @@ const DEFAULT_CONFIG = {
|
|
|
29
29
|
pages: () => ["/"],
|
|
30
30
|
client: "dist/client",
|
|
31
31
|
server: "dist/server"
|
|
32
|
+
},
|
|
33
|
+
AUTO_DISCOVER: {
|
|
34
|
+
pagePattern: "**/*.page.tsx",
|
|
35
|
+
propsPattern: "**/*.props.ts"
|
|
32
36
|
}
|
|
33
37
|
};
|
|
34
38
|
const resolveUserConfig = (condition, input, config, configEnv, userOptions) => {
|
|
@@ -84,7 +88,16 @@ const resolveUserConfig = (condition, input, config, configEnv, userOptions) =>
|
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
const { root: configRoot, mode: configMode, ...configRest } = config;
|
|
87
|
-
const {
|
|
91
|
+
const {
|
|
92
|
+
outDir: configOutDir,
|
|
93
|
+
assetsDir: configAssetsDir,
|
|
94
|
+
ssr: configSsr,
|
|
95
|
+
manifest: configManifest,
|
|
96
|
+
ssrManifest: configSsrManifest,
|
|
97
|
+
ssrEmitAssets: configSsrEmitAssets,
|
|
98
|
+
target: configTarget,
|
|
99
|
+
...configBuildRest
|
|
100
|
+
} = config.build ?? {};
|
|
88
101
|
return {
|
|
89
102
|
type: "success",
|
|
90
103
|
userConfig: {
|
|
@@ -96,6 +109,7 @@ const resolveUserConfig = (condition, input, config, configEnv, userOptions) =>
|
|
|
96
109
|
ssr: configSsr ?? isReactServer,
|
|
97
110
|
manifest: configManifest ?? true,
|
|
98
111
|
ssrManifest: configSsrManifest ?? true,
|
|
112
|
+
ssrEmitAssets: configSsrEmitAssets ?? true,
|
|
99
113
|
target: configTarget ?? "es2020",
|
|
100
114
|
outDir: typeof configOutDir === "string" ? configOutDir : isReactServer ? userOptions.build.server : userOptions.build.client,
|
|
101
115
|
assetsDir: typeof configAssetsDir === "string" ? configAssetsDir : isReactServer ? "" : DEFAULT_CONFIG.CLIENT_ASSETS_DIR
|
|
@@ -104,17 +118,40 @@ const resolveUserConfig = (condition, input, config, configEnv, userOptions) =>
|
|
|
104
118
|
};
|
|
105
119
|
};
|
|
106
120
|
const resolveOptions = (options) => {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
const {
|
|
122
|
+
workerPath: optionsWorkerPath,
|
|
123
|
+
loaderPath: optionsLoaderPath,
|
|
124
|
+
projectRoot: optionsProjectRoot,
|
|
125
|
+
moduleBase: optionsModuleBase,
|
|
126
|
+
moduleBasePath: optionsModuleBasePath,
|
|
127
|
+
moduleBaseURL: optionsModuleBaseURL,
|
|
128
|
+
build: optionsBuild,
|
|
129
|
+
Page: optionsPage,
|
|
130
|
+
props: optionsProps,
|
|
131
|
+
Html: optionsHtml,
|
|
132
|
+
pageExportName: optionsPageExportName,
|
|
133
|
+
propsExportName: optionsPropsExportName,
|
|
134
|
+
collectCss: optionsCollectCss,
|
|
135
|
+
collectAssets: optionsCollectAssets,
|
|
136
|
+
assetsDir: optionsAssetsDir,
|
|
137
|
+
clientEntry: optionsClientEntry,
|
|
138
|
+
serverOutDir: optionsServerOutDir,
|
|
139
|
+
clientOutDir: optionsClientOutDir,
|
|
140
|
+
autoDiscover: optionsAutoDiscover,
|
|
141
|
+
moduleBaseExceptions: optionsModuleBaseExceptions,
|
|
142
|
+
...restOptions
|
|
143
|
+
} = options;
|
|
144
|
+
const projectRoot = optionsProjectRoot ?? process.cwd();
|
|
145
|
+
const moduleBase = typeof optionsModuleBase === "string" ? optionsModuleBase.startsWith(path.sep) ? optionsModuleBase.slice(path.sep.length) : optionsModuleBase : DEFAULT_CONFIG.MODULE_BASE;
|
|
146
|
+
if (typeof optionsModuleBase === "string" && optionsModuleBase !== moduleBase) {
|
|
110
147
|
return {
|
|
111
148
|
type: "error",
|
|
112
149
|
error: new Error(
|
|
113
|
-
`moduleBase ${
|
|
150
|
+
`moduleBase ${optionsModuleBase} is invalid, should be like ${moduleBase}`
|
|
114
151
|
)
|
|
115
152
|
};
|
|
116
153
|
}
|
|
117
|
-
const moduleBasePath = typeof
|
|
154
|
+
const moduleBasePath = typeof optionsModuleBasePath === "string" ? !optionsModuleBasePath.startsWith(path.sep) ? `${path.sep}${optionsModuleBasePath}` : optionsModuleBasePath : `${path.sep}${moduleBase}`;
|
|
118
155
|
if (!moduleBasePath.includes(moduleBase)) {
|
|
119
156
|
return {
|
|
120
157
|
type: "error",
|
|
@@ -123,7 +160,7 @@ const resolveOptions = (options) => {
|
|
|
123
160
|
)
|
|
124
161
|
};
|
|
125
162
|
}
|
|
126
|
-
const moduleBaseURL = typeof
|
|
163
|
+
const moduleBaseURL = typeof optionsModuleBaseURL === "string" ? !optionsModuleBaseURL.endsWith(moduleBasePath) ? path.join(optionsModuleBaseURL, moduleBasePath) : optionsModuleBaseURL : moduleBasePath;
|
|
127
164
|
if (!moduleBaseURL.includes(moduleBasePath)) {
|
|
128
165
|
return {
|
|
129
166
|
type: "error",
|
|
@@ -132,35 +169,54 @@ const resolveOptions = (options) => {
|
|
|
132
169
|
)
|
|
133
170
|
};
|
|
134
171
|
}
|
|
135
|
-
if (typeof
|
|
172
|
+
if (typeof optionsModuleBaseURL === "string" && optionsModuleBaseURL !== moduleBaseURL) {
|
|
136
173
|
return {
|
|
137
174
|
type: "error",
|
|
138
175
|
error: new Error(
|
|
139
|
-
`moduleBaseURL ${
|
|
176
|
+
`moduleBaseURL ${optionsModuleBaseURL} is invalid, should be like ${moduleBaseURL}`
|
|
140
177
|
)
|
|
141
178
|
};
|
|
142
179
|
}
|
|
143
|
-
const build =
|
|
144
|
-
client:
|
|
145
|
-
pages:
|
|
146
|
-
server:
|
|
180
|
+
const build = optionsBuild ? {
|
|
181
|
+
client: optionsBuild.client ?? DEFAULT_CONFIG.BUILD.client,
|
|
182
|
+
pages: optionsBuild.pages ?? DEFAULT_CONFIG.BUILD.pages,
|
|
183
|
+
server: optionsBuild.server ?? DEFAULT_CONFIG.BUILD.server
|
|
147
184
|
} : DEFAULT_CONFIG.BUILD;
|
|
185
|
+
const autoDiscover = typeof optionsAutoDiscover === "object" ? {
|
|
186
|
+
pagePattern: typeof optionsAutoDiscover.pagePattern === "string" ? optionsAutoDiscover.pagePattern : DEFAULT_CONFIG.AUTO_DISCOVER.pagePattern,
|
|
187
|
+
propsPattern: typeof optionsAutoDiscover.propsPattern === "string" ? optionsAutoDiscover.propsPattern : DEFAULT_CONFIG.AUTO_DISCOVER.propsPattern
|
|
188
|
+
} : DEFAULT_CONFIG.AUTO_DISCOVER;
|
|
189
|
+
const workerPath = typeof optionsWorkerPath === "string" ? optionsWorkerPath : DEFAULT_CONFIG.WORKER_PATH;
|
|
190
|
+
const loaderPath = typeof optionsLoaderPath === "string" ? optionsLoaderPath : DEFAULT_CONFIG.LOADER_PATH;
|
|
148
191
|
return {
|
|
149
192
|
type: "success",
|
|
150
193
|
userOptions: {
|
|
194
|
+
...DEFAULT_CONFIG,
|
|
195
|
+
...restOptions,
|
|
151
196
|
moduleBase,
|
|
152
197
|
moduleBasePath,
|
|
153
198
|
moduleBaseURL,
|
|
154
199
|
build,
|
|
155
|
-
Page:
|
|
156
|
-
props:
|
|
157
|
-
Html:
|
|
158
|
-
pageExportName:
|
|
159
|
-
propsExportName:
|
|
160
|
-
collectCss:
|
|
161
|
-
collectAssets:
|
|
200
|
+
Page: optionsPage ?? DEFAULT_CONFIG.PAGE,
|
|
201
|
+
props: optionsProps ?? DEFAULT_CONFIG.PROPS,
|
|
202
|
+
Html: optionsHtml ?? DEFAULT_CONFIG.HTML,
|
|
203
|
+
pageExportName: optionsPageExportName ?? DEFAULT_CONFIG.PAGE_EXPORT,
|
|
204
|
+
propsExportName: optionsPropsExportName ?? DEFAULT_CONFIG.PROPS_EXPORT,
|
|
205
|
+
collectCss: optionsCollectCss ?? DEFAULT_CONFIG.COLLECT_CSS,
|
|
206
|
+
collectAssets: optionsCollectAssets ?? DEFAULT_CONFIG.COLLECT_ASSETS,
|
|
162
207
|
projectRoot,
|
|
163
|
-
assetsDir:
|
|
208
|
+
assetsDir: optionsAssetsDir ?? DEFAULT_CONFIG.CLIENT_ASSETS_DIR,
|
|
209
|
+
workerPath,
|
|
210
|
+
loaderPath,
|
|
211
|
+
clientEntry: optionsClientEntry ?? DEFAULT_CONFIG.CLIENT_ENTRY,
|
|
212
|
+
serverOutDir: optionsServerOutDir ?? DEFAULT_CONFIG.BUILD.server,
|
|
213
|
+
clientOutDir: optionsClientOutDir ?? DEFAULT_CONFIG.BUILD.client,
|
|
214
|
+
autoDiscover,
|
|
215
|
+
moduleBaseExceptions: [
|
|
216
|
+
workerPath,
|
|
217
|
+
loaderPath,
|
|
218
|
+
...optionsModuleBaseExceptions ?? []
|
|
219
|
+
]
|
|
164
220
|
}
|
|
165
221
|
};
|
|
166
222
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sources":["../../src/options.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { ConfigEnv, ResolvedConfig, UserConfig } from \"vite\";\nimport type { ResolvedUserConfig, ResolvedUserOptions, StreamPluginOptions } from \"./types.js\";\nimport type { InputOption } from \"rollup\";\n// Default configuration values\nexport const DEFAULT_CONFIG = {\n FILE_REGEX: /\\.(m|c)?(j|t)sx?$/,\n CLIENT_ASSETS_DIR: \"assets\",\n RSC_DIR: \"rsc\",\n MODULE_BASE: \"src\",\n MODULE_BASE_PATH: \"/src\",\n MODULE_BASE_URL: \"/src\",\n PAGE: \"/src/page/page.tsx\",\n PROPS: \"/src/page/props.ts\",\n CLIENT_ENTRY: \"/src/client.tsx\",\n PAGE_EXPORT: \"Page\",\n PROPS_EXPORT: \"props\",\n // Use package name paths instead of relative paths\n WORKER_PATH: \"vite-plugin-react-server/worker\",\n LOADER_PATH: \"vite-plugin-react-server/loader\",\n RSC_EXTENSION: \".rsc\",\n HTML: ({ children }: { children: any }) => children,\n COLLECT_CSS: true,\n COLLECT_ASSETS: true,\n PAGE_PATTERN: \"/src/page/**/*.page.tsx\",\n PROPS_PATTERN: \"/src/page/**/*.props.ts\",\n DEV_PORT: 5173,\n PREVIEW_PORT: 4173,\n DEV_HOST: \"localhost\",\n PREVIEW_HOST: \"localhost\",\n ENV_PREFIX: \"VITE_\",\n BUILD: {\n pages: () => [\"/\"],\n client: \"dist/client\",\n server: \"dist/server\",\n },\n AUTO_DISCOVER: {\n pagePattern: \"**/*.page.tsx\",\n propsPattern: \"**/*.props.ts\",\n },\n} as const;\n\nexport const resolveConfig = <T extends ResolvedConfig>(\n config: T,\n resolvedUserConfig: UserConfig,\n userOptions: ResolvedUserOptions\n) => {\n return {\n ...config,\n build: {\n ...config.build,\n assetsDir: config.build?.assetsDir ?? DEFAULT_CONFIG.CLIENT_ASSETS_DIR,\n },\n };\n};\n\nexport const resolveUserConfig = (\n condition: \"react-client\" | \"react-server\",\n input: InputOption,\n config: UserConfig,\n configEnv: ConfigEnv,\n userOptions: ResolvedUserOptions\n):\n | { type: \"error\"; error: Error }\n | {\n type: \"success\";\n userConfig: ResolvedUserConfig;\n } => {\n const isReactServer = condition === \"react-server\";\n const isViteServer = configEnv.command === \"serve\";\n const isVitePreview = configEnv.isPreview;\n\n if (isReactServer && configEnv.command === \"build\") {\n if (!config.build?.rollupOptions?.input) {\n config = {\n ...config,\n build: {\n ...config.build,\n rollupOptions: {\n ...config.build?.rollupOptions,\n input: input,\n },\n },\n };\n }\n }\n\n if (\n typeof config.build?.assetsDir === \"string\" &&\n userOptions.assetsDir !== config.build?.assetsDir\n ) {\n return {\n type: \"error\",\n error: new Error(\n `assetsDir cannot be changed after the config has been resolved, before: ${userOptions.assetsDir}, after: ${config.build?.assetsDir}`\n ),\n };\n }\n\n if (isReactServer) {\n if (configEnv.command === \"build\") {\n if (!configEnv.isSsrBuild) {\n return {\n type: \"error\",\n error: new Error(\n \"ssr must be true when using the server plugin, NODE_OPTIONS='--conditions react-server' vite build --ssr\"\n ),\n };\n }\n } else if (!isViteServer) {\n return {\n type: \"error\",\n error: new Error(\n isViteServer\n ? `react-server condition was not set. Please use \\`NODE_OPTIONS='--conditions react-server' vite${\n isVitePreview ? \" preview\" : \"\"\n }\\``\n : \"react-server condition was not set. Please use `NODE_OPTIONS='--conditions react-server' vite build --ssr`\"\n ),\n };\n } else if (!configEnv.isSsrBuild && configEnv.command !== \"serve\") {\n return {\n type: \"error\",\n error: new Error(\n \"Vite was run with the react-server condition, but is making a client build.\"\n ),\n };\n }\n }\n\n const { root: configRoot, mode: configMode, ...configRest } = config;\n const {\n outDir: configOutDir,\n assetsDir: configAssetsDir,\n ssr: configSsr,\n manifest: configManifest,\n ssrManifest: configSsrManifest,\n ssrEmitAssets: configSsrEmitAssets,\n target: configTarget,\n ...configBuildRest\n } = config.build ?? {};\n\n return {\n type: \"success\",\n userConfig: {\n ...configRest,\n root: configRoot ?? userOptions.projectRoot ?? process.cwd(),\n mode: configMode ?? process.env[\"NODE_ENV\"] ?? \"production\",\n build: {\n ...configBuildRest,\n ssr: configSsr ?? isReactServer,\n manifest: configManifest ?? true,\n ssrManifest: configSsrManifest ?? true,\n ssrEmitAssets: configSsrEmitAssets ?? true,\n target: configTarget ?? \"es2020\",\n outDir:\n typeof configOutDir === \"string\"\n ? configOutDir\n : isReactServer\n ? userOptions.build.server\n : userOptions.build.client,\n assetsDir:\n typeof configAssetsDir === \"string\"\n ? configAssetsDir\n : isReactServer\n ? \"\"\n : DEFAULT_CONFIG.CLIENT_ASSETS_DIR,\n },\n },\n };\n};\n\nexport const resolveOptions = (\n options: StreamPluginOptions\n):\n | {\n type: \"success\";\n userOptions: ResolvedUserOptions;\n }\n | {\n type: \"error\";\n error: Error;\n } => {\n const {\n workerPath: optionsWorkerPath,\n loaderPath: optionsLoaderPath,\n projectRoot: optionsProjectRoot,\n moduleBase: optionsModuleBase,\n moduleBasePath: optionsModuleBasePath,\n moduleBaseURL: optionsModuleBaseURL,\n build: optionsBuild,\n Page: optionsPage,\n props: optionsProps,\n Html: optionsHtml,\n pageExportName: optionsPageExportName,\n propsExportName: optionsPropsExportName,\n collectCss: optionsCollectCss,\n collectAssets: optionsCollectAssets,\n assetsDir: optionsAssetsDir,\n clientEntry: optionsClientEntry,\n serverOutDir: optionsServerOutDir,\n clientOutDir: optionsClientOutDir,\n autoDiscover: optionsAutoDiscover,\n moduleBaseExceptions: optionsModuleBaseExceptions,\n ...restOptions\n } = options;\n const projectRoot = optionsProjectRoot ?? process.cwd();\n /** the module base can be assumed to not have a leading slash */\n const moduleBase =\n typeof optionsModuleBase === \"string\"\n ? optionsModuleBase.startsWith(path.sep)\n ? optionsModuleBase.slice(path.sep.length)\n : optionsModuleBase\n : DEFAULT_CONFIG.MODULE_BASE;\n\n if (\n typeof optionsModuleBase === \"string\" &&\n optionsModuleBase !== moduleBase\n ) {\n return {\n type: \"error\",\n error: new Error(\n `moduleBase ${optionsModuleBase} is invalid, should be like ${moduleBase}`\n ),\n };\n }\n\n const moduleBasePath =\n typeof optionsModuleBasePath === \"string\"\n ? !optionsModuleBasePath.startsWith(path.sep)\n ? `${path.sep}${optionsModuleBasePath}`\n : optionsModuleBasePath\n : `${path.sep}${moduleBase}`;\n\n if (!moduleBasePath.includes(moduleBase)) {\n return {\n type: \"error\",\n error: new Error(\n `moduleBasePath ${moduleBasePath} is invalid, should include moduleBase ${moduleBase}`\n ),\n };\n }\n\n const moduleBaseURL =\n typeof optionsModuleBaseURL === \"string\"\n ? !optionsModuleBaseURL.endsWith(moduleBasePath)\n ? path.join(optionsModuleBaseURL, moduleBasePath)\n : optionsModuleBaseURL\n : moduleBasePath;\n\n if (!moduleBaseURL.includes(moduleBasePath)) {\n return {\n type: \"error\",\n error: new Error(\n `moduleBaseURL ${moduleBaseURL} is invalid, should include moduleBasePath ${moduleBasePath}`\n ),\n };\n }\n\n if (\n typeof optionsModuleBaseURL === \"string\" &&\n optionsModuleBaseURL !== moduleBaseURL\n ) {\n return {\n type: \"error\",\n error: new Error(\n `moduleBaseURL ${optionsModuleBaseURL} is invalid, should be like ${moduleBaseURL}`\n ),\n };\n }\n\n const build = optionsBuild\n ? {\n client: optionsBuild.client ?? DEFAULT_CONFIG.BUILD.client,\n pages: optionsBuild.pages ?? DEFAULT_CONFIG.BUILD.pages,\n server: optionsBuild.server ?? DEFAULT_CONFIG.BUILD.server,\n }\n : DEFAULT_CONFIG.BUILD;\n\n const autoDiscover =\n typeof optionsAutoDiscover === \"object\"\n ? {\n pagePattern:\n typeof optionsAutoDiscover.pagePattern === \"string\"\n ? optionsAutoDiscover.pagePattern\n : DEFAULT_CONFIG.AUTO_DISCOVER.pagePattern,\n propsPattern:\n typeof optionsAutoDiscover.propsPattern === \"string\"\n ? optionsAutoDiscover.propsPattern\n : DEFAULT_CONFIG.AUTO_DISCOVER.propsPattern,\n }\n : DEFAULT_CONFIG.AUTO_DISCOVER;\n\n const workerPath = typeof optionsWorkerPath === \"string\" ? optionsWorkerPath : DEFAULT_CONFIG.WORKER_PATH;\n const loaderPath = typeof optionsLoaderPath === \"string\" ? optionsLoaderPath : DEFAULT_CONFIG.LOADER_PATH;\n return {\n type: \"success\",\n userOptions: {\n ...DEFAULT_CONFIG,\n ...restOptions,\n moduleBase,\n moduleBasePath,\n moduleBaseURL,\n build,\n Page: optionsPage ?? DEFAULT_CONFIG.PAGE,\n props: optionsProps ?? DEFAULT_CONFIG.PROPS,\n Html: optionsHtml ?? DEFAULT_CONFIG.HTML,\n pageExportName: optionsPageExportName ?? DEFAULT_CONFIG.PAGE_EXPORT,\n propsExportName: optionsPropsExportName ?? DEFAULT_CONFIG.PROPS_EXPORT,\n collectCss: optionsCollectCss ?? DEFAULT_CONFIG.COLLECT_CSS,\n collectAssets: optionsCollectAssets ?? DEFAULT_CONFIG.COLLECT_ASSETS,\n projectRoot: projectRoot,\n assetsDir: optionsAssetsDir ?? DEFAULT_CONFIG.CLIENT_ASSETS_DIR,\n workerPath: workerPath,\n loaderPath: loaderPath,\n clientEntry: optionsClientEntry ?? DEFAULT_CONFIG.CLIENT_ENTRY,\n serverOutDir: optionsServerOutDir ?? DEFAULT_CONFIG.BUILD.server,\n clientOutDir: optionsClientOutDir ?? DEFAULT_CONFIG.BUILD.client,\n autoDiscover: autoDiscover,\n moduleBaseExceptions: [\n workerPath,\n loaderPath,\n ...(optionsModuleBaseExceptions ?? []),\n ],\n } satisfies ResolvedUserOptions,\n };\n};\n\nexport async function resolvePages(\n pages: ResolvedUserOptions[\"build\"][\"pages\"]\n): Promise<\n | {\n type: \"success\";\n pages: string[];\n }\n | {\n type: \"error\";\n error: Error;\n }\n> {\n if (!pages) {\n return {\n type: \"success\",\n pages: [],\n };\n }\n if (typeof pages === \"function\") {\n try {\n return resolvePages(await Promise.resolve(pages()));\n } catch (error) {\n return {\n type: \"error\",\n error:\n error instanceof Error\n ? error\n : new Error(\n `build.pages must be a array of strings, or a (async) function that returns a string or an array of strings. Got \"${JSON.stringify(\n pages\n )}\"`,\n {\n cause: error,\n }\n ),\n };\n }\n }\n try {\n const result = pages;\n const awaited = \"then\" in result ? await result : result;\n if (typeof awaited === \"string\") {\n return {\n type: \"success\",\n pages: [awaited],\n };\n }\n if (Array.isArray(awaited)) {\n if (awaited.every((page) => typeof page === \"string\")) {\n return {\n type: \"success\",\n pages: awaited,\n };\n } else {\n return {\n type: \"error\",\n error: new Error(\n `build.pages must be a array of strings, or a (async) function that returns a string or an array of strings. Got \"${JSON.stringify(\n awaited.find((page) => typeof page !== \"string\")\n )}\"`,\n {\n cause: awaited,\n }\n ),\n };\n }\n }\n return {\n type: \"error\",\n error: new Error(\n `build.pages must be a array of strings, or a (async) function that returns a string or an array of strings. Got \"${JSON.stringify(\n pages\n )}\"`,\n {\n cause: pages,\n }\n ),\n };\n } catch (error) {\n return {\n type: \"error\",\n error:\n error instanceof Error\n ? error\n : new Error(\n `build.pages must be a array of strings, or a (async) function that returns a string or an array of strings. Got \"${JSON.stringify(\n error\n )}\"`,\n {\n cause: error,\n }\n ),\n };\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHandler.js","sources":["../../../src/react-server/createHandler.ts"],"sourcesContent":["import { createLogger } from \"vite\";\nimport {\n collectManifestCss,\n collectModuleGraphCss,\n} from \"../collect-css-manifest.js\";\nimport { DEFAULT_CONFIG } from \"../options.js\";\nimport { resolvePage } from \"../resolvePage.js\";\nimport { resolveProps } from \"../resolveProps.js\";\nimport type { CreateHandlerOptions, StreamPluginOptions } from \"../types.js\";\nimport { createRscStream } from \"./createRscStream.js\";\n\nexport async function createHandler<T>(\n url: string,\n pluginOptions: Pick<\n StreamPluginOptions,\n \"Page\" | \"props\" | \"build\" | \"Html\" | \"pageExportName\" | \"propsExportName\"\n > &\n Required<\n Pick<StreamPluginOptions, \"moduleBase\" | \"moduleBasePath\" | \"projectRoot\">\n >,\n streamOptions: CreateHandlerOptions<T>\n) {\n const root = pluginOptions.projectRoot ?? process.cwd();\n\n const Html = pluginOptions.Html ?? DEFAULT_CONFIG.HTML;\n const pageExportName =\n pluginOptions.pageExportName ?? DEFAULT_CONFIG.PAGE_EXPORT;\n const propsExportName =\n pluginOptions.propsExportName ?? DEFAULT_CONFIG.PROPS_EXPORT;\n const controller = new AbortController();\n\n const cssFiles = streamOptions.cssFiles;\n const propsPath =\n typeof pluginOptions.props === \"function\"\n ? pluginOptions.props(url)\n : pluginOptions.props;\n const pagePath =\n typeof pluginOptions.Page === \"function\"\n ? pluginOptions.Page(url)\n : pluginOptions.Page;\n\n const cssModules = new Set<string>();\n\n if (!(streamOptions.manifest || streamOptions.moduleGraph))\n throw new Error(\"Missing manifest or moduleGraph, pass it to options.\");\n\n const getCss = streamOptions.manifest\n ? (id: string) =>\n collectManifestCss(\n streamOptions.manifest!,\n root,\n id,\n streamOptions.onCssFile\n )\n : (id: string) => collectModuleGraphCss(streamOptions.moduleGraph!, id);\n\n const loadWithCss = async (id: string) => {\n if (!id) return {};\n\n try {\n const mod = await streamOptions.loader(id);\n const pageCss = await Promise.resolve(getCss(id));\n Array.from(pageCss.keys()).forEach((css) => cssModules.add(css));\n return mod as Record<string, any>;\n } catch (e: any) {\n if (e.message?.includes(\"module runner has been closed\")) {\n return { type: \"skip\" } as Record<string, any>;\n } else {\n return { type: \"error\", error: e } as Record<string, any>;\n }\n }\n };\n\n const PropsModule = await resolveProps({\n propsModule: await loadWithCss(propsPath ?? pagePath),\n path: String(propsPath ?? pagePath),\n exportName: propsExportName,\n url,\n });\n if (PropsModule.type === \"error\")\n return { type: PropsModule.type, error: PropsModule?.error };\n if (PropsModule.type === \"skip\") return { type: PropsModule.type };\n const props = PropsModule[propsExportName as keyof typeof PropsModule] as any;\n if (props?.type === \"error\") return { type: props.type, error: props.error };\n if (props?.type === \"skip\") return { type: props.type };\n\n const PageModule = await resolvePage({\n pageModule: await loadWithCss(pagePath),\n path: pagePath,\n exportName: pageExportName,\n url,\n });\n if (PageModule.type === \"error\")\n return { type: PageModule.type, error: PageModule.error };\n if (PageModule.type === \"skip\") return { type: PageModule.type };\n const Page = PageModule[pageExportName as keyof typeof PageModule] as any;\n if (Page?.type === \"error\") return { type: Page.type, error: Page.error };\n if (Page?.type === \"skip\") return { type: Page.type };\n if (!(typeof Page === \"function\")) {\n return {\n type: \"error\",\n error: new Error(\"Invalid Page component: \" + pagePath, {\n cause: Page,\n }),\n };\n }\n if (!(typeof props === \"object\")) {\n return {\n type: \"error\",\n error: new Error(\"Invalid props: \" + propsPath, {\n cause: props,\n }),\n };\n }\n\n // Add any additional CSS files\n if (streamOptions.cssFiles) {\n streamOptions.cssFiles.forEach((css) => cssModules.add(css));\n }\n const stream = createRscStream({\n Html: Html,\n Page: Page,\n props: props,\n moduleBasePath: pluginOptions.moduleBasePath, // eg /src\n logger: streamOptions.logger ?? createLogger(),\n cssFiles: Array.from(cssModules),\n route: url,\n url,\n pipableStreamOptions: streamOptions.pipableStreamOptions,\n });\n\n if (!stream) {\n return { type: \"skip\" as const };\n }\n\n return {\n type: \"success\" as const,\n controller,\n stream,\n assets: {\n css: cssFiles,\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createRscStream.js","sources":["../../../src/react-server/createRscStream.ts"],"sourcesContent":["import React from \"react\";\nimport {\n renderToPipeableStream,\n type PipeableStream,\n} from \"react-server-dom-esm/server.node\";\nimport { CssCollector } from \"../components.js\";\nimport type { RscStreamOptions } from \"../types.js\";\n\nexport function createRscStream(\n streamOptions: RscStreamOptions\n): PipeableStream {\n const {\n Html,\n Page,\n props,\n logger,\n cssFiles,\n route,\n url,\n moduleBasePath,\n pipableStreamOptions,\n } = streamOptions;\n const css = Array.isArray(cssFiles)\n ? cssFiles.map((css, index) =>\n React.createElement(CssCollector, {\n key: `css-${index}`,\n url: css,\n })\n )\n : [];\n return renderToPipeableStream(\n React.createElement(\n Html,\n {\n key: \"html\",\n pageProps: props,\n moduleBasePath: moduleBasePath,\n route,\n url,\n },\n React.createElement(Page, { key: \"page\", ...props }),\n ...css\n ),\n moduleBasePath,\n {\n onError: logger?.error ?? console.error,\n onPostpone: logger?.info ?? console.info,\n environmentName: \"Server\",\n ...pipableStreamOptions,\n }\n );\n}\n"],"names":["css"],"mappings":";;;AAQO,SAAS,gBACd,eACgB;AACV,QAAA;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AACJ,QAAM,MAAM,MAAM,QAAQ,QAAQ,IAC9B,SAAS;AAAA,IAAI,CAACA,MAAK,UACjB,MAAM,cAAc,cAAc;AAAA,MAChC,KAAK,OAAO,KAAK;AAAA,MACjB,KAAKA;AAAAA,IACN,CAAA;AAAA,EAAA,IAEH,CAAC;AACE,SAAA;AAAA,IACL,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAM,cAAc,MAAM,EAAE,KAAK,QAAQ,GAAG,OAAO;AAAA,MACnD,GAAG;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS,QAAQ,SAAS,QAAQ;AAAA,MAClC,YAAY,QAAQ,QAAQ,QAAQ;AAAA,MACpC,iBAAiB;AAAA,MACjB,GAAG;AAAA,IAAA;AAAA,EAEP;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvePage.js","sources":["../../src/resolvePage.ts"],"sourcesContent":["type ResolvePageOptions = {\n pageModule: Record<string, any>;\n path: string;\n url: string;\n exportName: string;\n};\n\ntype ResolvePageResult =\n | { type: \"success\"; key: string; Page: any }\n | { type: \"error\"; error: Error }\n | { type: \"skip\" };\n\nexport async function resolvePage({\n pageModule,\n path,\n url,\n exportName,\n}: ResolvePageOptions): Promise<ResolvePageResult> {\n if (!pageModule) {\n return {\n type: \"error\",\n error: new Error(`pageModule is ${typeof pageModule}`),\n };\n }\n const keys =\n typeof pageModule === \"object\" && pageModule != null\n ? Object.keys(pageModule)\n : [];\n const found = keys.find((v) => v === exportName || v === url || v === path);\n if (found) {\n if (typeof pageModule[found] === \"function\") {\n return {\n type: \"success\",\n key: found,\n Page: pageModule[found],\n };\n } else {\n if (\n typeof pageModule === \"object\" &&\n pageModule != null &&\n Object.keys(pageModule).includes(\"type\")\n )\n return pageModule as ResolvePageResult;\n return {\n type: \"error\",\n [exportName]: () => found,\n error: pageModule[found][\"error\"],\n };\n }\n }\n if (keys.includes(\"type\")) return pageModule as ResolvePageResult;\n return {\n type: \"error\",\n error: new Error(\n `Could not find Page export \"${exportName}\" in \"${path}\". ${\n typeof pageModule === \"object\" && pageModule != null\n ? keys.length\n ? \"Available exports: \" + keys.join(\", \")\n : \"The object was defined but has no properties.\"\n : \"typeof pageModule =\" + typeof pageModule\n }`,\n { cause: pageModule }\n ),\n };\n}\n"],"names":[],"mappings":"AAYA,eAAsB,YAAY;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmD;AACjD,MAAI,CAAC,YAAY;AACR,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI,MAAM,iBAAiB,OAAO,UAAU,EAAE;AAAA,IACvD;AAAA,EAAA;AAEI,QAAA,OACJ,OAAO,eAAe,YAAY,cAAc,OAC5C,OAAO,KAAK,UAAU,IACtB,CAAC;AACD,QAAA,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM,IAAI;AAC1E,MAAI,OAAO;AACT,QAAI,OAAO,WAAW,KAAK,MAAM,YAAY;AACpC,aAAA;AAAA,QACL,MAAM;AAAA,QACN,KAAK;AAAA,QACL,MAAM,WAAW,KAAK;AAAA,MACxB;AAAA,IAAA,OACK;AAEH,UAAA,OAAO,eAAe,YACtB,cAAc,QACd,OAAO,KAAK,UAAU,EAAE,SAAS,MAAM;AAEhC,eAAA;AACF,aAAA;AAAA,QACL,MAAM;AAAA,QACN,CAAC,UAAU,GAAG,MAAM;AAAA,QACpB,OAAO,WAAW,KAAK,EAAE,OAAO;AAAA,MAClC;AAAA,IAAA;AAAA,EACF;AAEF,MAAI,KAAK,SAAS,MAAM,EAAU,QAAA;AAC3B,SAAA;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,MACT,+BAA+B,UAAU,SAAS,IAAI,MACpD,OAAO,eAAe,YAAY,cAAc,OAC5C,KAAK,SACH,wBAAwB,KAAK,KAAK,IAAI,IACtC,kDACF,wBAAwB,OAAO,UACrC;AAAA,MACA,EAAE,OAAO,WAAW;AAAA,IAAA;AAAA,EAExB;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveProps.js","sources":["../../src/resolveProps.ts"],"sourcesContent":["type ResolvePropsOptions = {\n propsModule: Record<string, any>;\n path: string;\n exportName: string;\n url: string;\n};\n\ntype ResolvePropsResult =\n | { type: \"success\"; key: string; props: any }\n | { type: \"error\"; error: Error }\n | { type: \"skip\" };\n\nfunction isFunction(value: any) {\n return typeof value === \"function\";\n}\n\nexport async function resolveProps({\n propsModule,\n path,\n exportName,\n url,\n}: ResolvePropsOptions): Promise<ResolvePropsResult> {\n if (!propsModule) {\n return {\n type: \"error\",\n error: new Error(`propsModule is ${typeof propsModule}`),\n };\n }\n\n if (typeof propsModule !== \"object\") {\n return {\n type: \"error\",\n error: new Error(\n `propsModule must be an object, got ${typeof propsModule}`\n ),\n };\n }\n\n const keys = Object.keys(propsModule);\n const found = keys.find((v) => v === exportName || v === url || v === path);\n if (found) {\n const value = propsModule[found];\n\n try {\n // If it's a function, call it with the URL\n if (isFunction(value)) {\n const props = await value(url);\n return {\n type: \"success\",\n key: found,\n props,\n };\n }\n\n // If it's a promise, await it\n if (value && typeof value.then === \"function\") {\n const props = await value;\n return {\n type: \"success\",\n key: found,\n props,\n };\n }\n\n // If it's a plain object, use it directly\n if (typeof value === \"object\" && value !== null) {\n return {\n type: \"success\",\n key: found,\n props: value,\n };\n }\n\n console.warn(found, \"error in resolveProps\", propsModule, url, path);\n return {\n type: \"error\",\n error: new Error(\n `Expected props export \"${exportName}\" in \"${path}\" to be a function, promise, or object that resolves to props, instead got typeof ${typeof value}.`\n ),\n };\n } catch (error) {\n console.warn(found, \"error in resolveProps\", propsModule, url, path);\n return {\n type: \"error\",\n error: error as Error,\n };\n }\n }\n const commonjs = keys.find((v) => v === \"exports\");\n\n if (!!commonjs) {\n const exportKeys = (commonjs as unknown as { exports: any })[\"exports\"]\n ? Object.keys((commonjs as unknown as { exports: any })[\"exports\"])\n : [];\n const foundCommonJS = exportKeys.find(\n (v) => v === exportName || v === url || v === path\n );\n return {\n type: \"error\",\n error: new Error(\n `Expected props export \"${exportName}\" in \"${path}\", but instead got \"exports\" with ${\n !!foundCommonJS\n ? foundCommonJS.toString()\n : exportKeys.length\n ? exportKeys.join(\", \")\n : \"no keys\"\n }, this will not work. Make sure to set esModule: true in rollupOptions.output`\n ),\n };\n }\n\n return {\n type: \"error\",\n error: new Error(\n `Could not find props export \"${exportName}\" in \"${path}\". ${\n keys.length\n ? \"Available exports: \" + keys.join(\", \")\n : \"The object was defined but has no properties.\"\n }`\n ),\n };\n}\n"],"names":[],"mappings":"AAYA,SAAS,WAAW,OAAY;AAC9B,SAAO,OAAO,UAAU;AAC1B;AAEA,eAAsB,aAAa;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqD;AACnD,MAAI,CAAC,aAAa;AACT,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI,MAAM,kBAAkB,OAAO,WAAW,EAAE;AAAA,IACzD;AAAA,EAAA;AAGE,MAAA,OAAO,gBAAgB,UAAU;AAC5B,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,QACT,sCAAsC,OAAO,WAAW;AAAA,MAAA;AAAA,IAE5D;AAAA,EAAA;AAGI,QAAA,OAAO,OAAO,KAAK,WAAW;AAC9B,QAAA,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM,IAAI;AAC1E,MAAI,OAAO;AACH,UAAA,QAAQ,YAAY,KAAK;AAE3B,QAAA;AAEE,UAAA,WAAW,KAAK,GAAG;AACf,cAAA,QAAQ,MAAM,MAAM,GAAG;AACtB,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MAAA;AAIF,UAAI,SAAS,OAAO,MAAM,SAAS,YAAY;AAC7C,cAAM,QAAQ,MAAM;AACb,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MAAA;AAIF,UAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AACxC,eAAA;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,UACL,OAAO;AAAA,QACT;AAAA,MAAA;AAGF,cAAQ,KAAK,OAAO,yBAAyB,aAAa,KAAK,IAAI;AAC5D,aAAA;AAAA,QACL,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,UACT,0BAA0B,UAAU,SAAS,IAAI,qFAAqF,OAAO,KAAK;AAAA,QAAA;AAAA,MAEtJ;AAAA,aACO,OAAO;AACd,cAAQ,KAAK,OAAO,yBAAyB,aAAa,KAAK,IAAI;AAC5D,aAAA;AAAA,QACL,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AAEF,QAAM,WAAW,KAAK,KAAK,CAAC,MAAM,MAAM,SAAS;AAE7C,MAAA,CAAC,CAAC,UAAU;AACR,UAAA,aAAc,SAAyC,SAAS,IAClE,OAAO,KAAM,SAAyC,SAAS,CAAC,IAChE,CAAC;AACL,UAAM,gBAAgB,WAAW;AAAA,MAC/B,CAAC,MAAM,MAAM,cAAc,MAAM,OAAO,MAAM;AAAA,IAChD;AACO,WAAA;AAAA,MACL,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,QACT,0BAA0B,UAAU,SAAS,IAAI,qCAC/C,CAAC,CAAC,gBACE,cAAc,aACd,WAAW,SACX,WAAW,KAAK,IAAI,IACpB,SACN;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,MACT,gCAAgC,UAAU,SAAS,IAAI,MACrD,KAAK,SACD,wBAAwB,KAAK,KAAK,IAAI,IACtC,+CACN;AAAA,IAAA;AAAA,EAEJ;AACF;"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createWriteStream } from "node:fs";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
import { parentPort } from "node:worker_threads";
|
|
4
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
5
|
+
import { createFromNodeStream } from "react-server-dom-esm/client.node";
|
|
6
|
+
const concatter = (chunk) => {
|
|
7
|
+
if (Array.isArray(chunk)) {
|
|
8
|
+
return Buffer.from(chunk);
|
|
9
|
+
}
|
|
10
|
+
return Buffer.from(chunk);
|
|
11
|
+
};
|
|
12
|
+
function createHtmlStream(renderState, writeStream) {
|
|
13
|
+
const outputPath = renderState.htmlOutputPath;
|
|
14
|
+
const rscStream = Readable.from(renderState.chunks.map(concatter));
|
|
15
|
+
const reactElements = createFromNodeStream(
|
|
16
|
+
rscStream,
|
|
17
|
+
renderState.moduleBasePath,
|
|
18
|
+
renderState.moduleBaseURL
|
|
19
|
+
);
|
|
20
|
+
const rscOutputPath = renderState.htmlOutputPath.endsWith(".html") ? renderState.htmlOutputPath.slice(0, -5) + ".rsc" : renderState.htmlOutputPath.endsWith("/") ? renderState.htmlOutputPath + "index.rsc" : renderState.htmlOutputPath.endsWith(".") ? renderState.htmlOutputPath + "rsc" : renderState.htmlOutputPath + ".rsc";
|
|
21
|
+
const writeRscEntry = createWriteStream(rscOutputPath);
|
|
22
|
+
rscStream.on("data", (chunk) => {
|
|
23
|
+
writeRscEntry.write(chunk);
|
|
24
|
+
});
|
|
25
|
+
rscStream.on("end", () => {
|
|
26
|
+
writeRscEntry.end();
|
|
27
|
+
});
|
|
28
|
+
const stream = renderToPipeableStream(reactElements, {
|
|
29
|
+
...renderState.pipableStreamOptions,
|
|
30
|
+
onAllReady() {
|
|
31
|
+
writeStream.on("finish", () => {
|
|
32
|
+
parentPort?.postMessage({
|
|
33
|
+
type: "HTML",
|
|
34
|
+
outputPath,
|
|
35
|
+
route: renderState.id
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
writeStream.on("error", (error) => {
|
|
39
|
+
console.error("[Worker] Write error at", error);
|
|
40
|
+
stream.abort();
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
onShellReady() {
|
|
44
|
+
stream.pipe(writeStream);
|
|
45
|
+
},
|
|
46
|
+
onError(error) {
|
|
47
|
+
console.error("[Worker] Render error at", error);
|
|
48
|
+
stream.abort();
|
|
49
|
+
writeStream.destroy();
|
|
50
|
+
},
|
|
51
|
+
onShellError(error) {
|
|
52
|
+
console.error("[Worker] Shell error at", error);
|
|
53
|
+
stream.abort();
|
|
54
|
+
writeStream.destroy();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return { stream, writeStream };
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
createHtmlStream
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=createHtmlStream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHtmlStream.js","sources":["../../../src/worker/createHtmlStream.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\nimport { Readable, Writable } from \"node:stream\";\nimport { parentPort } from \"node:worker_threads\";\nimport { renderToPipeableStream } from \"react-dom/server\";\nimport { createFromNodeStream } from \"react-server-dom-esm/client.node\";\nimport type { RenderState } from \"./types.js\";\n\nconst concatter = (chunk: string) => {\n if (Array.isArray(chunk)) {\n return Buffer.from(chunk);\n }\n return Buffer.from(chunk);\n};\n\nexport function createHtmlStream(\n renderState: RenderState,\n writeStream: Writable\n) {\n const outputPath = renderState.htmlOutputPath;\n\n // Create readable stream from RSC content\n const rscStream = Readable.from(renderState.chunks.map(concatter));\n\n // Create RSC node stream\n const reactElements = createFromNodeStream(\n rscStream,\n renderState.moduleBasePath,\n renderState.moduleBaseURL\n );\n // rsc file destination follows the same path as the html file, but with a .rsc extension\n const rscOutputPath = renderState.htmlOutputPath.endsWith(\".html\")\n ? renderState.htmlOutputPath.slice(0, -5) + \".rsc\"\n : renderState.htmlOutputPath.endsWith(\"/\")\n ? renderState.htmlOutputPath + \"index.rsc\"\n : renderState.htmlOutputPath.endsWith(\".\")\n ? renderState.htmlOutputPath + \"rsc\"\n : renderState.htmlOutputPath + \".rsc\";\n\n const writeRscEntry = createWriteStream(rscOutputPath);\n rscStream.on(\"data\", (chunk) => {\n writeRscEntry.write(chunk);\n });\n rscStream.on(\"end\", () => {\n writeRscEntry.end();\n });\n const stream = renderToPipeableStream(reactElements as React.ReactNode, {\n ...renderState.pipableStreamOptions,\n onAllReady() {\n writeStream.on(\"finish\", () => {\n parentPort?.postMessage({\n type: \"HTML\",\n outputPath,\n route: renderState.id,\n });\n });\n writeStream.on(\"error\", (error) => {\n console.error(\"[Worker] Write error at\", error);\n stream.abort();\n });\n },\n onShellReady() {\n stream.pipe(writeStream);\n },\n onError(error) {\n console.error(\"[Worker] Render error at\", error);\n stream.abort();\n writeStream.destroy();\n },\n onShellError(error) {\n console.error(\"[Worker] Shell error at\", error);\n stream.abort();\n writeStream.destroy();\n },\n });\n return { stream, writeStream };\n}\n"],"names":[],"mappings":";;;;;AAOA,MAAM,YAAY,CAAC,UAAkB;AAC/B,MAAA,MAAM,QAAQ,KAAK,GAAG;AACjB,WAAA,OAAO,KAAK,KAAK;AAAA,EAAA;AAEnB,SAAA,OAAO,KAAK,KAAK;AAC1B;AAEgB,SAAA,iBACd,aACA,aACA;AACA,QAAM,aAAa,YAAY;AAG/B,QAAM,YAAY,SAAS,KAAK,YAAY,OAAO,IAAI,SAAS,CAAC;AAGjE,QAAM,gBAAgB;AAAA,IACpB;AAAA,IACA,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAEA,QAAM,gBAAgB,YAAY,eAAe,SAAS,OAAO,IAC7D,YAAY,eAAe,MAAM,GAAG,EAAE,IAAI,SAC1C,YAAY,eAAe,SAAS,GAAG,IACvC,YAAY,iBAAiB,cAC7B,YAAY,eAAe,SAAS,GAAG,IACvC,YAAY,iBAAiB,QAC7B,YAAY,iBAAiB;AAE3B,QAAA,gBAAgB,kBAAkB,aAAa;AAC3C,YAAA,GAAG,QAAQ,CAAC,UAAU;AAC9B,kBAAc,MAAM,KAAK;AAAA,EAAA,CAC1B;AACS,YAAA,GAAG,OAAO,MAAM;AACxB,kBAAc,IAAI;AAAA,EAAA,CACnB;AACK,QAAA,SAAS,uBAAuB,eAAkC;AAAA,IACtE,GAAG,YAAY;AAAA,IACf,aAAa;AACC,kBAAA,GAAG,UAAU,MAAM;AAC7B,oBAAY,YAAY;AAAA,UACtB,MAAM;AAAA,UACN;AAAA,UACA,OAAO,YAAY;AAAA,QAAA,CACpB;AAAA,MAAA,CACF;AACW,kBAAA,GAAG,SAAS,CAAC,UAAU;AACzB,gBAAA,MAAM,2BAA2B,KAAK;AAC9C,eAAO,MAAM;AAAA,MAAA,CACd;AAAA,IACH;AAAA,IACA,eAAe;AACb,aAAO,KAAK,WAAW;AAAA,IACzB;AAAA,IACA,QAAQ,OAAO;AACL,cAAA,MAAM,4BAA4B,KAAK;AAC/C,aAAO,MAAM;AACb,kBAAY,QAAQ;AAAA,IACtB;AAAA,IACA,aAAa,OAAO;AACV,cAAA,MAAM,2BAA2B,KAAK;AAC9C,aAAO,MAAM;AACb,kBAAY,QAAQ;AAAA,IAAA;AAAA,EACtB,CACD;AACM,SAAA,EAAE,QAAQ,YAAY;AAC/B;"}
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "node:path";
|
|
2
2
|
import { Worker } from "node:worker_threads";
|
|
3
|
-
async function createWorker(
|
|
3
|
+
async function createWorker(options) {
|
|
4
|
+
const { workerPath, nodePath, mode, workerOptions } = options;
|
|
4
5
|
console.log("[Worker] Creating worker...");
|
|
5
|
-
const workerPath = resolve(projectRoot, outDir, fileName);
|
|
6
6
|
console.log("[Worker] Worker path:", workerPath);
|
|
7
7
|
try {
|
|
8
8
|
const worker = new Worker(workerPath, {
|
|
9
9
|
env: {
|
|
10
10
|
NODE_OPTIONS: "",
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
11
|
+
NODE_ENV: mode,
|
|
12
|
+
NODE_PATH: nodePath
|
|
13
|
+
},
|
|
14
|
+
...workerOptions
|
|
14
15
|
});
|
|
15
16
|
worker.setMaxListeners(1e3);
|
|
16
|
-
await new Promise((
|
|
17
|
+
await new Promise((resolve, reject) => {
|
|
17
18
|
worker.once("message", (message) => {
|
|
18
19
|
if (message.type === "READY") {
|
|
19
|
-
|
|
20
|
+
resolve();
|
|
20
21
|
}
|
|
21
22
|
});
|
|
22
23
|
worker.once("error", reject);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createWorker.js","sources":["../../../src/worker/createWorker.ts"],"sourcesContent":["import { join } from \"node:path\";\nimport { Worker } from \"node:worker_threads\";\n\ntype CreateWorkerOptions = {\n workerPath: string;\n nodePath: string;\n mode: \"production\" | \"development\";\n workerOptions?: WorkerOptions;\n};\n\nexport async function createWorker(\n options: CreateWorkerOptions\n) {\n const { workerPath, nodePath, mode, workerOptions } = options;\n console.log(\"[Worker] Creating worker...\");\n console.log(\"[Worker] Worker path:\", workerPath);\n\n try {\n const worker = new Worker(workerPath, {\n env: {\n NODE_OPTIONS: \"\",\n NODE_ENV: mode,\n NODE_PATH: nodePath,\n },\n ...workerOptions,\n });\n worker.setMaxListeners(1000);\n\n // Wait for worker to be ready\n await new Promise<void>((resolve, reject) => {\n worker.once(\"message\", (message) => {\n if (message.type === \"READY\") {\n resolve();\n }\n });\n worker.once(\"error\", reject);\n });\n\n return worker;\n } catch (error) {\n console.error(\"[Worker] Startup error:\", error);\n throw error;\n }\n}\n"],"names":[],"mappings":";;AAUA,eAAsB,aACpB,SACA;AACA,QAAM,EAAE,YAAY,UAAU,MAAM,cAAkB,IAAA;AACtD,UAAQ,IAAI,6BAA6B;AACjC,UAAA,IAAI,yBAAyB,UAAU;AAE3C,MAAA;AACI,UAAA,SAAS,IAAI,OAAO,YAAY;AAAA,MACpC,KAAK;AAAA,QACH,cAAc;AAAA,QACd,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MACA,GAAG;AAAA,IAAA,CACJ;AACD,WAAO,gBAAgB,GAAI;AAG3B,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AACpC,aAAA,KAAK,WAAW,CAAC,YAAY;AAC9B,YAAA,QAAQ,SAAS,SAAS;AACpB,kBAAA;AAAA,QAAA;AAAA,MACV,CACD;AACM,aAAA,KAAK,SAAS,MAAM;AAAA,IAAA,CAC5B;AAEM,WAAA;AAAA,WACA,OAAO;AACN,YAAA,MAAM,2BAA2B,KAAK;AACxC,UAAA;AAAA,EAAA;AAEV;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderPages.js","sources":["../../../src/worker/renderPages.ts"],"sourcesContent":["import { join, resolve as resolvePath } from \"node:path\";\nimport { Transform } from \"node:stream\";\nimport type { Worker } from \"node:worker_threads\";\nimport type { PipeableStreamOptions } from \"react-dom/server.node\";\nimport { createHandler } from \"../react-server/createHandler.js\";\nimport type { StreamPluginOptions } from \"../types.js\";\nimport type {\n WorkerRscChunkMessage,\n WorkerRscEndMessage,\n} from \"./types.js\";\n\ntype RenderPagesOptions = {\n pluginOptions: Required<\n Pick<\n StreamPluginOptions,\n \"moduleBase\" | \"moduleBasePath\" | \"moduleBaseURL\" | \"projectRoot\"\n >\n > &\n Pick<\n StreamPluginOptions,\n \"Page\" | \"props\" | \"build\" | \"Html\" | \"pageExportName\" | \"propsExportName\"\n >;\n outDir: string;\n manifest: Record<string, { file: string }>;\n worker: Worker;\n pipableStreamOptions?: PipeableStreamOptions;\n loader: (id: string) => Promise<Record<string, any>>;\n onCssFile?: (path: string) => void;\n clientCss?: string[];\n};\n\nexport async function renderPages(\n routes: string[],\n options: RenderPagesOptions\n) {\n const destinationRoot = resolvePath(\n options.pluginOptions.projectRoot,\n options.outDir\n );\n const failedRoutes = new Map<string, Error>();\n const moduleBasePath = join(\n destinationRoot,\n options.pluginOptions.moduleBasePath\n );\n const moduleBaseURL = options.pluginOptions.moduleBaseURL;\n\n const htmlRoot = resolvePath(\n options.pluginOptions.projectRoot,\n options.pluginOptions.build?.client ?? options.outDir\n );\n const filesOutputted: string[] = [];\n\n options.worker.on(\"message\", (msg) => {\n switch (msg.type) {\n case \"ERROR\":\n console.error(\"[RenderPages] Worker error:\", msg.error);\n break;\n case \"HTML\":\n filesOutputted.push(msg.outputPath);\n if (filesOutputted.length === routes.length) {\n renderPromises.push(\n new Promise<void>((resolve) => {\n options.worker.removeAllListeners();\n options.worker.terminate();\n resolve();\n })\n );\n }\n break;\n default:\n break;\n }\n });\n const pipableStreamOptions = options.pipableStreamOptions ?? {};\n\n // Create promises for each route in the batch\n const renderPromises = routes.map(async (route) => {\n try {\n // Wait for handler creation\n const result = await createHandler(route, options.pluginOptions, {\n loader: options.loader,\n manifest: options.manifest,\n });\n\n if (result.type !== \"success\") {\n return;\n }\n const htmlOutputPath = join(htmlRoot, route, \"index.html\");\n\n // Create a promise that resolves when the worker completes\n await new Promise<void>((resolve, reject) => {\n // Pipe RSC stream to worker\n const transform = new Transform({\n transform(chunk, _encoding, callback) {\n // Send raw chunk\n options.worker.postMessage({\n type: \"RSC_CHUNK\",\n id: route,\n chunk: chunk,\n moduleBasePath,\n moduleBaseURL,\n htmlOutputPath: htmlOutputPath,\n outDir: options.outDir,\n pipableStreamOptions,\n } satisfies WorkerRscChunkMessage);\n callback();\n },\n flush(callback) {\n options.worker.postMessage({\n type: \"RSC_END\",\n id: route,\n } satisfies WorkerRscEndMessage);\n callback();\n },\n });\n\n // Listen for worker response for this route\n const messageHandler = (msg: any) => {\n if (msg.route === route) {\n if (msg.type === \"ERROR\") {\n options.worker.removeListener(\"message\", messageHandler);\n reject(new Error(msg.error));\n } else if (msg.type === \"HTML\") {\n options.worker.removeListener(\"message\", messageHandler);\n resolve();\n }\n }\n };\n\n options.worker.on(\"message\", messageHandler);\n result.stream?.pipe(transform);\n });\n } catch (error) {\n failedRoutes.set(route, error as Error);\n }\n });\n\n // Wait for all routes to complete\n await Promise.all(renderPromises);\n\n if (failedRoutes.size > 0) {\n console.error(\"[vite-react-stream] Failed routes:\", failedRoutes);\n }\n}\n"],"names":["resolvePath","resolve"],"mappings":";;;AA+BsB,eAAA,YACpB,QACA,SACA;AACA,QAAM,kBAAkBA;AAAAA,IACtB,QAAQ,cAAc;AAAA,IACtB,QAAQ;AAAA,EACV;AACM,QAAA,mCAAmB,IAAmB;AAC5C,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,QAAQ,cAAc;AAAA,EACxB;AACM,QAAA,gBAAgB,QAAQ,cAAc;AAE5C,QAAM,WAAWA;AAAAA,IACf,QAAQ,cAAc;AAAA,IACtB,QAAQ,cAAc,OAAO,UAAU,QAAQ;AAAA,EACjD;AACA,QAAM,iBAA2B,CAAC;AAElC,UAAQ,OAAO,GAAG,WAAW,CAAC,QAAQ;AACpC,YAAQ,IAAI,MAAM;AAAA,MAChB,KAAK;AACK,gBAAA,MAAM,+BAA+B,IAAI,KAAK;AACtD;AAAA,MACF,KAAK;AACY,uBAAA,KAAK,IAAI,UAAU;AAC9B,YAAA,eAAe,WAAW,OAAO,QAAQ;AAC5B,yBAAA;AAAA,YACb,IAAI,QAAc,CAACC,aAAY;AAC7B,sBAAQ,OAAO,mBAAmB;AAClC,sBAAQ,OAAO,UAAU;AACjB,cAAAA,SAAA;AAAA,YACT,CAAA;AAAA,UACH;AAAA,QAAA;AAEF;AAAA,IAEA;AAAA,EACJ,CACD;AACK,QAAA,uBAAuB,QAAQ,wBAAwB,CAAC;AAG9D,QAAM,iBAAiB,OAAO,IAAI,OAAO,UAAU;AAC7C,QAAA;AAEF,YAAM,SAAS,MAAM,cAAc,OAAO,QAAQ,eAAe;AAAA,QAC/D,QAAQ,QAAQ;AAAA,QAChB,UAAU,QAAQ;AAAA,MAAA,CACnB;AAEG,UAAA,OAAO,SAAS,WAAW;AAC7B;AAAA,MAAA;AAEF,YAAM,iBAAiB,KAAK,UAAU,OAAO,YAAY;AAGzD,YAAM,IAAI,QAAc,CAACA,UAAS,WAAW;AAErC,cAAA,YAAY,IAAI,UAAU;AAAA,UAC9B,UAAU,OAAO,WAAW,UAAU;AAEpC,oBAAQ,OAAO,YAAY;AAAA,cACzB,MAAM;AAAA,cACN,IAAI;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ,QAAQ;AAAA,cAChB;AAAA,YAAA,CAC+B;AACxB,qBAAA;AAAA,UACX;AAAA,UACA,MAAM,UAAU;AACd,oBAAQ,OAAO,YAAY;AAAA,cACzB,MAAM;AAAA,cACN,IAAI;AAAA,YAAA,CACyB;AACtB,qBAAA;AAAA,UAAA;AAAA,QACX,CACD;AAGK,cAAA,iBAAiB,CAAC,QAAa;AAC/B,cAAA,IAAI,UAAU,OAAO;AACnB,gBAAA,IAAI,SAAS,SAAS;AAChB,sBAAA,OAAO,eAAe,WAAW,cAAc;AACvD,qBAAO,IAAI,MAAM,IAAI,KAAK,CAAC;AAAA,YAAA,WAClB,IAAI,SAAS,QAAQ;AACtB,sBAAA,OAAO,eAAe,WAAW,cAAc;AAC/C,cAAAA,SAAA;AAAA,YAAA;AAAA,UACV;AAAA,QAEJ;AAEQ,gBAAA,OAAO,GAAG,WAAW,cAAc;AACpC,eAAA,QAAQ,KAAK,SAAS;AAAA,MAAA,CAC9B;AAAA,aACM,OAAO;AACD,mBAAA,IAAI,OAAO,KAAc;AAAA,IAAA;AAAA,EACxC,CACD;AAGK,QAAA,QAAQ,IAAI,cAAc;AAE5B,MAAA,aAAa,OAAO,GAAG;AACjB,YAAA,MAAM,sCAAsC,YAAY;AAAA,EAAA;AAEpE;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AliasOptions, Connect, Logger, Manifest, ModuleGraph, ViteDevServer } from "vite";
|
|
1
|
+
import type { AliasOptions, BuildOptions, Connect, Logger, Manifest, ModuleGraph, UserConfig, ViteDevServer } from "vite";
|
|
2
2
|
export interface StreamPluginOptionsClient {
|
|
3
3
|
outDir?: string;
|
|
4
4
|
build?: BuildConfig;
|
|
@@ -10,8 +10,12 @@ export interface StreamPluginOptionsClient {
|
|
|
10
10
|
clientComponents?: AliasOptions;
|
|
11
11
|
cssFiles?: AliasOptions;
|
|
12
12
|
}
|
|
13
|
-
export type ResolvedUserOptions = Required<Pick<StreamPluginOptions, "moduleBase" | "moduleBasePath" | "moduleBaseURL" | "projectRoot" | "build" | "Page" | "props" | "Html" | "pageExportName" | "propsExportName" | "collectCss" | "collectAssets" | "assetsDir">> & {
|
|
13
|
+
export type ResolvedUserOptions = Required<Pick<StreamPluginOptions, "moduleBase" | "moduleBasePath" | "moduleBaseURL" | "projectRoot" | "build" | "Page" | "props" | "Html" | "pageExportName" | "propsExportName" | "collectCss" | "collectAssets" | "assetsDir" | "workerPath" | "loaderPath" | "clientEntry" | "serverOutDir" | "clientOutDir" | "moduleBaseExceptions">> & {
|
|
14
14
|
build: NonNullable<Required<StreamPluginOptions["build"]>>;
|
|
15
|
+
autoDiscover: NonNullable<Required<StreamPluginOptions["autoDiscover"]>>;
|
|
16
|
+
};
|
|
17
|
+
export type ResolvedUserConfig = Required<Pick<UserConfig, "root" | "mode">> & Omit<UserConfig, "root" | "mode" | "build"> & {
|
|
18
|
+
build: Required<Pick<BuildOptions, "target" | "outDir" | "assetsDir" | "ssr" | "ssrEmitAssets" | "ssrManifest" | "manifest">> & Partial<Omit<BuildOptions, "target" | "outDir" | "assetsDir" | "ssr" | "ssrEmitAssets" | "ssrManifest" | "manifest">>;
|
|
15
19
|
};
|
|
16
20
|
export interface StreamPluginOptions {
|
|
17
21
|
projectRoot?: string;
|
|
@@ -42,6 +46,7 @@ export interface StreamPluginOptions {
|
|
|
42
46
|
collectCss?: boolean;
|
|
43
47
|
collectAssets?: boolean;
|
|
44
48
|
build?: BuildConfig;
|
|
49
|
+
moduleBaseExceptions?: string[];
|
|
45
50
|
}
|
|
46
51
|
export interface CreateHandlerOptions<T = any> {
|
|
47
52
|
loader: (id: string) => Promise<T>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,OAAO,EACP,MAAM,EACN,QAAQ,EACR,WAAW,EACX,aAAa,EACd,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CACxC,IAAI,CACF,mBAAmB,EACjB,YAAY,GACZ,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,OAAO,GACP,MAAM,GACN,OAAO,GACP,MAAM,GACN,gBAAgB,GAChB,iBAAiB,GACjB,YAAY,GACZ,eAAe,GACf,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { Worker } from "node:worker_threads";
|
|
2
|
-
|
|
2
|
+
type CreateWorkerOptions = {
|
|
3
|
+
workerPath: string;
|
|
4
|
+
nodePath: string;
|
|
5
|
+
mode: "production" | "development";
|
|
6
|
+
workerOptions?: WorkerOptions;
|
|
7
|
+
};
|
|
8
|
+
export declare function createWorker(options: CreateWorkerOptions): Promise<Worker>;
|
|
9
|
+
export {};
|
|
3
10
|
//# sourceMappingURL=createWorker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWorker.d.ts","sourceRoot":"","sources":["../../src/worker/createWorker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,
|
|
1
|
+
{"version":3,"file":"createWorker.d.ts","sourceRoot":"","sources":["../../src/worker/createWorker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC;IACnC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,mBAgC7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sources":["../../src/worker/loader.ts"],"sourcesContent":["/**\n * Extension point for custom module loading in the worker thread.\n * This file can be overridden via the plugin options:\n *\n * ```ts\n * reactStreamPlugin({\n * loaderPath: './my-custom-loader.ts'\n * })\n * ```\n *\n * The default loader provides basic module loading functionality.\n * Override this if you need custom module resolution or transformation.\n */\nexport function load(id: string) {\n return import(id);\n}\n"],"names":[],"mappings":"AAaO,SAAS,KAAK,IAAY;AAC/B,SAAO,OAAO;AAChB;"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createWriteStream } from "node:fs";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { Writable } from "node:stream";
|
|
5
|
+
import { parentPort } from "node:worker_threads";
|
|
6
|
+
import { createHtmlStream } from "../src/worker/createHtmlStream.js";
|
|
7
|
+
if (!parentPort) {
|
|
8
|
+
throw new Error("This module must be run as a worker");
|
|
9
|
+
}
|
|
10
|
+
global.window = {
|
|
11
|
+
href: void 0,
|
|
12
|
+
pathname: void 0
|
|
13
|
+
};
|
|
14
|
+
const activeRenders = /* @__PURE__ */ new Map();
|
|
15
|
+
const activeStreams = /* @__PURE__ */ new Map();
|
|
16
|
+
const activeWrites = /* @__PURE__ */ new Map();
|
|
17
|
+
async function shutdown() {
|
|
18
|
+
console.log("[Worker] Shutting down forcefully");
|
|
19
|
+
while (activeRenders.size > 0) {
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
21
|
+
}
|
|
22
|
+
for (const stream of activeStreams.values()) {
|
|
23
|
+
stream.abort();
|
|
24
|
+
}
|
|
25
|
+
for (const writeStream of activeWrites.values()) {
|
|
26
|
+
writeStream.destroy();
|
|
27
|
+
}
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
parentPort.on("message", async (message) => {
|
|
31
|
+
if (message.type === "SHUTDOWN") {
|
|
32
|
+
await shutdown();
|
|
33
|
+
}
|
|
34
|
+
if (!parentPort) {
|
|
35
|
+
throw new Error("No parent port available");
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
switch (message.type) {
|
|
39
|
+
case "RSC_CHUNK": {
|
|
40
|
+
const { chunk, id, ...rest } = message;
|
|
41
|
+
global.window.pathname = id;
|
|
42
|
+
let renderState = activeRenders.get(id);
|
|
43
|
+
if (renderState?.rendered) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!renderState) {
|
|
47
|
+
renderState = {
|
|
48
|
+
chunks: [],
|
|
49
|
+
complete: false,
|
|
50
|
+
rendered: false,
|
|
51
|
+
id,
|
|
52
|
+
...rest
|
|
53
|
+
};
|
|
54
|
+
activeRenders.set(id, renderState);
|
|
55
|
+
}
|
|
56
|
+
if (chunk) renderState.chunks.push(chunk);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "RSC_END": {
|
|
60
|
+
const { id } = message;
|
|
61
|
+
const render = activeRenders.get(id);
|
|
62
|
+
if (!render || !parentPort || render.rendered) return;
|
|
63
|
+
try {
|
|
64
|
+
const writeToFile = render.outDir && render.htmlOutputPath;
|
|
65
|
+
if (writeToFile) {
|
|
66
|
+
await mkdir(dirname(render.htmlOutputPath), { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
const { stream, writeStream } = createHtmlStream(
|
|
69
|
+
render,
|
|
70
|
+
writeToFile ? createWriteStream(render.htmlOutputPath) : new Writable({
|
|
71
|
+
write(chunk, _, callback) {
|
|
72
|
+
parentPort?.postMessage({
|
|
73
|
+
type: "HTML",
|
|
74
|
+
route: render.id,
|
|
75
|
+
content: chunk.toString()
|
|
76
|
+
});
|
|
77
|
+
callback();
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
activeStreams.set(id, stream);
|
|
82
|
+
activeWrites.set(id, writeStream);
|
|
83
|
+
writeStream.on("finish", () => {
|
|
84
|
+
activeStreams.delete(id);
|
|
85
|
+
activeWrites.delete(id);
|
|
86
|
+
});
|
|
87
|
+
writeStream.on("error", () => {
|
|
88
|
+
activeStreams.delete(id);
|
|
89
|
+
activeWrites.delete(id);
|
|
90
|
+
stream.abort();
|
|
91
|
+
});
|
|
92
|
+
} catch (error) {
|
|
93
|
+
activeRenders.delete(id);
|
|
94
|
+
activeStreams.delete(id);
|
|
95
|
+
activeWrites.delete(id);
|
|
96
|
+
throw error;
|
|
97
|
+
} finally {
|
|
98
|
+
activeRenders.delete(id);
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
105
|
+
parentPort?.postMessage({
|
|
106
|
+
type: "ERROR",
|
|
107
|
+
error: errorMessage
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
parentPort.postMessage({ type: "READY" });
|
|
112
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sources":["../../src/worker/worker.tsx"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\nimport { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport { Writable } from \"node:stream\";\nimport { parentPort } from \"node:worker_threads\";\nimport type { PipeableStream } from \"react-server-dom-esm/server.node\";\nimport { createHtmlStream } from \"./createHtmlStream.js\";\nimport type { RenderState, WorkerMessage } from \"./types.js\";\n\nif (!parentPort) {\n throw new Error(\"This module must be run as a worker\");\n}\n\ndeclare global {\n interface Window {\n href: string;\n }\n} \n// Initialize happy-dom window\n(global as any).window = {\n href: undefined,\n pathname: undefined,\n}\n\n// Track active renders\nconst activeRenders = new Map<string, RenderState>();\nconst activeStreams = new Map<string, PipeableStream>();\nconst activeWrites = new Map<string, Writable>();\n\nasync function shutdown() {\n console.log(\"[Worker] Shutting down forcefully\");\n while (activeRenders.size > 0) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n for (const stream of activeStreams.values()) {\n stream.abort();\n }\n for (const writeStream of activeWrites.values()) {\n writeStream.destroy();\n }\n process.exit(0);\n}\n// Handle incoming messages\nparentPort.on(\"message\", async (message: WorkerMessage) => {\n if (message.type === \"SHUTDOWN\") {\n await shutdown();\n }\n if (!parentPort) {\n throw new Error(\"No parent port available\");\n }\n try {\n switch (message.type) {\n case \"RSC_CHUNK\": {\n const { chunk, id, ...rest } = message;\n (global as any).window.pathname = id;\n // Skip if already rendered\n let renderState = activeRenders.get(id);\n if (renderState?.rendered) {\n return;\n }\n // Initialize render state\n if (!renderState) {\n renderState = {\n chunks: [],\n complete: false,\n rendered: false,\n id: id,\n ...rest,\n };\n activeRenders.set(id, renderState);\n }\n // Add chunk\n if (chunk) renderState.chunks.push(chunk);\n break;\n }\n\n case \"RSC_END\": {\n const { id } = message;\n const render = activeRenders.get(id);\n\n if (!render || !parentPort || render.rendered) return;\n try {\n const writeToFile = render.outDir && render.htmlOutputPath;\n // Write RSC content\n if (writeToFile) {\n await mkdir(dirname(render.htmlOutputPath), { recursive: true });\n }\n const { stream, writeStream } = createHtmlStream(\n render,\n writeToFile\n ? createWriteStream(render.htmlOutputPath)\n : new Writable({\n write(chunk, _, callback) {\n parentPort?.postMessage({\n type: \"HTML\",\n route: render.id,\n content: chunk.toString(),\n });\n callback();\n },\n })\n );\n activeStreams.set(id, stream);\n activeWrites.set(id, writeStream);\n writeStream.on(\"finish\", () => {\n activeStreams.delete(id);\n activeWrites.delete(id);\n });\n writeStream.on(\"error\", () => {\n activeStreams.delete(id);\n activeWrites.delete(id);\n stream.abort();\n });\n } catch (error) {\n activeRenders.delete(id);\n activeStreams.delete(id);\n activeWrites.delete(id);\n throw error;\n } finally {\n activeRenders.delete(id);\n }\n break;\n }\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n parentPort?.postMessage({\n type: \"ERROR\",\n error: errorMessage,\n });\n }\n});\n\n// Signal ready only after loader is registered\nparentPort.postMessage({ type: \"READY\" });\n\n"],"names":[],"mappings":"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"}
|