@gdansk/vite 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/assets/{ssr-DnMeNprs.js → ssr-C3v_roWy.js} +319 -121
- package/dist/assets/ssr-C3v_roWy.js.map +1 -0
- package/dist/index.js +42 -8
- package/dist/index.js.map +1 -1
- package/dist/runtime.js +6 -5
- package/dist/runtime.js.map +1 -1
- package/package.json +3 -3
- package/types/development.d.ts +12 -0
- package/types/index.d.ts +1 -1
- package/types/plugin.d.ts +2 -2
- package/types/types.d.ts +12 -10
- package/types/virtual.d.ts +10 -0
- package/dist/assets/ssr-DnMeNprs.js.map +0 -1
package/deno.json
CHANGED
|
@@ -1,24 +1,149 @@
|
|
|
1
|
-
import { access, glob, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
-
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
3
1
|
import { build, loadConfigFromFile, mergeConfig, normalizePath } from "vite";
|
|
2
|
+
import { access, glob, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, matchesGlob, posix, relative, resolve, sep } from "node:path";
|
|
4
|
+
//#region src/virtual.ts
|
|
5
|
+
var GDANSK_DEV_CLIENT_PREFIX = "/@gdansk/client";
|
|
6
|
+
var GDANSK_SSR_ENTRY_ID = "virtual:gdansk/ssr-entry";
|
|
7
|
+
var CLIENT_MODULE_PREFIX = "virtual:gdansk/client/";
|
|
8
|
+
var RESOLVED_VIRTUAL_PREFIX = "\0";
|
|
9
|
+
var SYNTHETIC_ROOT = "__gdansk_virtual__";
|
|
10
|
+
function createGdanskVirtualModulesPlugin(options, prepared) {
|
|
11
|
+
return {
|
|
12
|
+
load(id) {
|
|
13
|
+
return loadVirtualModule(options, prepared, id);
|
|
14
|
+
},
|
|
15
|
+
name: "@gdansk/vite:virtual-modules",
|
|
16
|
+
resolveId(id, importer) {
|
|
17
|
+
return resolveVirtualModuleId(options, prepared, id, importer);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function createClientDevEntry(key) {
|
|
22
|
+
return `${GDANSK_DEV_CLIENT_PREFIX}/${key}.tsx`;
|
|
23
|
+
}
|
|
24
|
+
function createClientModuleId(key) {
|
|
25
|
+
return `${CLIENT_MODULE_PREFIX}${key}`;
|
|
26
|
+
}
|
|
27
|
+
function createResolvedClientModuleId(key) {
|
|
28
|
+
return `${RESOLVED_VIRTUAL_PREFIX}${createClientModuleId(key)}`;
|
|
29
|
+
}
|
|
30
|
+
function resolveVirtualModuleId(options, prepared, id, importer) {
|
|
31
|
+
const widgetByDevEntry = findWidgetByDevEntry(prepared.widgets, id);
|
|
32
|
+
if (widgetByDevEntry) return createResolvedClientModuleId(widgetByDevEntry.key);
|
|
33
|
+
const widgetByModuleId = findWidgetByModuleId(prepared.widgets, id);
|
|
34
|
+
if (widgetByModuleId) return createResolvedClientModuleId(widgetByModuleId.key);
|
|
35
|
+
if (id === "virtual:gdansk/ssr-entry") return resolveSSRModuleId();
|
|
36
|
+
if (!importer || !id.startsWith(".")) return null;
|
|
37
|
+
const syntheticImporterPath = getSyntheticImporterPath(options, prepared, importer);
|
|
38
|
+
if (!syntheticImporterPath) return null;
|
|
39
|
+
return resolve(dirname(syntheticImporterPath), id);
|
|
40
|
+
}
|
|
41
|
+
function loadVirtualModule(options, prepared, id) {
|
|
42
|
+
const widget = findWidgetByResolvedId(prepared.widgets, id);
|
|
43
|
+
if (widget) return createClientModuleSource(options, widget);
|
|
44
|
+
if (id === resolveSSRModuleId()) return createSSRModuleSource(options, prepared.widgets);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
function createClientModuleSource(options, widget) {
|
|
48
|
+
const sourceImport = createImportPath(getSyntheticClientPath(options, widget.key), widget.entry);
|
|
49
|
+
return [
|
|
50
|
+
"import React from \"react\";",
|
|
51
|
+
"import { createRoot, hydrateRoot } from \"react-dom/client\";",
|
|
52
|
+
`import App from ${JSON.stringify(sourceImport)};`,
|
|
53
|
+
"",
|
|
54
|
+
"const root = document.getElementById(\"root\");",
|
|
55
|
+
"",
|
|
56
|
+
"if (!root) {",
|
|
57
|
+
" throw new Error('Gdansk expected a #root element for widget hydration.');",
|
|
58
|
+
"}",
|
|
59
|
+
"",
|
|
60
|
+
"const element = React.createElement(React.StrictMode, null, React.createElement(App));",
|
|
61
|
+
"",
|
|
62
|
+
"if (root.hasChildNodes()) {",
|
|
63
|
+
" hydrateRoot(root, element);",
|
|
64
|
+
"} else {",
|
|
65
|
+
" createRoot(root).render(element);",
|
|
66
|
+
"}",
|
|
67
|
+
""
|
|
68
|
+
].join("\n");
|
|
69
|
+
}
|
|
70
|
+
function createSSRModuleSource(options, widgets) {
|
|
71
|
+
const syntheticPath = getSyntheticSSRPath(options);
|
|
72
|
+
const imports = widgets.map((widget, index) => {
|
|
73
|
+
const specifier = createImportPath(syntheticPath, widget.entry);
|
|
74
|
+
return `import Widget${index} from ${JSON.stringify(specifier)};`;
|
|
75
|
+
});
|
|
76
|
+
const widgetEntries = widgets.map((widget, index) => ` ${JSON.stringify(widget.key)}: Widget${index},`);
|
|
77
|
+
return [
|
|
78
|
+
"import { createElement } from \"react\";",
|
|
79
|
+
"import { renderToString } from \"react-dom/server\";",
|
|
80
|
+
...imports,
|
|
81
|
+
"",
|
|
82
|
+
"const widgets = {",
|
|
83
|
+
...widgetEntries,
|
|
84
|
+
"};",
|
|
85
|
+
"",
|
|
86
|
+
"export default async function renderWidget(widgetKey) {",
|
|
87
|
+
" const component = widgets[widgetKey];",
|
|
88
|
+
"",
|
|
89
|
+
" if (!component) {",
|
|
90
|
+
" throw new Error(`Unknown widget: ${widgetKey}`);",
|
|
91
|
+
" }",
|
|
92
|
+
"",
|
|
93
|
+
" return {",
|
|
94
|
+
" body: renderToString(createElement(component)),",
|
|
95
|
+
" head: [],",
|
|
96
|
+
" };",
|
|
97
|
+
"}",
|
|
98
|
+
""
|
|
99
|
+
].join("\n");
|
|
100
|
+
}
|
|
101
|
+
function createImportPath(from, to) {
|
|
102
|
+
const relativePath = toPosixPath$1(relative(dirname(from), to));
|
|
103
|
+
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
104
|
+
}
|
|
105
|
+
function findWidgetByDevEntry(widgets, id) {
|
|
106
|
+
return widgets.find((widget) => widget.clientDevEntry === id);
|
|
107
|
+
}
|
|
108
|
+
function findWidgetByModuleId(widgets, id) {
|
|
109
|
+
return widgets.find((widget) => widget.clientModuleId === id);
|
|
110
|
+
}
|
|
111
|
+
function findWidgetByResolvedId(widgets, id) {
|
|
112
|
+
return widgets.find((widget) => createResolvedClientModuleId(widget.key) === id);
|
|
113
|
+
}
|
|
114
|
+
function getSyntheticClientPath(options, key) {
|
|
115
|
+
return resolve(options.root, SYNTHETIC_ROOT, "client", key, "client.tsx");
|
|
116
|
+
}
|
|
117
|
+
function getSyntheticImporterPath(options, prepared, importer) {
|
|
118
|
+
if (importer === resolveSSRModuleId()) return getSyntheticSSRPath(options);
|
|
119
|
+
const widget = findWidgetByResolvedId(prepared.widgets, importer);
|
|
120
|
+
return widget ? getSyntheticClientPath(options, widget.key) : null;
|
|
121
|
+
}
|
|
122
|
+
function getSyntheticSSRPath(options) {
|
|
123
|
+
return resolve(options.root, SYNTHETIC_ROOT, "ssr-entry.ts");
|
|
124
|
+
}
|
|
125
|
+
function resolveSSRModuleId() {
|
|
126
|
+
return `${RESOLVED_VIRTUAL_PREFIX}${GDANSK_SSR_ENTRY_ID}`;
|
|
127
|
+
}
|
|
128
|
+
function toPosixPath$1(path) {
|
|
129
|
+
return path.split(sep).join("/");
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
4
132
|
//#region src/context.ts
|
|
5
133
|
function resolveOptions(options = {}, configRoot) {
|
|
6
134
|
const root = resolve(configRoot ?? options.root ?? process.cwd());
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const generatedDir = "dist-src";
|
|
135
|
+
const widgetsDirectory = options.widgetsDirectory ?? "widgets";
|
|
136
|
+
const buildDirectory = options.buildDirectory ?? "dist";
|
|
10
137
|
const host = options.host ?? "127.0.0.1";
|
|
11
138
|
return {
|
|
12
|
-
|
|
13
|
-
|
|
139
|
+
buildDirectory,
|
|
140
|
+
buildDirectoryPath: resolve(root, buildDirectory),
|
|
14
141
|
host,
|
|
15
|
-
outDir,
|
|
16
|
-
outDirPath: resolve(root, outDir),
|
|
17
142
|
root,
|
|
18
143
|
ssrEndpoint: "/ssr",
|
|
19
144
|
port: options.port ?? 13714,
|
|
20
|
-
|
|
21
|
-
|
|
145
|
+
widgetsDirectory,
|
|
146
|
+
widgetsDirectoryPath: resolve(root, widgetsDirectory)
|
|
22
147
|
};
|
|
23
148
|
}
|
|
24
149
|
async function globPaths(pattern, options) {
|
|
@@ -28,16 +153,15 @@ async function globPaths(pattern, options) {
|
|
|
28
153
|
return matches;
|
|
29
154
|
}
|
|
30
155
|
async function discoverWidgets(options) {
|
|
31
|
-
return (await globPaths("**/widget.{tsx,jsx}", { cwd: options.
|
|
156
|
+
return (await globPaths("**/widget.{tsx,jsx}", { cwd: options.widgetsDirectoryPath })).sort().map((entry) => {
|
|
32
157
|
const widgetPath = toPosixPath(entry);
|
|
33
158
|
const key = toPosixPath(dirname(widgetPath));
|
|
34
|
-
const clientSource = toPosixPath(join(options.generatedDir, key, "client.tsx"));
|
|
35
159
|
return {
|
|
36
|
-
clientCss: toPosixPath(join(options.
|
|
37
|
-
clientDevEntry:
|
|
38
|
-
clientEntry: toPosixPath(join(options.
|
|
39
|
-
|
|
40
|
-
entry: resolve(options.
|
|
160
|
+
clientCss: toPosixPath(join(options.buildDirectory, key, "client.css")),
|
|
161
|
+
clientDevEntry: createClientDevEntry(key),
|
|
162
|
+
clientEntry: toPosixPath(join(options.buildDirectory, key, "client.js")),
|
|
163
|
+
clientModuleId: createClientModuleId(key),
|
|
164
|
+
entry: resolve(options.widgetsDirectoryPath, entry),
|
|
41
165
|
key,
|
|
42
166
|
widgetPath
|
|
43
167
|
};
|
|
@@ -51,17 +175,17 @@ async function loadUserViteConfig(options, command) {
|
|
|
51
175
|
const { plugins: _, ...configWithoutPlugins } = loadedConfig;
|
|
52
176
|
return mergeConfig(configWithoutPlugins, {
|
|
53
177
|
plugins: (await normalizePlugins(loadedConfig.plugins)).filter((plugin) => plugin.name !== "@gdansk/vite"),
|
|
54
|
-
root: options.root
|
|
178
|
+
root: options.root,
|
|
179
|
+
resolve: {
|
|
180
|
+
...loadedConfig.resolve ?? {},
|
|
181
|
+
alias: mergeDefaultAlias(loadedConfig.resolve?.alias, options.root)
|
|
182
|
+
}
|
|
55
183
|
});
|
|
56
184
|
}
|
|
57
185
|
async function prepareProject(options) {
|
|
58
|
-
const widgets = await discoverWidgets(options);
|
|
59
|
-
await Promise.all(widgets.map((widget) => writeClientEntry(widget)));
|
|
60
|
-
const ssrEntry = resolve(options.generatedDirPath, "__gdansk_ssr__.ts");
|
|
61
|
-
await writeSSRRenderEntry(ssrEntry, widgets);
|
|
62
186
|
return {
|
|
63
|
-
|
|
64
|
-
widgets
|
|
187
|
+
ssrEntryId: GDANSK_SSR_ENTRY_ID,
|
|
188
|
+
widgets: await discoverWidgets(options)
|
|
65
189
|
};
|
|
66
190
|
}
|
|
67
191
|
async function pathExists(path) {
|
|
@@ -75,10 +199,6 @@ async function pathExists(path) {
|
|
|
75
199
|
function toPosixPath(path) {
|
|
76
200
|
return path.split(sep).join("/");
|
|
77
201
|
}
|
|
78
|
-
function createImportPath(from, to) {
|
|
79
|
-
const relativePath = toPosixPath(relative(dirname(from), to));
|
|
80
|
-
return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
81
|
-
}
|
|
82
202
|
async function normalizePlugins(plugins) {
|
|
83
203
|
if (!plugins) return [];
|
|
84
204
|
const entries = Array.isArray(plugins) ? plugins : [plugins];
|
|
@@ -94,70 +214,24 @@ async function normalizePlugins(plugins) {
|
|
|
94
214
|
}
|
|
95
215
|
return normalized;
|
|
96
216
|
}
|
|
97
|
-
function
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
"",
|
|
108
|
-
"const root = document.getElementById(\"root\");",
|
|
109
|
-
"",
|
|
110
|
-
"if (!root) {",
|
|
111
|
-
" throw new Error('Gdansk expected a #root element for widget hydration.');",
|
|
112
|
-
"}",
|
|
113
|
-
"",
|
|
114
|
-
"const element = (",
|
|
115
|
-
" <React.StrictMode>",
|
|
116
|
-
" <App />",
|
|
117
|
-
" </React.StrictMode>",
|
|
118
|
-
");",
|
|
119
|
-
"",
|
|
120
|
-
"if (root.hasChildNodes()) {",
|
|
121
|
-
" hydrateRoot(root, element);",
|
|
122
|
-
"} else {",
|
|
123
|
-
" createRoot(root).render(element);",
|
|
124
|
-
"}",
|
|
125
|
-
""
|
|
126
|
-
].join("\n"));
|
|
217
|
+
function mergeDefaultAlias(alias, root) {
|
|
218
|
+
if (Array.isArray(alias)) return hasNamedAlias$1(alias, "@") ? alias : [...alias, {
|
|
219
|
+
find: "@",
|
|
220
|
+
replacement: root
|
|
221
|
+
}];
|
|
222
|
+
if (typeof alias === "object" && alias !== null && "@" in alias) return alias;
|
|
223
|
+
return {
|
|
224
|
+
...alias ?? {},
|
|
225
|
+
"@": root
|
|
226
|
+
};
|
|
127
227
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return `import Widget${index} from "${createImportPath(path, widget.entry)}";`;
|
|
131
|
-
});
|
|
132
|
-
const widgetEntries = widgets.map((widget, index) => ` ${JSON.stringify(widget.key)}: Widget${index},`);
|
|
133
|
-
await mkdir(dirname(path), { recursive: true });
|
|
134
|
-
await writeFile(path, [
|
|
135
|
-
"import { createElement } from \"react\";",
|
|
136
|
-
"import { renderToString } from \"react-dom/server\";",
|
|
137
|
-
...imports,
|
|
138
|
-
"",
|
|
139
|
-
"const widgets = {",
|
|
140
|
-
...widgetEntries,
|
|
141
|
-
"} as const;",
|
|
142
|
-
"",
|
|
143
|
-
"export default async function renderWidget(widgetKey: string) {",
|
|
144
|
-
" const component = widgets[widgetKey as keyof typeof widgets];",
|
|
145
|
-
"",
|
|
146
|
-
" if (!component) {",
|
|
147
|
-
" throw new Error(`Unknown widget: ${widgetKey}`);",
|
|
148
|
-
" }",
|
|
149
|
-
"",
|
|
150
|
-
" return {",
|
|
151
|
-
" body: renderToString(createElement(component)),",
|
|
152
|
-
" head: [],",
|
|
153
|
-
" };",
|
|
154
|
-
"}",
|
|
155
|
-
""
|
|
156
|
-
].join("\n"));
|
|
228
|
+
function hasNamedAlias$1(aliases, name) {
|
|
229
|
+
return aliases.some((alias) => alias.find === name);
|
|
157
230
|
}
|
|
158
231
|
//#endregion
|
|
159
232
|
//#region src/build.ts
|
|
160
|
-
var CLIENT_MANIFEST_FILE = "
|
|
233
|
+
var CLIENT_MANIFEST_FILE = "manifest.json";
|
|
234
|
+
var GDANSK_MANIFEST_FILE = "gdansk-manifest.json";
|
|
161
235
|
var SERVER_BUNDLE = "ssr.js";
|
|
162
236
|
function createBuildConfig(options, prepared) {
|
|
163
237
|
return {
|
|
@@ -173,7 +247,7 @@ function createBuildConfig(options, prepared) {
|
|
|
173
247
|
build: {
|
|
174
248
|
copyPublicDir: false,
|
|
175
249
|
emptyOutDir: true,
|
|
176
|
-
outDir: options.
|
|
250
|
+
outDir: options.buildDirectory,
|
|
177
251
|
sourcemap: true
|
|
178
252
|
},
|
|
179
253
|
environments: {
|
|
@@ -186,21 +260,23 @@ function createBuildConfig(options, prepared) {
|
|
|
186
260
|
};
|
|
187
261
|
}
|
|
188
262
|
async function buildWidgets(options, prepared, config = {}) {
|
|
189
|
-
await rm(options.
|
|
263
|
+
await rm(options.buildDirectoryPath, {
|
|
190
264
|
force: true,
|
|
191
265
|
recursive: true
|
|
192
266
|
});
|
|
193
|
-
await mkdir(options.
|
|
267
|
+
await mkdir(options.buildDirectoryPath, { recursive: true });
|
|
194
268
|
if (prepared.widgets.length > 0) await build(mergeConfig(config, {
|
|
195
269
|
appType: "custom",
|
|
196
270
|
build: createClientBuildOptions(options, prepared),
|
|
197
271
|
configFile: false,
|
|
272
|
+
plugins: [createGdanskVirtualModulesPlugin(options, prepared)],
|
|
198
273
|
root: options.root
|
|
199
274
|
}));
|
|
200
275
|
await build(mergeConfig(config, {
|
|
201
276
|
appType: "custom",
|
|
202
277
|
build: createSSRBuildOptions(options, prepared),
|
|
203
278
|
configFile: false,
|
|
279
|
+
plugins: [createGdanskVirtualModulesPlugin(options, prepared)],
|
|
204
280
|
root: options.root
|
|
205
281
|
}));
|
|
206
282
|
return finalizeBuildOutputs(options, prepared.widgets);
|
|
@@ -209,18 +285,18 @@ async function readManifest(path) {
|
|
|
209
285
|
return JSON.parse(await readFile(path, "utf8"));
|
|
210
286
|
}
|
|
211
287
|
function createClientBuildOptions(options, prepared) {
|
|
212
|
-
const inputs = prepared.widgets.length > 0 ? Object.fromEntries(prepared.widgets.map((widget) => [widget.key, widget.
|
|
288
|
+
const inputs = prepared.widgets.length > 0 ? Object.fromEntries(prepared.widgets.map((widget) => [widget.key, widget.clientModuleId])) : { __gdansk_empty__: prepared.ssrEntryId };
|
|
213
289
|
return {
|
|
214
290
|
copyPublicDir: false,
|
|
215
291
|
cssCodeSplit: true,
|
|
216
292
|
emptyOutDir: true,
|
|
217
293
|
manifest: CLIENT_MANIFEST_FILE,
|
|
218
|
-
outDir: options.
|
|
294
|
+
outDir: options.buildDirectory,
|
|
219
295
|
rollupOptions: {
|
|
220
296
|
input: inputs,
|
|
221
297
|
output: {
|
|
222
298
|
assetFileNames: (assetInfo) => resolveClientAssetPath(options, prepared.widgets, assetInfo),
|
|
223
|
-
chunkFileNames: "
|
|
299
|
+
chunkFileNames: "assets/[name]-[hash].js",
|
|
224
300
|
entryFileNames: ({ name }) => `${name}/client.js`
|
|
225
301
|
}
|
|
226
302
|
},
|
|
@@ -231,79 +307,112 @@ function createSSRBuildOptions(options, prepared) {
|
|
|
231
307
|
return {
|
|
232
308
|
copyPublicDir: false,
|
|
233
309
|
emptyOutDir: false,
|
|
234
|
-
outDir: options.
|
|
310
|
+
outDir: options.buildDirectory,
|
|
235
311
|
rollupOptions: {
|
|
236
|
-
input: prepared.
|
|
312
|
+
input: prepared.ssrEntryId,
|
|
237
313
|
output: {
|
|
238
|
-
chunkFileNames: "
|
|
314
|
+
chunkFileNames: "assets/[name]-[hash].js",
|
|
239
315
|
entryFileNames: SERVER_BUNDLE
|
|
240
316
|
}
|
|
241
317
|
},
|
|
242
318
|
sourcemap: true,
|
|
243
|
-
ssr:
|
|
319
|
+
ssr: true
|
|
244
320
|
};
|
|
245
321
|
}
|
|
246
322
|
async function finalizeBuildOutputs(options, widgets) {
|
|
247
|
-
const clientManifest = await readClientManifest(resolve(options.
|
|
323
|
+
const clientManifest = await readClientManifest(resolve(options.buildDirectoryPath, CLIENT_MANIFEST_FILE));
|
|
248
324
|
const manifest = {
|
|
249
|
-
outDir: options.
|
|
325
|
+
outDir: options.buildDirectory,
|
|
250
326
|
root: options.root,
|
|
251
|
-
server: toPosixPath(`${options.
|
|
327
|
+
server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`),
|
|
252
328
|
widgets: Object.fromEntries(await Promise.all(widgets.map(async (widget) => {
|
|
253
|
-
const manifestEntry = getClientManifestEntry(
|
|
329
|
+
const manifestEntry = getClientManifestEntry(widget, clientManifest);
|
|
254
330
|
const fallbackCss = await pathExists(resolve(options.root, widget.clientCss)) ? [widget.clientCss] : [];
|
|
331
|
+
const css = manifestEntry ? await normalizeWidgetCssOutputs(options, widget, manifestEntry.css ?? []) : fallbackCss;
|
|
255
332
|
return [widget.key, {
|
|
256
333
|
client: manifestEntry ? toBuildPath(options, manifestEntry.file) : widget.clientEntry,
|
|
257
|
-
css
|
|
334
|
+
css,
|
|
258
335
|
entry: widget.widgetPath
|
|
259
336
|
}];
|
|
260
337
|
})))
|
|
261
338
|
};
|
|
262
|
-
await
|
|
263
|
-
await writeJson$1(resolve(options.outDirPath, "manifest.json"), manifest);
|
|
339
|
+
await writeJson$1(resolve(options.buildDirectoryPath, GDANSK_MANIFEST_FILE), manifest);
|
|
264
340
|
await writeProductionServer(options);
|
|
265
341
|
return manifest;
|
|
266
342
|
}
|
|
267
|
-
function getClientManifestEntry(
|
|
268
|
-
return manifest
|
|
343
|
+
function getClientManifestEntry(widget, manifest) {
|
|
344
|
+
return Object.values(manifest).find((entry) => entry.file === `${widget.key}/client.js`);
|
|
269
345
|
}
|
|
270
346
|
async function readClientManifest(path) {
|
|
271
347
|
if (!await pathExists(path)) return {};
|
|
272
348
|
return JSON.parse(await readFile(path, "utf8"));
|
|
273
349
|
}
|
|
274
350
|
function resolveClientAssetPath(options, widgets, assetInfo) {
|
|
275
|
-
if (!(assetInfo
|
|
276
|
-
const
|
|
277
|
-
const widget = originalFileName ? findWidgetForAsset(options, widgets, originalFileName) : void 0;
|
|
351
|
+
if (!(assetInfo?.names?.[0] ?? assetInfo?.originalFileNames?.[0] ?? "").endsWith(".css")) return "assets/[name]-[hash][extname]";
|
|
352
|
+
const widget = findWidgetForAsset(widgets, [...assetInfo?.originalFileNames ?? [], ...assetInfo?.names ?? []]);
|
|
278
353
|
if (!widget) return "assets/[name]-[hash][extname]";
|
|
279
354
|
return toOutputPath(options, widget.clientCss);
|
|
280
355
|
}
|
|
281
|
-
function findWidgetForAsset(
|
|
282
|
-
const normalized = toPosixPath(originalFileName);
|
|
356
|
+
function findWidgetForAsset(widgets, assetCandidates) {
|
|
283
357
|
return widgets.find((widget) => {
|
|
284
|
-
const
|
|
285
|
-
|
|
358
|
+
const normalizedModuleId = toPosixPath(widget.clientModuleId);
|
|
359
|
+
const cssName = `assets/${widget.key}`;
|
|
360
|
+
const cssNameWithExt = `${cssName}.css`;
|
|
361
|
+
return assetCandidates.map(toPosixPath).some((normalized) => {
|
|
362
|
+
return normalized === normalizedModuleId || normalized === createResolvedClientModuleId(widget.key) || normalized === cssName || normalized === cssNameWithExt || normalized.endsWith(`/${normalizedModuleId}`) || normalized.endsWith(`/${cssName}`) || normalized.endsWith(`/${cssNameWithExt}`) || normalized.endsWith(`/${widget.key}/client.js`);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
async function normalizeWidgetCssOutputs(options, widget, hrefs) {
|
|
367
|
+
if (hrefs.length !== 1) return hrefs.map((href) => toBuildPath(options, href));
|
|
368
|
+
const [href] = hrefs;
|
|
369
|
+
const target = toOutputPath(options, widget.clientCss);
|
|
370
|
+
if (href === target || href === widget.clientCss) return [toBuildPath(options, target)];
|
|
371
|
+
const sourcePath = resolve(options.buildDirectoryPath, href);
|
|
372
|
+
if (!await pathExists(sourcePath)) return hrefs.map((entry) => toBuildPath(options, entry));
|
|
373
|
+
const targetPath = resolve(options.buildDirectoryPath, target);
|
|
374
|
+
const rewrittenCss = rewriteRelativeCssUrls(await readFile(sourcePath, "utf8"), posix.dirname(href), posix.dirname(target));
|
|
375
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
376
|
+
await writeFile(targetPath, rewrittenCss);
|
|
377
|
+
await rm(sourcePath, { force: true });
|
|
378
|
+
return [toBuildPath(options, target)];
|
|
379
|
+
}
|
|
380
|
+
function rewriteRelativeCssUrls(css, fromDir, toDir) {
|
|
381
|
+
if (fromDir === toDir) return css;
|
|
382
|
+
return css.replace(/url\((['"]?)([^'")]+)\1\)/g, (_match, quote, value) => {
|
|
383
|
+
if (value.startsWith("/") || value.startsWith("#") || value.startsWith("data:") || /^[a-z]+:/i.test(value)) return `url(${quote}${value}${quote})`;
|
|
384
|
+
const [pathPart, suffix = ""] = splitCssUrl(value);
|
|
385
|
+
const fromPath = posix.join("/", fromDir, pathPart);
|
|
386
|
+
let relativePath = posix.relative(posix.join("/", toDir), fromPath);
|
|
387
|
+
if (!relativePath) relativePath = ".";
|
|
388
|
+
else if (!relativePath.startsWith(".")) relativePath = `./${relativePath}`;
|
|
389
|
+
return `url(${quote}${relativePath}${suffix}${quote})`;
|
|
286
390
|
});
|
|
287
391
|
}
|
|
392
|
+
function splitCssUrl(value) {
|
|
393
|
+
const match = /^([^?#]+)(.*)$/.exec(value);
|
|
394
|
+
return match ? [match[1], match[2]] : [value, ""];
|
|
395
|
+
}
|
|
288
396
|
async function writeJson$1(path, value) {
|
|
289
397
|
await mkdir(dirname(path), { recursive: true });
|
|
290
398
|
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
291
399
|
}
|
|
292
400
|
function toOutputPath(options, path) {
|
|
293
|
-
const prefix = `${options.
|
|
401
|
+
const prefix = `${options.buildDirectory}/`;
|
|
294
402
|
if (path.startsWith(prefix)) return path.slice(prefix.length);
|
|
295
403
|
return path;
|
|
296
404
|
}
|
|
297
405
|
function toBuildPath(options, path) {
|
|
298
|
-
return path.startsWith(`${options.
|
|
406
|
+
return path.startsWith(`${options.buildDirectory}/`) ? path : `${options.buildDirectory}/${path.replace(/^\/+/, "")}`;
|
|
299
407
|
}
|
|
300
408
|
async function writeProductionServer(options) {
|
|
301
|
-
const path = resolve(options.
|
|
409
|
+
const path = resolve(options.buildDirectoryPath, "server.js");
|
|
302
410
|
const runtimeModuleUrl = new URL("../runtime.js", import.meta.url).href;
|
|
303
411
|
const runtimeOptions = {
|
|
412
|
+
buildDirectory: options.buildDirectory,
|
|
304
413
|
host: options.host,
|
|
305
414
|
port: options.port,
|
|
306
|
-
|
|
415
|
+
widgetsDirectory: options.widgetsDirectory
|
|
307
416
|
};
|
|
308
417
|
await writeFile(path, [
|
|
309
418
|
"import { dirname, resolve } from \"node:path\";",
|
|
@@ -362,6 +471,95 @@ function resolveEntryModule(server, entry) {
|
|
|
362
471
|
return moduleGraph.getModuleById(normalized) ?? moduleGraph.getModuleById(entry);
|
|
363
472
|
}
|
|
364
473
|
//#endregion
|
|
474
|
+
//#region src/development.ts
|
|
475
|
+
var DEFAULT_REFRESH_PATHS = [
|
|
476
|
+
"../**/*.py",
|
|
477
|
+
"../**/*.j2",
|
|
478
|
+
"../**/*.jinja",
|
|
479
|
+
"../**/*.jinja2"
|
|
480
|
+
];
|
|
481
|
+
function mergeAliasConfig(alias, root) {
|
|
482
|
+
if (Array.isArray(alias)) return hasNamedAlias(alias, "@") ? alias : [...alias, {
|
|
483
|
+
find: "@",
|
|
484
|
+
replacement: root
|
|
485
|
+
}];
|
|
486
|
+
if (typeof alias === "object" && alias !== null && "@" in alias) return alias;
|
|
487
|
+
return {
|
|
488
|
+
...alias ?? {},
|
|
489
|
+
"@": root
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
function resolveDevelopmentServerConfig(options, resolved) {
|
|
493
|
+
if (typeof options.host === "undefined" && typeof options.port === "undefined") return;
|
|
494
|
+
return {
|
|
495
|
+
host: resolved.host,
|
|
496
|
+
port: resolved.port,
|
|
497
|
+
strictPort: true
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function createRefreshPlugin(options = {}) {
|
|
501
|
+
return {
|
|
502
|
+
apply: "serve",
|
|
503
|
+
configureServer(server) {
|
|
504
|
+
const resolved = resolveOptions(options, server.config.root);
|
|
505
|
+
const normalizedRoot = normalizePath(resolved.root);
|
|
506
|
+
const patterns = resolveRefreshPaths(options.refresh, resolved.root);
|
|
507
|
+
let ready = false;
|
|
508
|
+
if (patterns.length === 0) return;
|
|
509
|
+
server.watcher.add(patterns);
|
|
510
|
+
server.watcher.on("ready", () => {
|
|
511
|
+
ready = true;
|
|
512
|
+
});
|
|
513
|
+
const handleChange = (file) => {
|
|
514
|
+
if (!ready) return;
|
|
515
|
+
const normalized = normalizePath(file);
|
|
516
|
+
if (!patterns.some((pattern) => matchesGlob(normalized, pattern))) return;
|
|
517
|
+
const relativePath = normalized.startsWith(`${normalizedRoot}/`) ? normalized.slice(normalizedRoot.length + 1) : normalized;
|
|
518
|
+
server.config.logger.info(`Gdansk full reload: ${relativePath}`);
|
|
519
|
+
server.ws.send({
|
|
520
|
+
path: "*",
|
|
521
|
+
type: "full-reload"
|
|
522
|
+
});
|
|
523
|
+
};
|
|
524
|
+
server.watcher.on("add", handleChange);
|
|
525
|
+
server.watcher.on("change", handleChange);
|
|
526
|
+
server.watcher.on("unlink", handleChange);
|
|
527
|
+
},
|
|
528
|
+
name: "@gdansk/vite:refresh"
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
async function warmupWidgetEntries(server, widgets) {
|
|
532
|
+
const entries = /* @__PURE__ */ new Set();
|
|
533
|
+
for (const widget of widgets) {
|
|
534
|
+
entries.add(widget.entry);
|
|
535
|
+
entries.add(widget.clientDevEntry);
|
|
536
|
+
}
|
|
537
|
+
await Promise.allSettled([...entries].map(async (entry) => {
|
|
538
|
+
await server.warmupRequest(entry);
|
|
539
|
+
}));
|
|
540
|
+
await server.waitForRequestsIdle?.();
|
|
541
|
+
}
|
|
542
|
+
function normalizeRefreshConfig(refresh) {
|
|
543
|
+
if (!refresh) return [];
|
|
544
|
+
if (refresh === true) return [{ paths: [...DEFAULT_REFRESH_PATHS] }];
|
|
545
|
+
if (typeof refresh === "string") return [{ paths: [refresh] }];
|
|
546
|
+
if (Array.isArray(refresh)) {
|
|
547
|
+
if (refresh.length === 0) return [];
|
|
548
|
+
if (refresh.every((entry) => typeof entry === "string")) return [{ paths: [...refresh] }];
|
|
549
|
+
return refresh.map((entry) => normalizeRefreshEntry(entry));
|
|
550
|
+
}
|
|
551
|
+
return [normalizeRefreshEntry(refresh)];
|
|
552
|
+
}
|
|
553
|
+
function resolveRefreshPaths(refresh, root) {
|
|
554
|
+
return normalizeRefreshConfig(refresh).flatMap((config) => config.paths.map((pattern) => normalizePath(resolve(root, pattern))));
|
|
555
|
+
}
|
|
556
|
+
function hasNamedAlias(aliases, name) {
|
|
557
|
+
return aliases.some((alias) => alias.find === name);
|
|
558
|
+
}
|
|
559
|
+
function normalizeRefreshEntry(config) {
|
|
560
|
+
return { paths: Array.isArray(config.paths) ? [...config.paths] : [config.paths] };
|
|
561
|
+
}
|
|
562
|
+
//#endregion
|
|
365
563
|
//#region src/ssr.ts
|
|
366
564
|
var HEALTH_ENDPOINT = "/health";
|
|
367
565
|
function installDevSSRMiddleware({ options, server, ssrEntry, widgets }) {
|
|
@@ -503,6 +701,6 @@ function writeJson(res, status, payload) {
|
|
|
503
701
|
res.end(JSON.stringify(payload));
|
|
504
702
|
}
|
|
505
703
|
//#endregion
|
|
506
|
-
export {
|
|
704
|
+
export { loadVirtualModule as _, createRefreshPlugin as a, warmupWidgetEntries as c, createBuildConfig as d, readManifest as f, createGdanskVirtualModulesPlugin as g, resolveOptions as h, processSSRRequest as i, resolveViteOrigin as l, prepareProject as m, importRenderFunction as n, mergeAliasConfig as o, loadUserViteConfig as p, installDevSSRMiddleware as r, resolveDevelopmentServerConfig as s, HEALTH_ENDPOINT as t, buildWidgets as u, resolveVirtualModuleId as v };
|
|
507
705
|
|
|
508
|
-
//# sourceMappingURL=ssr-
|
|
706
|
+
//# sourceMappingURL=ssr-C3v_roWy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-C3v_roWy.js","names":[],"sources":["../../src/virtual.ts","../../src/context.ts","../../src/build.ts","../../src/css.ts","../../src/development.ts","../../src/ssr.ts"],"sourcesContent":["import { dirname, relative, resolve, sep } from \"node:path\";\n\nimport type { Plugin } from \"vite\";\n\nimport type { GdanskPreparedProject, ResolvedGdanskOptions, WidgetDefinition } from \"./types\";\n\nexport const GDANSK_DEV_CLIENT_PREFIX = \"/@gdansk/client\";\nexport const GDANSK_SSR_ENTRY_ID = \"virtual:gdansk/ssr-entry\";\n\nconst CLIENT_MODULE_PREFIX = \"virtual:gdansk/client/\";\nconst RESOLVED_VIRTUAL_PREFIX = \"\\0\";\nconst SYNTHETIC_ROOT = \"__gdansk_virtual__\";\n\nexport function createGdanskVirtualModulesPlugin(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n): Plugin {\n return {\n load(id) {\n return loadVirtualModule(options, prepared, id);\n },\n name: \"@gdansk/vite:virtual-modules\",\n resolveId(id, importer) {\n return resolveVirtualModuleId(options, prepared, id, importer);\n },\n };\n}\n\nexport function createClientDevEntry(key: string): string {\n return `${GDANSK_DEV_CLIENT_PREFIX}/${key}.tsx`;\n}\n\nexport function createClientModuleId(key: string): string {\n return `${CLIENT_MODULE_PREFIX}${key}`;\n}\n\nexport function createResolvedClientModuleId(key: string): string {\n return `${RESOLVED_VIRTUAL_PREFIX}${createClientModuleId(key)}`;\n}\n\nexport function resolveVirtualModuleId(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n id: string,\n importer?: string,\n): string | null {\n const widgetByDevEntry = findWidgetByDevEntry(prepared.widgets, id);\n if (widgetByDevEntry) {\n return createResolvedClientModuleId(widgetByDevEntry.key);\n }\n\n const widgetByModuleId = findWidgetByModuleId(prepared.widgets, id);\n if (widgetByModuleId) {\n return createResolvedClientModuleId(widgetByModuleId.key);\n }\n\n if (id === GDANSK_SSR_ENTRY_ID) {\n return resolveSSRModuleId();\n }\n\n if (!importer || !id.startsWith(\".\")) {\n return null;\n }\n\n const syntheticImporterPath = getSyntheticImporterPath(options, prepared, importer);\n if (!syntheticImporterPath) {\n return null;\n }\n\n return resolve(dirname(syntheticImporterPath), id);\n}\n\nexport function loadVirtualModule(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n id: string,\n): string | null {\n const widget = findWidgetByResolvedId(prepared.widgets, id);\n if (widget) {\n return createClientModuleSource(options, widget);\n }\n\n if (id === resolveSSRModuleId()) {\n return createSSRModuleSource(options, prepared.widgets);\n }\n\n return null;\n}\n\nfunction createClientModuleSource(options: ResolvedGdanskOptions, widget: WidgetDefinition): string {\n const syntheticPath = getSyntheticClientPath(options, widget.key);\n const sourceImport = createImportPath(syntheticPath, widget.entry);\n\n return [\n 'import React from \"react\";',\n 'import { createRoot, hydrateRoot } from \"react-dom/client\";',\n `import App from ${JSON.stringify(sourceImport)};`,\n \"\",\n 'const root = document.getElementById(\"root\");',\n \"\",\n \"if (!root) {\",\n \" throw new Error('Gdansk expected a #root element for widget hydration.');\",\n \"}\",\n \"\",\n \"const element = React.createElement(React.StrictMode, null, React.createElement(App));\",\n \"\",\n \"if (root.hasChildNodes()) {\",\n \" hydrateRoot(root, element);\",\n \"} else {\",\n \" createRoot(root).render(element);\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction createSSRModuleSource(options: ResolvedGdanskOptions, widgets: WidgetDefinition[]): string {\n const syntheticPath = getSyntheticSSRPath(options);\n const imports = widgets.map((widget, index) => {\n const specifier = createImportPath(syntheticPath, widget.entry);\n return `import Widget${index} from ${JSON.stringify(specifier)};`;\n });\n const widgetEntries = widgets.map((widget, index) => ` ${JSON.stringify(widget.key)}: Widget${index},`);\n\n return [\n 'import { createElement } from \"react\";',\n 'import { renderToString } from \"react-dom/server\";',\n ...imports,\n \"\",\n \"const widgets = {\",\n ...widgetEntries,\n \"};\",\n \"\",\n \"export default async function renderWidget(widgetKey) {\",\n \" const component = widgets[widgetKey];\",\n \"\",\n \" if (!component) {\",\n \" throw new Error(`Unknown widget: ${widgetKey}`);\",\n \" }\",\n \"\",\n \" return {\",\n \" body: renderToString(createElement(component)),\",\n \" head: [],\",\n \" };\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction createImportPath(from: string, to: string): string {\n const relativePath = toPosixPath(relative(dirname(from), to));\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nfunction findWidgetByDevEntry(widgets: WidgetDefinition[], id: string): WidgetDefinition | undefined {\n return widgets.find((widget) => widget.clientDevEntry === id);\n}\n\nfunction findWidgetByModuleId(widgets: WidgetDefinition[], id: string): WidgetDefinition | undefined {\n return widgets.find((widget) => widget.clientModuleId === id);\n}\n\nfunction findWidgetByResolvedId(widgets: WidgetDefinition[], id: string): WidgetDefinition | undefined {\n return widgets.find((widget) => createResolvedClientModuleId(widget.key) === id);\n}\n\nfunction getSyntheticClientPath(options: ResolvedGdanskOptions, key: string): string {\n return resolve(options.root, SYNTHETIC_ROOT, \"client\", key, \"client.tsx\");\n}\n\nfunction getSyntheticImporterPath(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n importer: string,\n): string | null {\n if (importer === resolveSSRModuleId()) {\n return getSyntheticSSRPath(options);\n }\n\n const widget = findWidgetByResolvedId(prepared.widgets, importer);\n return widget ? getSyntheticClientPath(options, widget.key) : null;\n}\n\nfunction getSyntheticSSRPath(options: ResolvedGdanskOptions): string {\n return resolve(options.root, SYNTHETIC_ROOT, \"ssr-entry.ts\");\n}\n\nfunction resolveSSRModuleId(): string {\n return `${RESOLVED_VIRTUAL_PREFIX}${GDANSK_SSR_ENTRY_ID}`;\n}\n\nfunction toPosixPath(path: string): string {\n return path.split(sep).join(\"/\");\n}\n","import { access, glob as globIterate } from \"node:fs/promises\";\nimport { dirname, join, resolve, sep } from \"node:path\";\n\nimport { loadConfigFromFile, mergeConfig } from \"vite\";\nimport type { Alias, InlineConfig, Plugin, PluginOption } from \"vite\";\n\nimport type {\n GdanskPreparedProject,\n GdanskPluginOptions,\n LoadedProjectConfig,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\nimport { createClientDevEntry, createClientModuleId, GDANSK_SSR_ENTRY_ID } from \"./virtual\";\n\nexport function resolveOptions(options: GdanskPluginOptions = {}, configRoot?: string): ResolvedGdanskOptions {\n const root = resolve(configRoot ?? options.root ?? process.cwd());\n const widgetsDirectory = options.widgetsDirectory ?? \"widgets\";\n const buildDirectory = options.buildDirectory ?? \"dist\";\n const host = options.host ?? \"127.0.0.1\";\n const ssrEndpoint = \"/ssr\";\n\n return {\n buildDirectory,\n buildDirectoryPath: resolve(root, buildDirectory),\n host,\n root,\n ssrEndpoint,\n port: options.port ?? 13714,\n widgetsDirectory,\n widgetsDirectoryPath: resolve(root, widgetsDirectory),\n };\n}\n\nasync function globPaths(pattern: string, options: { absolute?: boolean; cwd: string }): Promise<string[]> {\n const { cwd, absolute = false } = options;\n const matches: string[] = [];\n for await (const entry of globIterate(pattern, { cwd })) {\n matches.push(absolute ? resolve(cwd, entry) : entry);\n }\n return matches;\n}\n\nexport async function discoverWidgets(options: ResolvedGdanskOptions): Promise<WidgetDefinition[]> {\n const entries = await globPaths(\"**/widget.{tsx,jsx}\", {\n cwd: options.widgetsDirectoryPath,\n });\n\n return entries.sort().map((entry) => {\n const widgetPath = toPosixPath(entry);\n const key = toPosixPath(dirname(widgetPath));\n\n return {\n clientCss: toPosixPath(join(options.buildDirectory, key, \"client.css\")),\n clientDevEntry: createClientDevEntry(key),\n clientEntry: toPosixPath(join(options.buildDirectory, key, \"client.js\")),\n clientModuleId: createClientModuleId(key),\n entry: resolve(options.widgetsDirectoryPath, entry),\n key,\n widgetPath,\n };\n });\n}\n\nexport async function loadUserViteConfig(\n options: ResolvedGdanskOptions,\n command: \"build\" | \"serve\",\n): Promise<LoadedProjectConfig> {\n const loaded = await loadConfigFromFile(\n {\n command,\n mode: command === \"build\" ? \"production\" : \"development\",\n },\n undefined,\n options.root,\n );\n const loadedConfig = loaded?.config ?? ({} satisfies InlineConfig);\n const { plugins: _, ...configWithoutPlugins } = loadedConfig;\n\n const plugins = (await normalizePlugins(loadedConfig.plugins)).filter((plugin) => plugin.name !== \"@gdansk/vite\");\n\n return mergeConfig(configWithoutPlugins, {\n plugins,\n root: options.root,\n resolve: {\n ...(loadedConfig.resolve ?? {}),\n alias: mergeDefaultAlias(loadedConfig.resolve?.alias, options.root),\n },\n } satisfies InlineConfig);\n}\n\nexport async function prepareProject(options: ResolvedGdanskOptions): Promise<GdanskPreparedProject> {\n const widgets = await discoverWidgets(options);\n\n return {\n ssrEntryId: GDANSK_SSR_ENTRY_ID,\n widgets,\n };\n}\n\nexport async function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function toPosixPath(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\nasync function normalizePlugins(plugins: PluginOption | PluginOption[] | undefined): Promise<Plugin[]> {\n if (!plugins) {\n return [];\n }\n\n const entries = Array.isArray(plugins) ? plugins : [plugins];\n const normalized: Plugin[] = [];\n\n for (const entry of entries) {\n const plugin = await entry;\n\n if (!plugin) {\n continue;\n }\n\n if (Array.isArray(plugin)) {\n normalized.push(...(await normalizePlugins(plugin)));\n continue;\n }\n\n normalized.push(plugin);\n }\n\n return normalized;\n}\n\ntype AliasOption = NonNullable<NonNullable<InlineConfig[\"resolve\"]>[\"alias\"]>;\n\nfunction mergeDefaultAlias(alias: AliasOption | undefined, root: string): AliasOption {\n if (Array.isArray(alias)) {\n return hasNamedAlias(alias, \"@\") ? alias : [...alias, { find: \"@\", replacement: root }];\n }\n\n if (typeof alias === \"object\" && alias !== null && \"@\" in alias) {\n return alias;\n }\n\n return {\n ...(alias ?? {}),\n \"@\": root,\n };\n}\n\nfunction hasNamedAlias(aliases: Alias[], name: string): boolean {\n return aliases.some((alias) => alias.find === name);\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, posix, resolve } from \"node:path\";\n\nimport { build, mergeConfig } from \"vite\";\nimport type { UserConfig } from \"vite\";\n\nimport { pathExists, toPosixPath } from \"./context\";\nimport type {\n GdanskManifest,\n GdanskPreparedProject,\n LoadedProjectConfig,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\nimport { createGdanskVirtualModulesPlugin, createResolvedClientModuleId } from \"./virtual\";\n\nconst CLIENT_MANIFEST_FILE = \"manifest.json\";\nconst GDANSK_MANIFEST_FILE = \"gdansk-manifest.json\";\nconst SERVER_BUNDLE = \"ssr.js\";\n\ntype ViteManifestEntry = {\n css?: string[];\n file: string;\n};\n\nexport function createBuildConfig(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject): UserConfig {\n return {\n appType: \"custom\",\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n if (prepared.widgets.length > 0) {\n await builder.build(builder.environments.client);\n }\n\n await builder.build(builder.environments.ssr);\n await finalizeBuildOutputs(options, prepared.widgets);\n },\n },\n build: {\n copyPublicDir: false,\n emptyOutDir: true,\n outDir: options.buildDirectory,\n sourcemap: true,\n },\n environments: {\n client: {\n build: createClientBuildOptions(options, prepared),\n },\n ssr: {\n consumer: \"server\",\n build: createSSRBuildOptions(options, prepared),\n },\n },\n };\n}\n\nexport async function buildWidgets(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n config: LoadedProjectConfig = {},\n): Promise<GdanskManifest> {\n await rm(options.buildDirectoryPath, { force: true, recursive: true });\n await mkdir(options.buildDirectoryPath, { recursive: true });\n\n if (prepared.widgets.length > 0) {\n await build(\n mergeConfig(config, {\n appType: \"custom\",\n build: createClientBuildOptions(options, prepared),\n configFile: false,\n plugins: [createGdanskVirtualModulesPlugin(options, prepared)],\n root: options.root,\n }),\n );\n }\n\n await build(\n mergeConfig(config, {\n appType: \"custom\",\n build: createSSRBuildOptions(options, prepared),\n configFile: false,\n plugins: [createGdanskVirtualModulesPlugin(options, prepared)],\n root: options.root,\n }),\n );\n\n return finalizeBuildOutputs(options, prepared.widgets);\n}\n\nexport async function readManifest(path: string): Promise<GdanskManifest> {\n return JSON.parse(await readFile(path, \"utf8\")) as GdanskManifest;\n}\n\nfunction createClientBuildOptions(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n): UserConfig[\"build\"] {\n const inputs =\n prepared.widgets.length > 0\n ? Object.fromEntries(prepared.widgets.map((widget) => [widget.key, widget.clientModuleId]))\n : { __gdansk_empty__: prepared.ssrEntryId };\n\n return {\n copyPublicDir: false,\n cssCodeSplit: true,\n emptyOutDir: true,\n manifest: CLIENT_MANIFEST_FILE,\n outDir: options.buildDirectory,\n rollupOptions: {\n input: inputs,\n output: {\n assetFileNames: (assetInfo: { names?: string[]; originalFileNames?: string[] }) =>\n resolveClientAssetPath(options, prepared.widgets, assetInfo),\n chunkFileNames: \"assets/[name]-[hash].js\",\n entryFileNames: ({ name }) => `${name}/client.js`,\n },\n },\n sourcemap: true,\n };\n}\n\nfunction createSSRBuildOptions(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject): UserConfig[\"build\"] {\n return {\n copyPublicDir: false,\n emptyOutDir: false,\n outDir: options.buildDirectory,\n rollupOptions: {\n input: prepared.ssrEntryId,\n output: {\n chunkFileNames: \"assets/[name]-[hash].js\",\n entryFileNames: SERVER_BUNDLE,\n },\n },\n sourcemap: true,\n ssr: true,\n };\n}\n\nasync function finalizeBuildOutputs(\n options: ResolvedGdanskOptions,\n widgets: WidgetDefinition[],\n): Promise<GdanskManifest> {\n const clientManifest = await readClientManifest(resolve(options.buildDirectoryPath, CLIENT_MANIFEST_FILE));\n\n const manifest: GdanskManifest = {\n outDir: options.buildDirectory,\n root: options.root,\n server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`),\n widgets: Object.fromEntries(\n await Promise.all(\n widgets.map(async (widget) => {\n const manifestEntry = getClientManifestEntry(widget, clientManifest);\n const fallbackCss = (await pathExists(resolve(options.root, widget.clientCss))) ? [widget.clientCss] : [];\n const css = manifestEntry\n ? await normalizeWidgetCssOutputs(options, widget, manifestEntry.css ?? [])\n : fallbackCss;\n\n return [\n widget.key,\n {\n client: manifestEntry ? toBuildPath(options, manifestEntry.file) : widget.clientEntry,\n css,\n entry: widget.widgetPath,\n },\n ];\n }),\n ),\n ),\n };\n\n await writeJson(resolve(options.buildDirectoryPath, GDANSK_MANIFEST_FILE), manifest);\n await writeProductionServer(options);\n\n return manifest;\n}\n\nfunction getClientManifestEntry(\n widget: WidgetDefinition,\n manifest: Record<string, ViteManifestEntry>,\n): ViteManifestEntry | undefined {\n return Object.values(manifest).find((entry) => entry.file === `${widget.key}/client.js`);\n}\n\nasync function readClientManifest(path: string): Promise<Record<string, ViteManifestEntry>> {\n if (!(await pathExists(path))) {\n return {};\n }\n\n return JSON.parse(await readFile(path, \"utf8\")) as Record<string, ViteManifestEntry>;\n}\n\nfunction resolveClientAssetPath(\n options: ResolvedGdanskOptions,\n widgets: WidgetDefinition[],\n assetInfo?: { names?: string[]; originalFileNames?: string[] },\n): string {\n const fileName = assetInfo?.names?.[0] ?? assetInfo?.originalFileNames?.[0] ?? \"\";\n\n if (!fileName.endsWith(\".css\")) {\n return \"assets/[name]-[hash][extname]\";\n }\n\n const candidates = [...(assetInfo?.originalFileNames ?? []), ...(assetInfo?.names ?? [])];\n const widget = findWidgetForAsset(widgets, candidates);\n\n if (!widget) {\n return \"assets/[name]-[hash][extname]\";\n }\n\n return toOutputPath(options, widget.clientCss);\n}\n\nfunction findWidgetForAsset(widgets: WidgetDefinition[], assetCandidates: string[]): WidgetDefinition | undefined {\n return widgets.find((widget) => {\n const normalizedModuleId = toPosixPath(widget.clientModuleId);\n const cssName = `assets/${widget.key}`;\n const cssNameWithExt = `${cssName}.css`;\n\n return assetCandidates.map(toPosixPath).some((normalized) => {\n return (\n normalized === normalizedModuleId ||\n normalized === createResolvedClientModuleId(widget.key) ||\n normalized === cssName ||\n normalized === cssNameWithExt ||\n normalized.endsWith(`/${normalizedModuleId}`) ||\n normalized.endsWith(`/${cssName}`) ||\n normalized.endsWith(`/${cssNameWithExt}`) ||\n normalized.endsWith(`/${widget.key}/client.js`)\n );\n });\n });\n}\n\nasync function normalizeWidgetCssOutputs(\n options: ResolvedGdanskOptions,\n widget: WidgetDefinition,\n hrefs: string[],\n): Promise<string[]> {\n if (hrefs.length !== 1) {\n return hrefs.map((href) => toBuildPath(options, href));\n }\n\n const [href] = hrefs;\n const target = toOutputPath(options, widget.clientCss);\n\n if (href === target || href === widget.clientCss) {\n return [toBuildPath(options, target)];\n }\n\n const sourcePath = resolve(options.buildDirectoryPath, href);\n if (!(await pathExists(sourcePath))) {\n return hrefs.map((entry) => toBuildPath(options, entry));\n }\n\n const targetPath = resolve(options.buildDirectoryPath, target);\n const css = await readFile(sourcePath, \"utf8\");\n const rewrittenCss = rewriteRelativeCssUrls(css, posix.dirname(href), posix.dirname(target));\n\n await mkdir(dirname(targetPath), { recursive: true });\n await writeFile(targetPath, rewrittenCss);\n await rm(sourcePath, { force: true });\n\n return [toBuildPath(options, target)];\n}\n\nfunction rewriteRelativeCssUrls(css: string, fromDir: string, toDir: string): string {\n if (fromDir === toDir) {\n return css;\n }\n\n return css.replace(/url\\((['\"]?)([^'\")]+)\\1\\)/g, (_match, quote: string, value: string) => {\n if (value.startsWith(\"/\") || value.startsWith(\"#\") || value.startsWith(\"data:\") || /^[a-z]+:/i.test(value)) {\n return `url(${quote}${value}${quote})`;\n }\n\n const [pathPart, suffix = \"\"] = splitCssUrl(value);\n const fromPath = posix.join(\"/\", fromDir, pathPart);\n let relativePath = posix.relative(posix.join(\"/\", toDir), fromPath);\n\n if (!relativePath) {\n relativePath = \".\";\n } else if (!relativePath.startsWith(\".\")) {\n relativePath = `./${relativePath}`;\n }\n\n return `url(${quote}${relativePath}${suffix}${quote})`;\n });\n}\n\nfunction splitCssUrl(value: string): [string, string] {\n const match = /^([^?#]+)(.*)$/.exec(value);\n return match ? [match[1], match[2]] : [value, \"\"];\n}\n\nasync function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction toOutputPath(options: ResolvedGdanskOptions, path: string): string {\n const prefix = `${options.buildDirectory}/`;\n\n if (path.startsWith(prefix)) {\n return path.slice(prefix.length);\n }\n\n return path;\n}\n\nfunction toBuildPath(options: ResolvedGdanskOptions, path: string): string {\n return path.startsWith(`${options.buildDirectory}/`) ? path : `${options.buildDirectory}/${path.replace(/^\\/+/, \"\")}`;\n}\n\nasync function writeProductionServer(options: ResolvedGdanskOptions): Promise<void> {\n const path = resolve(options.buildDirectoryPath, \"server.js\");\n const runtimeModuleUrl = new URL(\"../runtime.js\", import.meta.url).href;\n const runtimeOptions = {\n buildDirectory: options.buildDirectory,\n host: options.host,\n port: options.port,\n widgetsDirectory: options.widgetsDirectory,\n };\n\n await writeFile(\n path,\n [\n 'import { dirname, resolve } from \"node:path\";',\n 'import { fileURLToPath } from \"node:url\";',\n `import { createGdanskRuntime } from \"${runtimeModuleUrl}\";`,\n \"\",\n \"const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');\",\n `const runtime = await createGdanskRuntime({ ...${JSON.stringify(runtimeOptions)}, root });`,\n \"await runtime.startProductionServer();\",\n \"await new Promise(() => {});\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n","import type { EnvironmentModuleNode, ViteDevServer } from \"vite\";\nimport { normalizePath } from \"vite\";\n\nexport function collectCSSFromModuleGraph(server: ViteDevServer, entry: string): string[] {\n const entryModule = resolveEntryModule(server, entry);\n\n if (!entryModule) {\n return [];\n }\n\n const cssModules = collectCSSModules(entryModule);\n\n if (cssModules.length === 0) {\n return [];\n }\n\n const origin = resolveViteOrigin(server);\n const base = server.config.base === \"/\" ? \"\" : server.config.base.replace(/\\/$/, \"\");\n\n return cssModules.map(({ id, url }) => {\n const devId = id ? ` data-vite-dev-id=\"${id}\"` : \"\";\n return `<link rel=\"stylesheet\" href=\"${origin}${base}${url}\"${devId}>`;\n });\n}\n\nexport function resolveViteOrigin(server: ViteDevServer): string {\n const origin = server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];\n\n if (origin) {\n return new URL(origin).origin;\n }\n\n const protocol = server.config.server.https ? \"https\" : \"http\";\n return `${protocol}://${server.config.server.host ?? \"127.0.0.1\"}:${server.config.server.port ?? 5173}`;\n}\n\nfunction collectCSSModules(entryModule: EnvironmentModuleNode): Array<{ id: string | null; url: string }> {\n const cssModules: Array<{ id: string | null; url: string }> = [];\n const visited = new Set<EnvironmentModuleNode>();\n\n const walk = (mod: EnvironmentModuleNode): void => {\n if (visited.has(mod)) {\n return;\n }\n\n visited.add(mod);\n\n if (isCssRequest(mod.url)) {\n cssModules.push({ id: mod.id, url: mod.url });\n return;\n }\n\n for (const imported of mod.importedModules) {\n walk(imported);\n }\n };\n\n walk(entryModule);\n\n return cssModules;\n}\n\nfunction isCssRequest(url: string): boolean {\n return /\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\\?)/.test(url);\n}\n\nfunction resolveEntryModule(server: ViteDevServer, entry: string): EnvironmentModuleNode | undefined {\n const moduleGraph = server.environments.ssr.moduleGraph;\n const normalized = normalizePath(entry);\n\n return moduleGraph.getModuleById(normalized) ?? moduleGraph.getModuleById(entry);\n}\n","import { matchesGlob, resolve } from \"node:path\";\n\nimport { normalizePath, type Alias, type Plugin, type UserConfig, type ViteDevServer } from \"vite\";\n\nimport { resolveOptions } from \"./context\";\nimport type { GdanskPluginOptions, RefreshConfig, ResolvedGdanskOptions, WidgetDefinition } from \"./types\";\n\ntype AliasOption = NonNullable<NonNullable<UserConfig[\"resolve\"]>[\"alias\"]>;\n\nconst DEFAULT_REFRESH_PATHS = [\"../**/*.py\", \"../**/*.j2\", \"../**/*.jinja\", \"../**/*.jinja2\"];\n\nexport function mergeAliasConfig(alias: AliasOption | undefined, root: string): AliasOption {\n if (Array.isArray(alias)) {\n return hasNamedAlias(alias, \"@\") ? alias : [...alias, { find: \"@\", replacement: root }];\n }\n\n if (typeof alias === \"object\" && alias !== null && \"@\" in alias) {\n return alias;\n }\n\n return {\n ...(alias ?? {}),\n \"@\": root,\n };\n}\n\nexport function resolveDevelopmentServerConfig(\n options: GdanskPluginOptions,\n resolved: ResolvedGdanskOptions,\n): UserConfig[\"server\"] | undefined {\n if (typeof options.host === \"undefined\" && typeof options.port === \"undefined\") {\n return undefined;\n }\n\n return {\n host: resolved.host,\n port: resolved.port,\n strictPort: true,\n };\n}\n\nexport function createRefreshPlugin(options: GdanskPluginOptions = {}): Plugin {\n return {\n apply: \"serve\",\n configureServer(server) {\n const resolved = resolveOptions(options, server.config.root);\n const normalizedRoot = normalizePath(resolved.root);\n const patterns = resolveRefreshPaths(options.refresh, resolved.root);\n let ready = false;\n\n if (patterns.length === 0) {\n return;\n }\n\n server.watcher.add(patterns);\n server.watcher.on(\"ready\", () => {\n ready = true;\n });\n\n const handleChange = (file: string): void => {\n if (!ready) {\n return;\n }\n\n const normalized = normalizePath(file);\n\n if (!patterns.some((pattern) => matchesGlob(normalized, pattern))) {\n return;\n }\n\n const relativePath = normalized.startsWith(`${normalizedRoot}/`)\n ? normalized.slice(normalizedRoot.length + 1)\n : normalized;\n\n server.config.logger.info(`Gdansk full reload: ${relativePath}`);\n server.ws.send({ path: \"*\", type: \"full-reload\" });\n };\n\n server.watcher.on(\"add\", handleChange);\n server.watcher.on(\"change\", handleChange);\n server.watcher.on(\"unlink\", handleChange);\n },\n name: \"@gdansk/vite:refresh\",\n };\n}\n\nexport async function warmupWidgetEntries(server: ViteDevServer, widgets: WidgetDefinition[]): Promise<void> {\n const entries = new Set<string>();\n\n for (const widget of widgets) {\n entries.add(widget.entry);\n entries.add(widget.clientDevEntry);\n }\n\n await Promise.allSettled(\n [...entries].map(async (entry) => {\n await server.warmupRequest(entry);\n }),\n );\n\n await server.waitForRequestsIdle?.();\n}\n\nexport function normalizeRefreshConfig(refresh: GdanskPluginOptions[\"refresh\"]): Array<{ paths: string[] }> {\n if (!refresh) {\n return [];\n }\n\n if (refresh === true) {\n return [{ paths: [...DEFAULT_REFRESH_PATHS] }];\n }\n\n if (typeof refresh === \"string\") {\n return [{ paths: [refresh] }];\n }\n\n if (Array.isArray(refresh)) {\n if (refresh.length === 0) {\n return [];\n }\n\n if (refresh.every((entry) => typeof entry === \"string\")) {\n return [{ paths: [...refresh] }];\n }\n\n return refresh.map((entry) => normalizeRefreshEntry(entry as RefreshConfig));\n }\n\n return [normalizeRefreshEntry(refresh)];\n}\n\nexport function resolveRefreshPaths(refresh: GdanskPluginOptions[\"refresh\"], root: string): string[] {\n return normalizeRefreshConfig(refresh).flatMap((config) =>\n config.paths.map((pattern) => normalizePath(resolve(root, pattern))),\n );\n}\n\nfunction hasNamedAlias(aliases: Alias[], name: string): boolean {\n return aliases.some((alias) => alias.find === name);\n}\n\nfunction normalizeRefreshEntry(config: RefreshConfig): { paths: string[] } {\n return {\n paths: Array.isArray(config.paths) ? [...config.paths] : [config.paths],\n };\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { ViteDevServer } from \"vite\";\n\nimport { collectCSSFromModuleGraph } from \"./css\";\nimport type {\n GdanskManifest,\n GdanskRenderFunction,\n GdanskRenderRequest,\n GdanskRenderResponse,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\n\nexport const HEALTH_ENDPOINT = \"/health\";\n\ntype GdanskErrorResponse = {\n error: {\n message: string;\n type: \"invalid_json\" | \"invalid_request\" | \"render_error\" | \"unknown_widget\";\n };\n};\n\ntype GdanskResponsePayload = GdanskErrorResponse | GdanskRenderResponse;\n\ntype ProcessSSRRequestOptions = {\n manifest?: GdanskManifest;\n render: GdanskRenderFunction;\n requestBody: string;\n viteServer?: ViteDevServer;\n widgets: WidgetDefinition[];\n};\n\ntype ProcessSSRRequestResult = {\n payload: GdanskResponsePayload;\n status: 200 | 400 | 404 | 500;\n};\n\ntype InstallDevSSRMiddlewareOptions = {\n options: ResolvedGdanskOptions;\n server: ViteDevServer;\n ssrEntry: string;\n widgets: WidgetDefinition[];\n};\n\nexport function installDevSSRMiddleware({ options, server, ssrEntry, widgets }: InstallDevSSRMiddlewareOptions): void {\n server.middlewares.use(HEALTH_ENDPOINT, (req, res, next) => {\n if (req.method !== \"GET\") {\n next();\n return;\n }\n\n writeJson(res, 200, { status: \"OK\" });\n });\n\n server.middlewares.use(options.ssrEndpoint, async (req, res, next) => {\n if (req.method !== \"POST\") {\n next();\n return;\n }\n\n try {\n const requestBody = await readRequestBody(req);\n const render = await loadRenderFunction(server, ssrEntry);\n const result = await processSSRRequest({\n render,\n requestBody,\n viteServer: server,\n widgets,\n });\n\n writeJson(res, result.status, result.payload);\n } catch (error) {\n writeJson(res, 500, createErrorResponse(error, \"render_error\"));\n }\n });\n\n server.config.logger.info(`Gdansk SSR dev endpoint: ${options.ssrEndpoint}`);\n\n server.httpServer?.once(\"listening\", () => {\n server.config.logger.info(\"Warming up Gdansk SSR module graph...\");\n\n server\n .ssrLoadModule(ssrEntry)\n .then(() => server.config.logger.info(\"Gdansk SSR module graph warmed up\"))\n .catch((error) => {\n server.config.logger.warn(`Failed to warm up Gdansk SSR module graph: ${getErrorMessage(error)}`);\n });\n });\n}\n\nexport async function importRenderFunction(path: string): Promise<GdanskRenderFunction> {\n const module = (await import(path)) as { default?: unknown };\n return resolveRenderFunction(module.default, path);\n}\n\nexport async function processSSRRequest({\n manifest,\n render,\n requestBody,\n viteServer,\n widgets,\n}: ProcessSSRRequestOptions): Promise<ProcessSSRRequestResult> {\n let payload: GdanskRenderRequest;\n\n try {\n payload = JSON.parse(requestBody) as GdanskRenderRequest;\n } catch (error) {\n return {\n payload: createErrorResponse(error, \"invalid_json\"),\n status: 400,\n };\n }\n\n const widgetKey = payload.widget ?? payload.component;\n\n if (!widgetKey) {\n return {\n payload: createErrorResponse('Request body must include \"widget\" or \"component\"', \"invalid_request\"),\n status: 400,\n };\n }\n\n const widget = widgets.find((candidate) => candidate.key === widgetKey);\n\n if (!widget) {\n return {\n payload: createErrorResponse(`Unknown widget: ${widgetKey}`, \"unknown_widget\"),\n status: 404,\n };\n }\n\n try {\n const rendered = await Promise.resolve(render(widget.key));\n const response = validateRenderResponse(rendered);\n const assetBaseUrl = payload.assetBaseUrl;\n const head = viteServer\n ? [...collectCSSFromModuleGraph(viteServer, widget.entry), ...response.head]\n : [...createProductionCssHead(assetBaseUrl, manifest, widget.key), ...response.head];\n\n return {\n payload: {\n body: response.body,\n head,\n },\n status: 200,\n };\n } catch (error) {\n return {\n payload: createErrorResponse(error, \"render_error\"),\n status: 500,\n };\n }\n}\n\nasync function loadRenderFunction(server: ViteDevServer, entry: string): Promise<GdanskRenderFunction> {\n const module = (await server.ssrLoadModule(entry)) as { default?: unknown };\n return resolveRenderFunction(module.default, entry);\n}\n\nfunction resolveRenderFunction(candidate: unknown, entry: string): GdanskRenderFunction {\n if (typeof candidate !== \"function\") {\n throw new Error(`SSR entry \"${entry}\" must export a render function`);\n }\n\n return candidate as GdanskRenderFunction;\n}\n\nfunction validateRenderResponse(result: unknown): GdanskRenderResponse {\n if (!result || typeof result !== \"object\") {\n throw new Error(\"SSR render must return { head: string[], body: string }\");\n }\n\n const body = Reflect.get(result, \"body\");\n const head = Reflect.get(result, \"head\");\n\n if (typeof body !== \"string\" || !Array.isArray(head) || !head.every((value) => typeof value === \"string\")) {\n throw new Error(\"SSR render must return { head: string[], body: string }\");\n }\n\n return {\n body,\n head,\n };\n}\n\nfunction createProductionCssHead(\n assetBaseUrl: string | undefined,\n manifest: GdanskManifest | undefined,\n widgetKey: string,\n): string[] {\n if (!manifest) {\n return [];\n }\n\n const widget = manifest.widgets[widgetKey];\n\n if (!widget) {\n throw new Error(`Widget \"${widgetKey}\" is not present in the production manifest`);\n }\n\n return widget.css.map((href) => {\n if (assetBaseUrl) {\n return `<link rel=\"stylesheet\" href=\"${toAbsoluteAssetPath(assetBaseUrl, manifest.outDir, href)}\">`;\n }\n\n return `<link rel=\"stylesheet\" href=\"${toRootRelativeAssetPath(manifest.outDir, href)}\">`;\n });\n}\n\nfunction toAbsoluteAssetPath(assetBaseUrl: string, outDir: string, href: string): string {\n return new URL(stripOutDirPrefix(outDir, href), `${assetBaseUrl.replace(/\\/+$/g, \"\")}/`).toString();\n}\n\nfunction toRootRelativeAssetPath(outDir: string, href: string): string {\n const normalizedOutDir = outDir.replace(/^\\/+|\\/+$/g, \"\");\n const normalizedPath = stripOutDirPrefix(outDir, href);\n return `/${[normalizedOutDir, normalizedPath].filter(Boolean).join(\"/\")}`;\n}\n\nfunction stripOutDirPrefix(outDir: string, href: string): string {\n const normalized = href.replace(/^\\/+/, \"\");\n const prefix = `${outDir.replace(/^\\/+|\\/+$/g, \"\")}/`;\n\n return normalized.startsWith(prefix) ? normalized.slice(prefix.length) : normalized;\n}\n\nfunction createErrorResponse(error: unknown, type: GdanskErrorResponse[\"error\"][\"type\"]): GdanskErrorResponse {\n return {\n error: {\n message: getErrorMessage(error),\n type,\n },\n };\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = \"\";\n\n req.on(\"data\", (chunk) => {\n data += chunk;\n });\n req.on(\"end\", () => {\n resolve(data);\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, payload: unknown): void {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(payload));\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { _ as loadVirtualModule, a as createRefreshPlugin, c as warmupWidgetEntries, d as createBuildConfig, h as resolveOptions, l as resolveViteOrigin, m as prepareProject, o as mergeAliasConfig, r as installDevSSRMiddleware, s as resolveDevelopmentServerConfig, v as resolveVirtualModuleId } from "./assets/ssr-C3v_roWy.js";
|
|
2
|
+
import { mergeConfig } from "vite";
|
|
2
3
|
//#region src/plugin.ts
|
|
3
4
|
function gdansk(options = {}) {
|
|
4
5
|
let prepared;
|
|
@@ -12,24 +13,35 @@ function gdansk(options = {}) {
|
|
|
12
13
|
});
|
|
13
14
|
return preparePromise;
|
|
14
15
|
};
|
|
15
|
-
return {
|
|
16
|
+
return [{
|
|
16
17
|
async config(config, env) {
|
|
17
18
|
resolved = resolveOptions(options, config.root);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const sharedConfig = createSharedConfig(config, options, resolved);
|
|
20
|
+
if (env.command === "build") {
|
|
21
|
+
const project = await ensurePrepared(config.root);
|
|
22
|
+
return mergeConfig(sharedConfig, createBuildConfig(resolved, project));
|
|
23
|
+
}
|
|
24
|
+
return sharedConfig;
|
|
21
25
|
},
|
|
22
26
|
async configResolved(config) {
|
|
23
27
|
await ensurePrepared(config.root);
|
|
24
28
|
},
|
|
29
|
+
async load(id) {
|
|
30
|
+
const project = prepared ?? await ensurePrepared(resolved?.root);
|
|
31
|
+
return loadVirtualModule(resolved ?? resolveOptions(options), project, id);
|
|
32
|
+
},
|
|
25
33
|
name: "@gdansk/vite",
|
|
34
|
+
async resolveId(id, importer) {
|
|
35
|
+
const project = prepared ?? await ensurePrepared(resolved?.root);
|
|
36
|
+
return resolveVirtualModuleId(resolved ?? resolveOptions(options), project, id, importer);
|
|
37
|
+
},
|
|
26
38
|
async configureServer(server) {
|
|
27
39
|
const project = prepared ?? await ensurePrepared(server.config.root);
|
|
28
40
|
const resolvedOptions = resolved ?? resolveOptions(options, server.config.root);
|
|
29
41
|
installDevSSRMiddleware({
|
|
30
42
|
options: resolvedOptions,
|
|
31
43
|
server,
|
|
32
|
-
ssrEntry: project.
|
|
44
|
+
ssrEntry: project.ssrEntryId,
|
|
33
45
|
widgets: project.widgets
|
|
34
46
|
});
|
|
35
47
|
const updateMetadata = () => {
|
|
@@ -38,13 +50,35 @@ function gdansk(options = {}) {
|
|
|
38
50
|
ssrOrigin: resolveViteOrigin(server)
|
|
39
51
|
};
|
|
40
52
|
};
|
|
53
|
+
const warmupWidgets = () => {
|
|
54
|
+
warmupWidgetEntries(server, project.widgets);
|
|
55
|
+
};
|
|
41
56
|
const clearMetadata = () => {
|
|
42
57
|
delete server.__gdansk;
|
|
43
58
|
};
|
|
44
|
-
if (server.httpServer?.listening)
|
|
45
|
-
|
|
59
|
+
if (server.httpServer?.listening) {
|
|
60
|
+
updateMetadata();
|
|
61
|
+
warmupWidgets();
|
|
62
|
+
} else {
|
|
63
|
+
server.httpServer?.once("listening", updateMetadata);
|
|
64
|
+
server.httpServer?.once("listening", warmupWidgets);
|
|
65
|
+
}
|
|
46
66
|
server.httpServer?.once("close", clearMetadata);
|
|
47
67
|
}
|
|
68
|
+
}, createRefreshPlugin(options)];
|
|
69
|
+
}
|
|
70
|
+
function createSharedConfig(config, options, resolved) {
|
|
71
|
+
const server = resolveDevelopmentServerConfig(options, resolved);
|
|
72
|
+
return {
|
|
73
|
+
appType: "custom",
|
|
74
|
+
resolve: {
|
|
75
|
+
...config.resolve ?? {},
|
|
76
|
+
alias: mergeAliasConfig(config.resolve?.alias, resolved.root)
|
|
77
|
+
},
|
|
78
|
+
...server ? { server: {
|
|
79
|
+
...config.server ?? {},
|
|
80
|
+
...server
|
|
81
|
+
} } : {}
|
|
48
82
|
};
|
|
49
83
|
}
|
|
50
84
|
//#endregion
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import type
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import { mergeConfig, type Plugin, type PluginOption, type UserConfig, type ViteDevServer } from \"vite\";\n\nimport { createBuildConfig } from \"./build\";\nimport { prepareProject, resolveOptions } from \"./context\";\nimport { resolveViteOrigin } from \"./css\";\nimport {\n createRefreshPlugin,\n mergeAliasConfig,\n resolveDevelopmentServerConfig,\n warmupWidgetEntries,\n} from \"./development\";\nimport { installDevSSRMiddleware } from \"./ssr\";\nimport type { GdanskPluginOptions, GdanskPreparedProject, ResolvedGdanskOptions } from \"./types\";\nimport { loadVirtualModule, resolveVirtualModuleId } from \"./virtual\";\n\ntype GdanskDevServerMetadata = {\n ssrEndpoint: string;\n ssrOrigin: string;\n};\n\ntype GdanskDevServer = ViteDevServer & {\n __gdansk?: GdanskDevServerMetadata;\n};\n\nexport function gdansk(options: GdanskPluginOptions = {}): PluginOption {\n let prepared: GdanskPreparedProject | undefined;\n let preparePromise: Promise<GdanskPreparedProject> | undefined;\n let resolved: ResolvedGdanskOptions | undefined;\n\n const ensurePrepared = (configRoot?: string): Promise<GdanskPreparedProject> => {\n resolved = resolveOptions(options, configRoot);\n preparePromise ??= prepareProject(resolved).then((result) => {\n prepared = result;\n return result;\n });\n return preparePromise;\n };\n\n const corePlugin: Plugin = {\n async config(config, env) {\n resolved = resolveOptions(options, config.root);\n const sharedConfig = createSharedConfig(config, options, resolved);\n\n if (env.command === \"build\") {\n const project = await ensurePrepared(config.root);\n return mergeConfig(sharedConfig, createBuildConfig(resolved, project));\n }\n\n return sharedConfig;\n },\n async configResolved(config) {\n await ensurePrepared(config.root);\n },\n async load(id) {\n const project = prepared ?? (await ensurePrepared(resolved?.root));\n const resolvedOptions = resolved ?? resolveOptions(options);\n return loadVirtualModule(resolvedOptions, project, id);\n },\n name: \"@gdansk/vite\",\n async resolveId(id, importer) {\n const project = prepared ?? (await ensurePrepared(resolved?.root));\n const resolvedOptions = resolved ?? resolveOptions(options);\n return resolveVirtualModuleId(resolvedOptions, project, id, importer);\n },\n async configureServer(server) {\n const project = prepared ?? (await ensurePrepared(server.config.root));\n const resolvedOptions = resolved ?? resolveOptions(options, server.config.root);\n\n installDevSSRMiddleware({\n options: resolvedOptions,\n server,\n ssrEntry: project.ssrEntryId,\n widgets: project.widgets,\n });\n\n const updateMetadata = (): void => {\n (server as GdanskDevServer).__gdansk = {\n ssrEndpoint: resolvedOptions.ssrEndpoint,\n ssrOrigin: resolveViteOrigin(server),\n };\n };\n\n const warmupWidgets = (): void => {\n void warmupWidgetEntries(server, project.widgets);\n };\n\n const clearMetadata = (): void => {\n delete (server as GdanskDevServer).__gdansk;\n };\n\n if (server.httpServer?.listening) {\n updateMetadata();\n warmupWidgets();\n } else {\n server.httpServer?.once(\"listening\", updateMetadata);\n server.httpServer?.once(\"listening\", warmupWidgets);\n }\n\n server.httpServer?.once(\"close\", clearMetadata);\n },\n };\n\n return [corePlugin, createRefreshPlugin(options)];\n}\n\nfunction createSharedConfig(\n config: UserConfig,\n options: GdanskPluginOptions,\n resolved: ResolvedGdanskOptions,\n): UserConfig {\n const server = resolveDevelopmentServerConfig(options, resolved);\n\n return {\n appType: \"custom\",\n resolve: {\n ...(config.resolve ?? {}),\n alias: mergeAliasConfig(config.resolve?.alias, resolved.root),\n },\n ...(server\n ? {\n server: {\n ...(config.server ?? {}),\n ...server,\n },\n }\n : {}),\n };\n}\n"],"mappings":";;;AAwBA,SAAgB,OAAO,UAA+B,EAAE,EAAgB;CACtE,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,kBAAkB,eAAwD;AAC9E,aAAW,eAAe,SAAS,WAAW;AAC9C,qBAAmB,eAAe,SAAS,CAAC,MAAM,WAAW;AAC3D,cAAW;AACX,UAAO;IACP;AACF,SAAO;;AAmET,QAAO,CAhEoB;EACzB,MAAM,OAAO,QAAQ,KAAK;AACxB,cAAW,eAAe,SAAS,OAAO,KAAK;GAC/C,MAAM,eAAe,mBAAmB,QAAQ,SAAS,SAAS;AAElE,OAAI,IAAI,YAAY,SAAS;IAC3B,MAAM,UAAU,MAAM,eAAe,OAAO,KAAK;AACjD,WAAO,YAAY,cAAc,kBAAkB,UAAU,QAAQ,CAAC;;AAGxE,UAAO;;EAET,MAAM,eAAe,QAAQ;AAC3B,SAAM,eAAe,OAAO,KAAK;;EAEnC,MAAM,KAAK,IAAI;GACb,MAAM,UAAU,YAAa,MAAM,eAAe,UAAU,KAAK;AAEjE,UAAO,kBADiB,YAAY,eAAe,QAAQ,EACjB,SAAS,GAAG;;EAExD,MAAM;EACN,MAAM,UAAU,IAAI,UAAU;GAC5B,MAAM,UAAU,YAAa,MAAM,eAAe,UAAU,KAAK;AAEjE,UAAO,uBADiB,YAAY,eAAe,QAAQ,EACZ,SAAS,IAAI,SAAS;;EAEvE,MAAM,gBAAgB,QAAQ;GAC5B,MAAM,UAAU,YAAa,MAAM,eAAe,OAAO,OAAO,KAAK;GACrE,MAAM,kBAAkB,YAAY,eAAe,SAAS,OAAO,OAAO,KAAK;AAE/E,2BAAwB;IACtB,SAAS;IACT;IACA,UAAU,QAAQ;IAClB,SAAS,QAAQ;IAClB,CAAC;GAEF,MAAM,uBAA6B;AAChC,WAA2B,WAAW;KACrC,aAAa,gBAAgB;KAC7B,WAAW,kBAAkB,OAAO;KACrC;;GAGH,MAAM,sBAA4B;AAC3B,wBAAoB,QAAQ,QAAQ,QAAQ;;GAGnD,MAAM,sBAA4B;AAChC,WAAQ,OAA2B;;AAGrC,OAAI,OAAO,YAAY,WAAW;AAChC,oBAAgB;AAChB,mBAAe;UACV;AACL,WAAO,YAAY,KAAK,aAAa,eAAe;AACpD,WAAO,YAAY,KAAK,aAAa,cAAc;;AAGrD,UAAO,YAAY,KAAK,SAAS,cAAc;;EAElD,EAEmB,oBAAoB,QAAQ,CAAC;;AAGnD,SAAS,mBACP,QACA,SACA,UACY;CACZ,MAAM,SAAS,+BAA+B,SAAS,SAAS;AAEhE,QAAO;EACL,SAAS;EACT,SAAS;GACP,GAAI,OAAO,WAAW,EAAE;GACxB,OAAO,iBAAiB,OAAO,SAAS,OAAO,SAAS,KAAK;GAC9D;EACD,GAAI,SACA,EACE,QAAQ;GACN,GAAI,OAAO,UAAU,EAAE;GACvB,GAAG;GACJ,EACF,GACD,EAAE;EACP"}
|
package/dist/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as createRefreshPlugin, f as readManifest, g as createGdanskVirtualModulesPlugin, h as resolveOptions, i as processSSRRequest, l as resolveViteOrigin, m as prepareProject, n as importRenderFunction, p as loadUserViteConfig, r as installDevSSRMiddleware, t as HEALTH_ENDPOINT, u as buildWidgets } from "./assets/ssr-C3v_roWy.js";
|
|
2
|
+
import { createServer, mergeConfig } from "vite";
|
|
2
3
|
import { stat } from "node:fs/promises";
|
|
3
4
|
import { resolve } from "node:path";
|
|
4
|
-
import { createServer, mergeConfig } from "vite";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
import { serve } from "@hono/node-server";
|
|
7
7
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
@@ -9,7 +9,7 @@ import { Hono } from "hono";
|
|
|
9
9
|
//#region src/server.ts
|
|
10
10
|
async function startGdanskServer(options) {
|
|
11
11
|
const app = new Hono();
|
|
12
|
-
const outDirPrefix = `/${options.options.
|
|
12
|
+
const outDirPrefix = `/${options.options.buildDirectory.replace(/^\/+/, "")}`;
|
|
13
13
|
app.get(HEALTH_ENDPOINT, (c) => c.json({ status: "OK" }));
|
|
14
14
|
app.post(options.options.ssrEndpoint, async (c) => {
|
|
15
15
|
const requestBody = await c.req.text();
|
|
@@ -69,7 +69,7 @@ var GdanskRuntimeImpl = class {
|
|
|
69
69
|
#server;
|
|
70
70
|
#viteServer;
|
|
71
71
|
constructor(options) {
|
|
72
|
-
this.manifestPath = `${options.
|
|
72
|
+
this.manifestPath = `${options.buildDirectoryPath}/gdansk-manifest.json`;
|
|
73
73
|
this.options = options;
|
|
74
74
|
}
|
|
75
75
|
async build() {
|
|
@@ -93,6 +93,7 @@ var GdanskRuntimeImpl = class {
|
|
|
93
93
|
this.#viteServer = await createServer(mergeConfig(await loadUserViteConfig(this.options, "serve"), {
|
|
94
94
|
appType: "custom",
|
|
95
95
|
configFile: false,
|
|
96
|
+
plugins: [createGdanskVirtualModulesPlugin(this.options, prepared), createRefreshPlugin(this.options)],
|
|
96
97
|
root: this.options.root,
|
|
97
98
|
server: {
|
|
98
99
|
host: this.options.host,
|
|
@@ -103,7 +104,7 @@ var GdanskRuntimeImpl = class {
|
|
|
103
104
|
installDevSSRMiddleware({
|
|
104
105
|
options: this.options,
|
|
105
106
|
server: this.#viteServer,
|
|
106
|
-
ssrEntry: prepared.
|
|
107
|
+
ssrEntry: prepared.ssrEntryId,
|
|
107
108
|
widgets: prepared.widgets
|
|
108
109
|
});
|
|
109
110
|
await this.#viteServer.listen();
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","names":["#manifest","#server","#viteServer","#prepared"],"sources":["../src/server.ts","../src/runtime.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { Hono } from \"hono\";\n\nimport { HEALTH_ENDPOINT, processSSRRequest } from \"./ssr\";\nimport type { GdanskServerHandle, GdanskServerOptions } from \"./types\";\n\nexport async function startGdanskServer(options: GdanskServerOptions): Promise<GdanskServerHandle> {\n const app = new Hono();\n const outDirPrefix = `/${options.options.outDir.replace(/^\\/+/, \"\")}`;\n\n app.get(HEALTH_ENDPOINT, (c) => c.json({ status: \"OK\" }));\n\n app.post(options.options.ssrEndpoint, async (c) => {\n const requestBody = await c.req.text();\n const result = await processSSRRequest({\n manifest: options.manifest,\n render: options.render,\n requestBody,\n widgets: options.widgets,\n });\n\n return c.json(result.payload, result.status);\n });\n\n app.use(\n `${outDirPrefix}/*`,\n serveStatic({\n onFound: (_, c) => {\n c.header(\"Access-Control-Allow-Origin\", \"*\");\n c.header(\"Cache-Control\", \"public, max-age=31536000, immutable\");\n },\n root: options.options.root,\n }),\n );\n\n let resolvedPort = options.options.port;\n\n const server = await new Promise<ReturnType<typeof serve>>((resolveServer) => {\n const instance = serve(\n {\n fetch: app.fetch,\n hostname: options.options.host,\n port: options.options.port,\n },\n (info) => {\n resolvedPort = info.port;\n resolveServer(instance);\n },\n );\n });\n\n const origin = `http://${options.options.host}:${resolvedPort}`;\n\n return {\n close: () =>\n new Promise<void>((resolveClose, rejectClose) => {\n server.close((error) => {\n if (error) {\n rejectClose(error);\n return;\n }\n\n resolveClose();\n });\n }),\n origin,\n port: resolvedPort,\n };\n}\n","import { stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { createServer, mergeConfig } from \"vite\";\n\nimport { buildWidgets, readManifest } from \"./build\";\nimport { loadUserViteConfig, prepareProject, resolveOptions } from \"./context\";\nimport { resolveViteOrigin } from \"./css\";\nimport { startGdanskServer } from \"./server\";\nimport { installDevSSRMiddleware, importRenderFunction } from \"./ssr\";\nimport type {\n GdanskManifest,\n GdanskPluginOptions,\n GdanskPreparedProject,\n GdanskRuntime,\n GdanskRuntimeMetadata,\n GdanskServerHandle,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\n\nexport async function createGdanskRuntime(options: GdanskPluginOptions = {}): Promise<GdanskRuntime> {\n const resolved = resolveOptions(options);\n const runtime = new GdanskRuntimeImpl(resolved);\n await runtime.refreshWidgets();\n return runtime;\n}\n\nclass GdanskRuntimeImpl implements GdanskRuntime {\n readonly manifestPath: string;\n readonly options: ResolvedGdanskOptions;\n widgets: WidgetDefinition[] = [];\n\n #manifest?: GdanskManifest;\n #prepared?: GdanskPreparedProject;\n #server?: GdanskServerHandle;\n #viteServer?: Awaited<ReturnType<typeof createServer>>;\n\n constructor(options: ResolvedGdanskOptions) {\n this.manifestPath = `${options.outDirPath}/manifest.json`;\n this.options = options;\n }\n\n async build(): Promise<GdanskManifest> {\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"build\");\n\n this.#manifest = await buildWidgets(this.options, prepared, config);\n\n return this.#manifest;\n }\n\n async close(): Promise<void> {\n await this.#server?.close();\n this.#server = undefined;\n\n await this.#viteServer?.close();\n this.#viteServer = undefined;\n }\n\n async refreshWidgets(): Promise<void> {\n const prepared = await this.prepare();\n this.widgets = prepared.widgets;\n }\n\n async startDev(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"serve\");\n\n this.#viteServer = await createServer(\n mergeConfig(config, {\n appType: \"custom\",\n configFile: false,\n root: this.options.root,\n server: {\n host: this.options.host,\n port: this.options.port,\n strictPort: true,\n },\n }),\n );\n\n installDevSSRMiddleware({\n options: this.options,\n server: this.#viteServer,\n ssrEntry: prepared.ssrEntry,\n widgets: prepared.widgets,\n });\n\n await this.#viteServer.listen();\n\n const origin = resolveViteOrigin(this.#viteServer);\n\n return {\n assetOrigin: origin,\n mode: \"development\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: origin,\n viteOrigin: origin,\n widgets: Object.fromEntries(\n prepared.widgets.map((widget) => [widget.key, { clientPath: widget.clientDevEntry }]),\n ),\n };\n }\n\n async startProductionServer(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n\n this.#manifest = this.#manifest ?? (await this.loadOrBuildManifest());\n this.#server = await startGdanskServer({\n manifest: this.#manifest,\n options: this.options,\n render: await loadServerRenderFunction(this.options, this.#manifest.server),\n widgets: prepared.widgets,\n });\n\n return {\n assetOrigin: this.#server.origin,\n mode: \"production\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: this.#server.origin,\n viteOrigin: null,\n widgets: Object.fromEntries(\n Object.entries(this.#manifest.widgets).map(([key, widget]) => [key, { clientPath: `/${widget.client}` }]),\n ),\n };\n }\n\n async loadOrBuildManifest(): Promise<GdanskManifest> {\n try {\n return await readManifest(this.manifestPath);\n } catch {\n return this.build();\n }\n }\n\n async prepare(): Promise<GdanskPreparedProject> {\n this.#prepared = await prepareProject(this.options);\n this.widgets = this.#prepared.widgets;\n return this.#prepared;\n }\n}\n\nasync function loadServerRenderFunction(options: ResolvedGdanskOptions, serverEntry: string) {\n const path = resolveServerPath(options, serverEntry);\n const modified = await stat(path);\n return importRenderFunction(`${pathToFileURL(path).href}?t=${modified.mtimeMs}`);\n}\n\nfunction resolveServerPath(options: ResolvedGdanskOptions, serverEntry: string): string {\n return resolve(options.root, serverEntry);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.js","names":["#manifest","#server","#viteServer","#prepared"],"sources":["../src/server.ts","../src/runtime.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { Hono } from \"hono\";\n\nimport { HEALTH_ENDPOINT, processSSRRequest } from \"./ssr\";\nimport type { GdanskServerHandle, GdanskServerOptions } from \"./types\";\n\nexport async function startGdanskServer(options: GdanskServerOptions): Promise<GdanskServerHandle> {\n const app = new Hono();\n const outDirPrefix = `/${options.options.buildDirectory.replace(/^\\/+/, \"\")}`;\n\n app.get(HEALTH_ENDPOINT, (c) => c.json({ status: \"OK\" }));\n\n app.post(options.options.ssrEndpoint, async (c) => {\n const requestBody = await c.req.text();\n const result = await processSSRRequest({\n manifest: options.manifest,\n render: options.render,\n requestBody,\n widgets: options.widgets,\n });\n\n return c.json(result.payload, result.status);\n });\n\n app.use(\n `${outDirPrefix}/*`,\n serveStatic({\n onFound: (_, c) => {\n c.header(\"Access-Control-Allow-Origin\", \"*\");\n c.header(\"Cache-Control\", \"public, max-age=31536000, immutable\");\n },\n root: options.options.root,\n }),\n );\n\n let resolvedPort = options.options.port;\n\n const server = await new Promise<ReturnType<typeof serve>>((resolveServer) => {\n const instance = serve(\n {\n fetch: app.fetch,\n hostname: options.options.host,\n port: options.options.port,\n },\n (info) => {\n resolvedPort = info.port;\n resolveServer(instance);\n },\n );\n });\n\n const origin = `http://${options.options.host}:${resolvedPort}`;\n\n return {\n close: () =>\n new Promise<void>((resolveClose, rejectClose) => {\n server.close((error) => {\n if (error) {\n rejectClose(error);\n return;\n }\n\n resolveClose();\n });\n }),\n origin,\n port: resolvedPort,\n };\n}\n","import { stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { createServer, mergeConfig } from \"vite\";\n\nimport { buildWidgets, readManifest } from \"./build\";\nimport { loadUserViteConfig, prepareProject, resolveOptions } from \"./context\";\nimport { resolveViteOrigin } from \"./css\";\nimport { createRefreshPlugin } from \"./development\";\nimport { startGdanskServer } from \"./server\";\nimport { installDevSSRMiddleware, importRenderFunction } from \"./ssr\";\nimport type {\n GdanskManifest,\n GdanskPluginOptions,\n GdanskPreparedProject,\n GdanskRuntime,\n GdanskRuntimeMetadata,\n GdanskServerHandle,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\nimport { createGdanskVirtualModulesPlugin } from \"./virtual\";\n\nexport async function createGdanskRuntime(options: GdanskPluginOptions = {}): Promise<GdanskRuntime> {\n const resolved = resolveOptions(options);\n const runtime = new GdanskRuntimeImpl(resolved);\n await runtime.refreshWidgets();\n return runtime;\n}\n\nclass GdanskRuntimeImpl implements GdanskRuntime {\n readonly manifestPath: string;\n readonly options: ResolvedGdanskOptions;\n widgets: WidgetDefinition[] = [];\n\n #manifest?: GdanskManifest;\n #prepared?: GdanskPreparedProject;\n #server?: GdanskServerHandle;\n #viteServer?: Awaited<ReturnType<typeof createServer>>;\n\n constructor(options: ResolvedGdanskOptions) {\n this.manifestPath = `${options.buildDirectoryPath}/gdansk-manifest.json`;\n this.options = options;\n }\n\n async build(): Promise<GdanskManifest> {\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"build\");\n\n this.#manifest = await buildWidgets(this.options, prepared, config);\n\n return this.#manifest;\n }\n\n async close(): Promise<void> {\n await this.#server?.close();\n this.#server = undefined;\n\n await this.#viteServer?.close();\n this.#viteServer = undefined;\n }\n\n async refreshWidgets(): Promise<void> {\n const prepared = await this.prepare();\n this.widgets = prepared.widgets;\n }\n\n async startDev(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"serve\");\n\n this.#viteServer = await createServer(\n mergeConfig(config, {\n appType: \"custom\",\n configFile: false,\n plugins: [createGdanskVirtualModulesPlugin(this.options, prepared), createRefreshPlugin(this.options)],\n root: this.options.root,\n server: {\n host: this.options.host,\n port: this.options.port,\n strictPort: true,\n },\n }),\n );\n\n installDevSSRMiddleware({\n options: this.options,\n server: this.#viteServer,\n ssrEntry: prepared.ssrEntryId,\n widgets: prepared.widgets,\n });\n\n await this.#viteServer.listen();\n\n const origin = resolveViteOrigin(this.#viteServer);\n\n return {\n assetOrigin: origin,\n mode: \"development\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: origin,\n viteOrigin: origin,\n widgets: Object.fromEntries(\n prepared.widgets.map((widget) => [widget.key, { clientPath: widget.clientDevEntry }]),\n ),\n };\n }\n\n async startProductionServer(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n\n this.#manifest = this.#manifest ?? (await this.loadOrBuildManifest());\n this.#server = await startGdanskServer({\n manifest: this.#manifest,\n options: this.options,\n render: await loadServerRenderFunction(this.options, this.#manifest.server),\n widgets: prepared.widgets,\n });\n\n return {\n assetOrigin: this.#server.origin,\n mode: \"production\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: this.#server.origin,\n viteOrigin: null,\n widgets: Object.fromEntries(\n Object.entries(this.#manifest.widgets).map(([key, widget]) => [key, { clientPath: `/${widget.client}` }]),\n ),\n };\n }\n\n async loadOrBuildManifest(): Promise<GdanskManifest> {\n try {\n return await readManifest(this.manifestPath);\n } catch {\n return this.build();\n }\n }\n\n async prepare(): Promise<GdanskPreparedProject> {\n this.#prepared = await prepareProject(this.options);\n this.widgets = this.#prepared.widgets;\n return this.#prepared;\n }\n}\n\nasync function loadServerRenderFunction(options: ResolvedGdanskOptions, serverEntry: string) {\n const path = resolveServerPath(options, serverEntry);\n const modified = await stat(path);\n return importRenderFunction(`${pathToFileURL(path).href}?t=${modified.mtimeMs}`);\n}\n\nfunction resolveServerPath(options: ResolvedGdanskOptions, serverEntry: string): string {\n return resolve(options.root, serverEntry);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gdansk/vite",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"node": ">=22"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@hono/node-server": "1.19.
|
|
38
|
+
"@hono/node-server": "1.19.14",
|
|
39
39
|
"@vitejs/plugin-react": "6.0.1",
|
|
40
40
|
"hono": "4.12.12",
|
|
41
41
|
"react": "19.2.5",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"vite": "8.0.8"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/node": "25.
|
|
48
|
+
"@types/node": "25.6.0",
|
|
49
49
|
"@types/react": "19.2.14",
|
|
50
50
|
"@types/react-dom": "19.2.3",
|
|
51
51
|
"typescript": "~6.0.2",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Plugin, type UserConfig, type ViteDevServer } from "vite";
|
|
2
|
+
import type { GdanskPluginOptions, ResolvedGdanskOptions, WidgetDefinition } from "./types";
|
|
3
|
+
type AliasOption = NonNullable<NonNullable<UserConfig["resolve"]>["alias"]>;
|
|
4
|
+
export declare function mergeAliasConfig(alias: AliasOption | undefined, root: string): AliasOption;
|
|
5
|
+
export declare function resolveDevelopmentServerConfig(options: GdanskPluginOptions, resolved: ResolvedGdanskOptions): UserConfig["server"] | undefined;
|
|
6
|
+
export declare function createRefreshPlugin(options?: GdanskPluginOptions): Plugin;
|
|
7
|
+
export declare function warmupWidgetEntries(server: ViteDevServer, widgets: WidgetDefinition[]): Promise<void>;
|
|
8
|
+
export declare function normalizeRefreshConfig(refresh: GdanskPluginOptions["refresh"]): Array<{
|
|
9
|
+
paths: string[];
|
|
10
|
+
}>;
|
|
11
|
+
export declare function resolveRefreshPaths(refresh: GdanskPluginOptions["refresh"], root: string): string[];
|
|
12
|
+
export {};
|
package/types/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { gdansk as default, gdansk } from "./plugin";
|
|
2
|
-
export type { GdanskPluginOptions, ResolvedGdanskOptions } from "./types";
|
|
2
|
+
export type { GdanskPluginOptions, RefreshConfig, ResolvedGdanskOptions } from "./types";
|
package/types/plugin.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PluginOption } from "vite";
|
|
2
2
|
import type { GdanskPluginOptions } from "./types";
|
|
3
|
-
export declare function gdansk(options?: GdanskPluginOptions):
|
|
3
|
+
export declare function gdansk(options?: GdanskPluginOptions): PluginOption;
|
package/types/types.d.ts
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import type { InlineConfig, UserConfig } from "vite";
|
|
2
|
+
export interface RefreshConfig {
|
|
3
|
+
paths: string | string[];
|
|
4
|
+
}
|
|
2
5
|
export interface GdanskPluginOptions {
|
|
3
|
-
|
|
6
|
+
buildDirectory?: string;
|
|
7
|
+
refresh?: boolean | string | string[] | RefreshConfig | RefreshConfig[];
|
|
4
8
|
root?: string;
|
|
5
|
-
|
|
9
|
+
widgetsDirectory?: string;
|
|
6
10
|
host?: string;
|
|
7
11
|
port?: number;
|
|
8
12
|
}
|
|
9
13
|
export interface ResolvedGdanskOptions {
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
buildDirectory: string;
|
|
15
|
+
buildDirectoryPath: string;
|
|
12
16
|
host: string;
|
|
13
|
-
outDir: string;
|
|
14
|
-
outDirPath: string;
|
|
15
17
|
root: string;
|
|
16
18
|
ssrEndpoint: string;
|
|
17
19
|
port: number;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
widgetsDirectory: string;
|
|
21
|
+
widgetsDirectoryPath: string;
|
|
20
22
|
}
|
|
21
23
|
export interface WidgetDefinition {
|
|
22
24
|
clientCss: string;
|
|
23
25
|
clientDevEntry: string;
|
|
24
26
|
clientEntry: string;
|
|
25
|
-
|
|
27
|
+
clientModuleId: string;
|
|
26
28
|
entry: string;
|
|
27
29
|
key: string;
|
|
28
30
|
widgetPath: string;
|
|
@@ -60,7 +62,7 @@ export interface GdanskRenderResponse {
|
|
|
60
62
|
}
|
|
61
63
|
export type GdanskRenderFunction = (widgetKey: string) => Promise<GdanskRenderResponse> | GdanskRenderResponse;
|
|
62
64
|
export interface GdanskPreparedProject {
|
|
63
|
-
|
|
65
|
+
ssrEntryId: string;
|
|
64
66
|
widgets: WidgetDefinition[];
|
|
65
67
|
}
|
|
66
68
|
export interface GdanskServerOptions {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import type { GdanskPreparedProject, ResolvedGdanskOptions } from "./types";
|
|
3
|
+
export declare const GDANSK_DEV_CLIENT_PREFIX = "/@gdansk/client";
|
|
4
|
+
export declare const GDANSK_SSR_ENTRY_ID = "virtual:gdansk/ssr-entry";
|
|
5
|
+
export declare function createGdanskVirtualModulesPlugin(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject): Plugin;
|
|
6
|
+
export declare function createClientDevEntry(key: string): string;
|
|
7
|
+
export declare function createClientModuleId(key: string): string;
|
|
8
|
+
export declare function createResolvedClientModuleId(key: string): string;
|
|
9
|
+
export declare function resolveVirtualModuleId(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject, id: string, importer?: string): string | null;
|
|
10
|
+
export declare function loadVirtualModule(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject, id: string): string | null;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-DnMeNprs.js","names":[],"sources":["../../src/context.ts","../../src/build.ts","../../src/css.ts","../../src/ssr.ts"],"sourcesContent":["import { access, glob as globIterate, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve, sep } from \"node:path\";\n\nimport { loadConfigFromFile, mergeConfig } from \"vite\";\nimport type { InlineConfig, Plugin, PluginOption } from \"vite\";\n\nimport type {\n GdanskPreparedProject,\n GdanskPluginOptions,\n LoadedProjectConfig,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\n\nexport function resolveOptions(options: GdanskPluginOptions = {}, configRoot?: string): ResolvedGdanskOptions {\n const root = resolve(configRoot ?? options.root ?? process.cwd());\n const widgetsRoot = options.widgetsRoot ?? \"widgets\";\n const outDir = options.assets ?? \"assets\";\n const generatedDir = \"dist-src\";\n const host = options.host ?? \"127.0.0.1\";\n const ssrEndpoint = \"/ssr\";\n\n return {\n generatedDir,\n generatedDirPath: resolve(root, generatedDir),\n host,\n outDir,\n outDirPath: resolve(root, outDir),\n root,\n ssrEndpoint,\n port: options.port ?? 13714,\n widgetsRoot,\n widgetsRootPath: resolve(root, widgetsRoot),\n };\n}\n\nasync function globPaths(pattern: string, options: { absolute?: boolean; cwd: string }): Promise<string[]> {\n const { cwd, absolute = false } = options;\n const matches: string[] = [];\n for await (const entry of globIterate(pattern, { cwd })) {\n matches.push(absolute ? resolve(cwd, entry) : entry);\n }\n return matches;\n}\n\nexport async function discoverWidgets(options: ResolvedGdanskOptions): Promise<WidgetDefinition[]> {\n const entries = await globPaths(\"**/widget.{tsx,jsx}\", {\n cwd: options.widgetsRootPath,\n });\n\n return entries.sort().map((entry) => {\n const widgetPath = toPosixPath(entry);\n const key = toPosixPath(dirname(widgetPath));\n const clientSource = toPosixPath(join(options.generatedDir, key, \"client.tsx\"));\n\n return {\n clientCss: toPosixPath(join(options.outDir, key, \"client.css\")),\n clientDevEntry: toPublicPath(clientSource),\n clientEntry: toPosixPath(join(options.outDir, key, \"client.js\")),\n clientSource: resolve(options.root, clientSource),\n entry: resolve(options.widgetsRootPath, entry),\n key,\n widgetPath,\n };\n });\n}\n\nexport async function loadUserViteConfig(\n options: ResolvedGdanskOptions,\n command: \"build\" | \"serve\",\n): Promise<LoadedProjectConfig> {\n const loaded = await loadConfigFromFile(\n {\n command,\n mode: command === \"build\" ? \"production\" : \"development\",\n },\n undefined,\n options.root,\n );\n const loadedConfig = loaded?.config ?? ({} satisfies InlineConfig);\n const { plugins: _, ...configWithoutPlugins } = loadedConfig;\n\n const plugins = (await normalizePlugins(loadedConfig.plugins)).filter((plugin) => plugin.name !== \"@gdansk/vite\");\n\n return mergeConfig(configWithoutPlugins, {\n plugins,\n root: options.root,\n } satisfies InlineConfig);\n}\n\nexport async function prepareProject(options: ResolvedGdanskOptions): Promise<GdanskPreparedProject> {\n const widgets = await discoverWidgets(options);\n await Promise.all(widgets.map((widget) => writeClientEntry(widget)));\n\n const ssrEntry = resolve(options.generatedDirPath, \"__gdansk_ssr__.ts\");\n await writeSSRRenderEntry(ssrEntry, widgets);\n\n return {\n ssrEntry,\n widgets,\n };\n}\n\nexport async function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function toPosixPath(path: string): string {\n return path.split(sep).join(\"/\");\n}\n\nfunction createImportPath(from: string, to: string): string {\n const relativePath = toPosixPath(relative(dirname(from), to));\n return relativePath.startsWith(\".\") ? relativePath : `./${relativePath}`;\n}\n\nasync function normalizePlugins(plugins: PluginOption | PluginOption[] | undefined): Promise<Plugin[]> {\n if (!plugins) {\n return [];\n }\n\n const entries = Array.isArray(plugins) ? plugins : [plugins];\n const normalized: Plugin[] = [];\n\n for (const entry of entries) {\n const plugin = await entry;\n\n if (!plugin) {\n continue;\n }\n\n if (Array.isArray(plugin)) {\n normalized.push(...(await normalizePlugins(plugin)));\n continue;\n }\n\n normalized.push(plugin);\n }\n\n return normalized;\n}\n\nfunction toPublicPath(path: string): string {\n return `/${path.replace(/^\\/+/, \"\")}`;\n}\n\nasync function writeClientEntry(widget: WidgetDefinition): Promise<void> {\n const sourceImport = createImportPath(widget.clientSource, widget.entry);\n\n await mkdir(dirname(widget.clientSource), { recursive: true });\n await writeFile(\n widget.clientSource,\n [\n 'import React from \"react\";',\n 'import { createRoot, hydrateRoot } from \"react-dom/client\";',\n `import App from \"${sourceImport}\";`,\n \"\",\n 'const root = document.getElementById(\"root\");',\n \"\",\n \"if (!root) {\",\n \" throw new Error('Gdansk expected a #root element for widget hydration.');\",\n \"}\",\n \"\",\n \"const element = (\",\n \" <React.StrictMode>\",\n \" <App />\",\n \" </React.StrictMode>\",\n \");\",\n \"\",\n \"if (root.hasChildNodes()) {\",\n \" hydrateRoot(root, element);\",\n \"} else {\",\n \" createRoot(root).render(element);\",\n \"}\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n\nasync function writeSSRRenderEntry(path: string, widgets: WidgetDefinition[]): Promise<void> {\n const imports = widgets.map((widget, index) => {\n const specifier = createImportPath(path, widget.entry);\n return `import Widget${index} from \"${specifier}\";`;\n });\n\n const widgetEntries = widgets.map((widget, index) => ` ${JSON.stringify(widget.key)}: Widget${index},`);\n\n await mkdir(dirname(path), { recursive: true });\n await writeFile(\n path,\n [\n 'import { createElement } from \"react\";',\n 'import { renderToString } from \"react-dom/server\";',\n ...imports,\n \"\",\n \"const widgets = {\",\n ...widgetEntries,\n \"} as const;\",\n \"\",\n \"export default async function renderWidget(widgetKey: string) {\",\n \" const component = widgets[widgetKey as keyof typeof widgets];\",\n \"\",\n \" if (!component) {\",\n \" throw new Error(`Unknown widget: ${widgetKey}`);\",\n \" }\",\n \"\",\n \" return {\",\n \" body: renderToString(createElement(component)),\",\n \" head: [],\",\n \" };\",\n \"}\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, resolve } from \"node:path\";\n\nimport { build, mergeConfig } from \"vite\";\nimport type { UserConfig } from \"vite\";\n\nimport { pathExists, toPosixPath } from \"./context\";\nimport type {\n GdanskManifest,\n GdanskPreparedProject,\n LoadedProjectConfig,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\n\nconst CLIENT_MANIFEST_FILE = \".gdansk-client-manifest.json\";\nconst SERVER_BUNDLE = \"ssr.js\";\n\ntype ViteManifestEntry = {\n css?: string[];\n file: string;\n};\n\nexport function createBuildConfig(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject): UserConfig {\n return {\n appType: \"custom\",\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n if (prepared.widgets.length > 0) {\n await builder.build(builder.environments.client);\n }\n\n await builder.build(builder.environments.ssr);\n await finalizeBuildOutputs(options, prepared.widgets);\n },\n },\n build: {\n copyPublicDir: false,\n emptyOutDir: true,\n outDir: options.outDir,\n sourcemap: true,\n },\n environments: {\n client: {\n build: createClientBuildOptions(options, prepared),\n },\n ssr: {\n consumer: \"server\",\n build: createSSRBuildOptions(options, prepared),\n },\n },\n };\n}\n\nexport async function buildWidgets(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n config: LoadedProjectConfig = {},\n): Promise<GdanskManifest> {\n await rm(options.outDirPath, { force: true, recursive: true });\n await mkdir(options.outDirPath, { recursive: true });\n\n if (prepared.widgets.length > 0) {\n await build(\n mergeConfig(config, {\n appType: \"custom\",\n build: createClientBuildOptions(options, prepared),\n configFile: false,\n root: options.root,\n }),\n );\n }\n\n await build(\n mergeConfig(config, {\n appType: \"custom\",\n build: createSSRBuildOptions(options, prepared),\n configFile: false,\n root: options.root,\n }),\n );\n\n return finalizeBuildOutputs(options, prepared.widgets);\n}\n\nexport async function readManifest(path: string): Promise<GdanskManifest> {\n return JSON.parse(await readFile(path, \"utf8\")) as GdanskManifest;\n}\n\nfunction createClientBuildOptions(\n options: ResolvedGdanskOptions,\n prepared: GdanskPreparedProject,\n): UserConfig[\"build\"] {\n const inputs =\n prepared.widgets.length > 0\n ? Object.fromEntries(prepared.widgets.map((widget) => [widget.key, widget.clientSource]))\n : { __gdansk_empty__: prepared.ssrEntry };\n\n return {\n copyPublicDir: false,\n cssCodeSplit: true,\n emptyOutDir: true,\n manifest: CLIENT_MANIFEST_FILE,\n outDir: options.outDir,\n rollupOptions: {\n input: inputs,\n output: {\n assetFileNames: (assetInfo: { names?: string[]; originalFileNames?: string[] }) =>\n resolveClientAssetPath(options, prepared.widgets, assetInfo),\n chunkFileNames: \"chunks/[name]-[hash].js\",\n entryFileNames: ({ name }) => `${name}/client.js`,\n },\n },\n sourcemap: true,\n };\n}\n\nfunction createSSRBuildOptions(options: ResolvedGdanskOptions, prepared: GdanskPreparedProject): UserConfig[\"build\"] {\n return {\n copyPublicDir: false,\n emptyOutDir: false,\n outDir: options.outDir,\n rollupOptions: {\n input: prepared.ssrEntry,\n output: {\n chunkFileNames: \"chunks/[name]-[hash].js\",\n entryFileNames: SERVER_BUNDLE,\n },\n },\n sourcemap: true,\n ssr: prepared.ssrEntry,\n };\n}\n\nasync function finalizeBuildOutputs(\n options: ResolvedGdanskOptions,\n widgets: WidgetDefinition[],\n): Promise<GdanskManifest> {\n const clientManifest = await readClientManifest(resolve(options.outDirPath, CLIENT_MANIFEST_FILE));\n\n const manifest: GdanskManifest = {\n outDir: options.outDir,\n root: options.root,\n server: toPosixPath(`${options.outDir}/${SERVER_BUNDLE}`),\n widgets: Object.fromEntries(\n await Promise.all(\n widgets.map(async (widget) => {\n const manifestEntry = getClientManifestEntry(options, widget, clientManifest);\n const fallbackCss = (await pathExists(resolve(options.root, widget.clientCss))) ? [widget.clientCss] : [];\n\n return [\n widget.key,\n {\n client: manifestEntry ? toBuildPath(options, manifestEntry.file) : widget.clientEntry,\n css: manifestEntry?.css?.map((href) => toBuildPath(options, href)) ?? fallbackCss,\n entry: widget.widgetPath,\n },\n ];\n }),\n ),\n ),\n };\n\n await rm(resolve(options.outDirPath, CLIENT_MANIFEST_FILE), { force: true });\n await writeJson(resolve(options.outDirPath, \"manifest.json\"), manifest);\n await writeProductionServer(options);\n\n return manifest;\n}\n\nfunction getClientManifestEntry(\n options: ResolvedGdanskOptions,\n widget: WidgetDefinition,\n manifest: Record<string, ViteManifestEntry>,\n): ViteManifestEntry | undefined {\n const key = toPosixPath(relative(options.root, widget.clientSource));\n return manifest[key];\n}\n\nasync function readClientManifest(path: string): Promise<Record<string, ViteManifestEntry>> {\n if (!(await pathExists(path))) {\n return {};\n }\n\n return JSON.parse(await readFile(path, \"utf8\")) as Record<string, ViteManifestEntry>;\n}\n\nfunction resolveClientAssetPath(\n options: ResolvedGdanskOptions,\n widgets: WidgetDefinition[],\n assetInfo: { names?: string[]; originalFileNames?: string[] },\n): string {\n const fileName = assetInfo.names?.[0] ?? assetInfo.originalFileNames?.[0] ?? \"\";\n\n if (!fileName.endsWith(\".css\")) {\n return \"assets/[name]-[hash][extname]\";\n }\n\n const originalFileName = assetInfo.originalFileNames?.[0];\n const widget = originalFileName ? findWidgetForAsset(options, widgets, originalFileName) : undefined;\n\n if (!widget) {\n return \"assets/[name]-[hash][extname]\";\n }\n\n return toOutputPath(options, widget.clientCss);\n}\n\nfunction findWidgetForAsset(\n options: ResolvedGdanskOptions,\n widgets: WidgetDefinition[],\n originalFileName: string,\n): WidgetDefinition | undefined {\n const normalized = toPosixPath(originalFileName);\n\n return widgets.find((widget) => {\n const relativeClientSource = toPosixPath(relative(options.root, widget.clientSource));\n return normalized === widget.clientSource || normalized === relativeClientSource;\n });\n}\n\nasync function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nfunction toOutputPath(options: ResolvedGdanskOptions, path: string): string {\n const prefix = `${options.outDir}/`;\n\n if (path.startsWith(prefix)) {\n return path.slice(prefix.length);\n }\n\n return path;\n}\n\nfunction toBuildPath(options: ResolvedGdanskOptions, path: string): string {\n return path.startsWith(`${options.outDir}/`) ? path : `${options.outDir}/${path.replace(/^\\/+/, \"\")}`;\n}\n\nasync function writeProductionServer(options: ResolvedGdanskOptions): Promise<void> {\n const path = resolve(options.outDirPath, \"server.js\");\n const runtimeModuleUrl = new URL(\"../runtime.js\", import.meta.url).href;\n const runtimeOptions = {\n host: options.host,\n port: options.port,\n widgetsRoot: options.widgetsRoot,\n };\n\n await writeFile(\n path,\n [\n 'import { dirname, resolve } from \"node:path\";',\n 'import { fileURLToPath } from \"node:url\";',\n `import { createGdanskRuntime } from \"${runtimeModuleUrl}\";`,\n \"\",\n \"const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');\",\n `const runtime = await createGdanskRuntime({ ...${JSON.stringify(runtimeOptions)}, root });`,\n \"await runtime.startProductionServer();\",\n \"await new Promise(() => {});\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n","import type { EnvironmentModuleNode, ViteDevServer } from \"vite\";\nimport { normalizePath } from \"vite\";\n\nexport function collectCSSFromModuleGraph(server: ViteDevServer, entry: string): string[] {\n const entryModule = resolveEntryModule(server, entry);\n\n if (!entryModule) {\n return [];\n }\n\n const cssModules = collectCSSModules(entryModule);\n\n if (cssModules.length === 0) {\n return [];\n }\n\n const origin = resolveViteOrigin(server);\n const base = server.config.base === \"/\" ? \"\" : server.config.base.replace(/\\/$/, \"\");\n\n return cssModules.map(({ id, url }) => {\n const devId = id ? ` data-vite-dev-id=\"${id}\"` : \"\";\n return `<link rel=\"stylesheet\" href=\"${origin}${base}${url}\"${devId}>`;\n });\n}\n\nexport function resolveViteOrigin(server: ViteDevServer): string {\n const origin = server.resolvedUrls?.local[0] ?? server.resolvedUrls?.network[0];\n\n if (origin) {\n return new URL(origin).origin;\n }\n\n const protocol = server.config.server.https ? \"https\" : \"http\";\n return `${protocol}://${server.config.server.host ?? \"127.0.0.1\"}:${server.config.server.port ?? 5173}`;\n}\n\nfunction collectCSSModules(entryModule: EnvironmentModuleNode): Array<{ id: string | null; url: string }> {\n const cssModules: Array<{ id: string | null; url: string }> = [];\n const visited = new Set<EnvironmentModuleNode>();\n\n const walk = (mod: EnvironmentModuleNode): void => {\n if (visited.has(mod)) {\n return;\n }\n\n visited.add(mod);\n\n if (isCssRequest(mod.url)) {\n cssModules.push({ id: mod.id, url: mod.url });\n return;\n }\n\n for (const imported of mod.importedModules) {\n walk(imported);\n }\n };\n\n walk(entryModule);\n\n return cssModules;\n}\n\nfunction isCssRequest(url: string): boolean {\n return /\\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\\?)/.test(url);\n}\n\nfunction resolveEntryModule(server: ViteDevServer, entry: string): EnvironmentModuleNode | undefined {\n const moduleGraph = server.environments.ssr.moduleGraph;\n const normalized = normalizePath(entry);\n\n return moduleGraph.getModuleById(normalized) ?? moduleGraph.getModuleById(entry);\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\n\nimport type { ViteDevServer } from \"vite\";\n\nimport { collectCSSFromModuleGraph } from \"./css\";\nimport type {\n GdanskManifest,\n GdanskRenderFunction,\n GdanskRenderRequest,\n GdanskRenderResponse,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\n\nexport const HEALTH_ENDPOINT = \"/health\";\n\ntype GdanskErrorResponse = {\n error: {\n message: string;\n type: \"invalid_json\" | \"invalid_request\" | \"render_error\" | \"unknown_widget\";\n };\n};\n\ntype GdanskResponsePayload = GdanskErrorResponse | GdanskRenderResponse;\n\ntype ProcessSSRRequestOptions = {\n manifest?: GdanskManifest;\n render: GdanskRenderFunction;\n requestBody: string;\n viteServer?: ViteDevServer;\n widgets: WidgetDefinition[];\n};\n\ntype ProcessSSRRequestResult = {\n payload: GdanskResponsePayload;\n status: 200 | 400 | 404 | 500;\n};\n\ntype InstallDevSSRMiddlewareOptions = {\n options: ResolvedGdanskOptions;\n server: ViteDevServer;\n ssrEntry: string;\n widgets: WidgetDefinition[];\n};\n\nexport function installDevSSRMiddleware({ options, server, ssrEntry, widgets }: InstallDevSSRMiddlewareOptions): void {\n server.middlewares.use(HEALTH_ENDPOINT, (req, res, next) => {\n if (req.method !== \"GET\") {\n next();\n return;\n }\n\n writeJson(res, 200, { status: \"OK\" });\n });\n\n server.middlewares.use(options.ssrEndpoint, async (req, res, next) => {\n if (req.method !== \"POST\") {\n next();\n return;\n }\n\n try {\n const requestBody = await readRequestBody(req);\n const render = await loadRenderFunction(server, ssrEntry);\n const result = await processSSRRequest({\n render,\n requestBody,\n viteServer: server,\n widgets,\n });\n\n writeJson(res, result.status, result.payload);\n } catch (error) {\n writeJson(res, 500, createErrorResponse(error, \"render_error\"));\n }\n });\n\n server.config.logger.info(`Gdansk SSR dev endpoint: ${options.ssrEndpoint}`);\n\n server.httpServer?.once(\"listening\", () => {\n server.config.logger.info(\"Warming up Gdansk SSR module graph...\");\n\n server\n .ssrLoadModule(ssrEntry)\n .then(() => server.config.logger.info(\"Gdansk SSR module graph warmed up\"))\n .catch((error) => {\n server.config.logger.warn(`Failed to warm up Gdansk SSR module graph: ${getErrorMessage(error)}`);\n });\n });\n}\n\nexport async function importRenderFunction(path: string): Promise<GdanskRenderFunction> {\n const module = (await import(path)) as { default?: unknown };\n return resolveRenderFunction(module.default, path);\n}\n\nexport async function processSSRRequest({\n manifest,\n render,\n requestBody,\n viteServer,\n widgets,\n}: ProcessSSRRequestOptions): Promise<ProcessSSRRequestResult> {\n let payload: GdanskRenderRequest;\n\n try {\n payload = JSON.parse(requestBody) as GdanskRenderRequest;\n } catch (error) {\n return {\n payload: createErrorResponse(error, \"invalid_json\"),\n status: 400,\n };\n }\n\n const widgetKey = payload.widget ?? payload.component;\n\n if (!widgetKey) {\n return {\n payload: createErrorResponse('Request body must include \"widget\" or \"component\"', \"invalid_request\"),\n status: 400,\n };\n }\n\n const widget = widgets.find((candidate) => candidate.key === widgetKey);\n\n if (!widget) {\n return {\n payload: createErrorResponse(`Unknown widget: ${widgetKey}`, \"unknown_widget\"),\n status: 404,\n };\n }\n\n try {\n const rendered = await Promise.resolve(render(widget.key));\n const response = validateRenderResponse(rendered);\n const assetBaseUrl = payload.assetBaseUrl;\n const head = viteServer\n ? [...collectCSSFromModuleGraph(viteServer, widget.entry), ...response.head]\n : [...createProductionCssHead(assetBaseUrl, manifest, widget.key), ...response.head];\n\n return {\n payload: {\n body: response.body,\n head,\n },\n status: 200,\n };\n } catch (error) {\n return {\n payload: createErrorResponse(error, \"render_error\"),\n status: 500,\n };\n }\n}\n\nasync function loadRenderFunction(server: ViteDevServer, entry: string): Promise<GdanskRenderFunction> {\n const module = (await server.ssrLoadModule(entry)) as { default?: unknown };\n return resolveRenderFunction(module.default, entry);\n}\n\nfunction resolveRenderFunction(candidate: unknown, entry: string): GdanskRenderFunction {\n if (typeof candidate !== \"function\") {\n throw new Error(`SSR entry \"${entry}\" must export a render function`);\n }\n\n return candidate as GdanskRenderFunction;\n}\n\nfunction validateRenderResponse(result: unknown): GdanskRenderResponse {\n if (!result || typeof result !== \"object\") {\n throw new Error(\"SSR render must return { head: string[], body: string }\");\n }\n\n const body = Reflect.get(result, \"body\");\n const head = Reflect.get(result, \"head\");\n\n if (typeof body !== \"string\" || !Array.isArray(head) || !head.every((value) => typeof value === \"string\")) {\n throw new Error(\"SSR render must return { head: string[], body: string }\");\n }\n\n return {\n body,\n head,\n };\n}\n\nfunction createProductionCssHead(\n assetBaseUrl: string | undefined,\n manifest: GdanskManifest | undefined,\n widgetKey: string,\n): string[] {\n if (!manifest) {\n return [];\n }\n\n const widget = manifest.widgets[widgetKey];\n\n if (!widget) {\n throw new Error(`Widget \"${widgetKey}\" is not present in the production manifest`);\n }\n\n return widget.css.map((href) => {\n if (assetBaseUrl) {\n return `<link rel=\"stylesheet\" href=\"${toAbsoluteAssetPath(assetBaseUrl, manifest.outDir, href)}\">`;\n }\n\n return `<link rel=\"stylesheet\" href=\"${toRootRelativeAssetPath(manifest.outDir, href)}\">`;\n });\n}\n\nfunction toAbsoluteAssetPath(assetBaseUrl: string, outDir: string, href: string): string {\n return new URL(stripOutDirPrefix(outDir, href), `${assetBaseUrl.replace(/\\/+$/g, \"\")}/`).toString();\n}\n\nfunction toRootRelativeAssetPath(outDir: string, href: string): string {\n const normalizedOutDir = outDir.replace(/^\\/+|\\/+$/g, \"\");\n const normalizedPath = stripOutDirPrefix(outDir, href);\n return `/${[normalizedOutDir, normalizedPath].filter(Boolean).join(\"/\")}`;\n}\n\nfunction stripOutDirPrefix(outDir: string, href: string): string {\n const normalized = href.replace(/^\\/+/, \"\");\n const prefix = `${outDir.replace(/^\\/+|\\/+$/g, \"\")}/`;\n\n return normalized.startsWith(prefix) ? normalized.slice(prefix.length) : normalized;\n}\n\nfunction createErrorResponse(error: unknown, type: GdanskErrorResponse[\"error\"][\"type\"]): GdanskErrorResponse {\n return {\n error: {\n message: getErrorMessage(error),\n type,\n },\n };\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readRequestBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = \"\";\n\n req.on(\"data\", (chunk) => {\n data += chunk;\n });\n req.on(\"end\", () => {\n resolve(data);\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction writeJson(res: ServerResponse, status: number, payload: unknown): void {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify(payload));\n}\n"],"mappings":"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"}
|