@gdansk/vite 0.4.0 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "imports": {
3
- "@hono/node-server": "npm:@hono/node-server@1.19.13",
3
+ "@hono/node-server": "npm:@hono/node-server@1.19.14",
4
4
  "@vitejs/plugin-react": "npm:@vitejs/plugin-react@6.0.1",
5
5
  "hono": "npm:hono@4.12.12",
6
6
  "react": "npm:react@19.2.5",
@@ -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 widgetsRoot = options.widgetsRoot ?? "widgets";
8
- const outDir = options.assets ?? "assets";
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
- generatedDir,
13
- generatedDirPath: resolve(root, generatedDir),
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
- widgetsRoot,
21
- widgetsRootPath: resolve(root, widgetsRoot)
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.widgetsRootPath })).sort().map((entry) => {
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.outDir, key, "client.css")),
37
- clientDevEntry: toPublicPath(clientSource),
38
- clientEntry: toPosixPath(join(options.outDir, key, "client.js")),
39
- clientSource: resolve(options.root, clientSource),
40
- entry: resolve(options.widgetsRootPath, entry),
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
- ssrEntry,
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 toPublicPath(path) {
98
- return `/${path.replace(/^\/+/, "")}`;
99
- }
100
- async function writeClientEntry(widget) {
101
- const sourceImport = createImportPath(widget.clientSource, widget.entry);
102
- await mkdir(dirname(widget.clientSource), { recursive: true });
103
- await writeFile(widget.clientSource, [
104
- "import React from \"react\";",
105
- "import { createRoot, hydrateRoot } from \"react-dom/client\";",
106
- `import App from "${sourceImport}";`,
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
- async function writeSSRRenderEntry(path, widgets) {
129
- const imports = widgets.map((widget, index) => {
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 = ".gdansk-client-manifest.json";
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.outDir,
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.outDirPath, {
263
+ await rm(options.buildDirectoryPath, {
190
264
  force: true,
191
265
  recursive: true
192
266
  });
193
- await mkdir(options.outDirPath, { recursive: true });
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.clientSource])) : { __gdansk_empty__: prepared.ssrEntry };
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.outDir,
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: "chunks/[name]-[hash].js",
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.outDir,
310
+ outDir: options.buildDirectory,
235
311
  rollupOptions: {
236
- input: prepared.ssrEntry,
312
+ input: prepared.ssrEntryId,
237
313
  output: {
238
- chunkFileNames: "chunks/[name]-[hash].js",
314
+ chunkFileNames: "assets/[name]-[hash].js",
239
315
  entryFileNames: SERVER_BUNDLE
240
316
  }
241
317
  },
242
318
  sourcemap: true,
243
- ssr: prepared.ssrEntry
319
+ ssr: true
244
320
  };
245
321
  }
246
322
  async function finalizeBuildOutputs(options, widgets) {
247
- const clientManifest = await readClientManifest(resolve(options.outDirPath, CLIENT_MANIFEST_FILE));
323
+ const clientManifest = await readClientManifest(resolve(options.buildDirectoryPath, CLIENT_MANIFEST_FILE));
248
324
  const manifest = {
249
- outDir: options.outDir,
325
+ outDir: options.buildDirectory,
250
326
  root: options.root,
251
- server: toPosixPath(`${options.outDir}/${SERVER_BUNDLE}`),
327
+ server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`),
252
328
  widgets: Object.fromEntries(await Promise.all(widgets.map(async (widget) => {
253
- const manifestEntry = getClientManifestEntry(options, widget, clientManifest);
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: manifestEntry?.css?.map((href) => toBuildPath(options, href)) ?? fallbackCss,
334
+ css,
258
335
  entry: widget.widgetPath
259
336
  }];
260
337
  })))
261
338
  };
262
- await rm(resolve(options.outDirPath, CLIENT_MANIFEST_FILE), { force: true });
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(options, widget, manifest) {
268
- return manifest[toPosixPath(relative(options.root, widget.clientSource))];
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.names?.[0] ?? assetInfo.originalFileNames?.[0] ?? "").endsWith(".css")) return "assets/[name]-[hash][extname]";
276
- const originalFileName = assetInfo.originalFileNames?.[0];
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(options, widgets, originalFileName) {
282
- const normalized = toPosixPath(originalFileName);
356
+ function findWidgetForAsset(widgets, assetCandidates) {
283
357
  return widgets.find((widget) => {
284
- const relativeClientSource = toPosixPath(relative(options.root, widget.clientSource));
285
- return normalized === widget.clientSource || normalized === relativeClientSource;
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.outDir}/`;
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.outDir}/`) ? path : `${options.outDir}/${path.replace(/^\/+/, "")}`;
406
+ return path.startsWith(`${options.buildDirectory}/`) ? path : `${options.buildDirectory}/${path.replace(/^\/+/, "")}`;
299
407
  }
300
408
  async function writeProductionServer(options) {
301
- const path = resolve(options.outDirPath, "server.js");
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
- widgetsRoot: options.widgetsRoot
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 { resolveViteOrigin as a, readManifest as c, resolveOptions as d, processSSRRequest as i, loadUserViteConfig as l, importRenderFunction as n, buildWidgets as o, installDevSSRMiddleware as r, createBuildConfig as s, HEALTH_ENDPOINT as t, prepareProject as u };
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-DnMeNprs.js.map
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 resolveViteOrigin, d as resolveOptions, r as installDevSSRMiddleware, s as createBuildConfig, u as prepareProject } from "./assets/ssr-DnMeNprs.js";
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
- if (env.command !== "build") return { appType: "custom" };
19
- const project = await ensurePrepared(config.root);
20
- return createBuildConfig(resolved, project);
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.ssrEntry,
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) updateMetadata();
45
- else server.httpServer?.once("listening", updateMetadata);
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 { Plugin, ViteDevServer } from \"vite\";\n\nimport { createBuildConfig } from \"./build\";\nimport { prepareProject, resolveOptions } from \"./context\";\nimport { resolveViteOrigin } from \"./css\";\nimport { installDevSSRMiddleware } from \"./ssr\";\nimport type { GdanskPluginOptions, GdanskPreparedProject, ResolvedGdanskOptions } from \"./types\";\n\ntype GdanskDevServerMetadata = {\n ssrEndpoint: string;\n ssrOrigin: string;\n};\n\ntype GdanskDevServer = ViteDevServer & {\n __gdansk?: GdanskDevServerMetadata;\n};\n\nexport function gdansk(options: GdanskPluginOptions = {}): Plugin {\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 return {\n async config(config, env) {\n resolved = resolveOptions(options, config.root);\n\n if (env.command !== \"build\") {\n return {\n appType: \"custom\",\n };\n }\n\n const project = await ensurePrepared(config.root);\n\n return createBuildConfig(resolved, project);\n },\n async configResolved(config) {\n await ensurePrepared(config.root);\n },\n name: \"@gdansk/vite\",\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.ssrEntry,\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 clearMetadata = (): void => {\n delete (server as GdanskDevServer).__gdansk;\n };\n\n if (server.httpServer?.listening) {\n updateMetadata();\n } else {\n server.httpServer?.once(\"listening\", updateMetadata);\n }\n\n server.httpServer?.once(\"close\", clearMetadata);\n },\n };\n}\n"],"mappings":";;AAiBA,SAAgB,OAAO,UAA+B,EAAE,EAAU;CAChE,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;;AAGT,QAAO;EACL,MAAM,OAAO,QAAQ,KAAK;AACxB,cAAW,eAAe,SAAS,OAAO,KAAK;AAE/C,OAAI,IAAI,YAAY,QAClB,QAAO,EACL,SAAS,UACV;GAGH,MAAM,UAAU,MAAM,eAAe,OAAO,KAAK;AAEjD,UAAO,kBAAkB,UAAU,QAAQ;;EAE7C,MAAM,eAAe,QAAQ;AAC3B,SAAM,eAAe,OAAO,KAAK;;EAEnC,MAAM;EACN,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;AAChC,WAAQ,OAA2B;;AAGrC,OAAI,OAAO,YAAY,UACrB,iBAAgB;OAEhB,QAAO,YAAY,KAAK,aAAa,eAAe;AAGtD,UAAO,YAAY,KAAK,SAAS,cAAc;;EAElD"}
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 resolveViteOrigin, c as readManifest, d as resolveOptions, i as processSSRRequest, l as loadUserViteConfig, n as importRenderFunction, o as buildWidgets, r as installDevSSRMiddleware, t as HEALTH_ENDPOINT, u as prepareProject } from "./assets/ssr-DnMeNprs.js";
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.outDir.replace(/^\/+/, "")}`;
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.outDirPath}/manifest.json`;
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.ssrEntry,
107
+ ssrEntry: prepared.ssrEntryId,
107
108
  widgets: prepared.widgets
108
109
  });
109
110
  await this.#viteServer.listen();
@@ -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":";;;;;;;;;AAOA,eAAsB,kBAAkB,SAA2D;CACjG,MAAM,MAAM,IAAI,MAAM;CACtB,MAAM,eAAe,IAAI,QAAQ,QAAQ,eAAe,QAAQ,QAAQ,GAAG;AAE3E,KAAI,IAAI,kBAAkB,MAAM,EAAE,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC;AAEzD,KAAI,KAAK,QAAQ,QAAQ,aAAa,OAAO,MAAM;EACjD,MAAM,cAAc,MAAM,EAAE,IAAI,MAAM;EACtC,MAAM,SAAS,MAAM,kBAAkB;GACrC,UAAU,QAAQ;GAClB,QAAQ,QAAQ;GAChB;GACA,SAAS,QAAQ;GAClB,CAAC;AAEF,SAAO,EAAE,KAAK,OAAO,SAAS,OAAO,OAAO;GAC5C;AAEF,KAAI,IACF,GAAG,aAAa,KAChB,YAAY;EACV,UAAU,GAAG,MAAM;AACjB,KAAE,OAAO,+BAA+B,IAAI;AAC5C,KAAE,OAAO,iBAAiB,sCAAsC;;EAElE,MAAM,QAAQ,QAAQ;EACvB,CAAC,CACH;CAED,IAAI,eAAe,QAAQ,QAAQ;CAEnC,MAAM,SAAS,MAAM,IAAI,SAAmC,kBAAkB;EAC5E,MAAM,WAAW,MACf;GACE,OAAO,IAAI;GACX,UAAU,QAAQ,QAAQ;GAC1B,MAAM,QAAQ,QAAQ;GACvB,GACA,SAAS;AACR,kBAAe,KAAK;AACpB,iBAAc,SAAS;IAE1B;GACD;AAIF,QAAO;EACL,aACE,IAAI,SAAe,cAAc,gBAAgB;AAC/C,UAAO,OAAO,UAAU;AACtB,QAAI,OAAO;AACT,iBAAY,MAAM;AAClB;;AAGF,kBAAc;KACd;IACF;EACJ,QAda,UAAU,QAAQ,QAAQ,KAAK,GAAG;EAe/C,MAAM;EACP;;;;AC5CH,eAAsB,oBAAoB,UAA+B,EAAE,EAA0B;CAEnG,MAAM,UAAU,IAAI,kBADH,eAAe,QAAQ,CACO;AAC/C,OAAM,QAAQ,gBAAgB;AAC9B,QAAO;;AAGT,IAAM,oBAAN,MAAiD;CAC/C;CACA;CACA,UAA8B,EAAE;CAEhC;CACA;CACA;CACA;CAEA,YAAY,SAAgC;AAC1C,OAAK,eAAe,GAAG,QAAQ,mBAAmB;AAClD,OAAK,UAAU;;CAGjB,MAAM,QAAiC;EACrC,MAAM,WAAW,MAAM,KAAK,SAAS;EACrC,MAAM,SAAS,MAAM,mBAAmB,KAAK,SAAS,QAAQ;AAE9D,QAAA,WAAiB,MAAM,aAAa,KAAK,SAAS,UAAU,OAAO;AAEnE,SAAO,MAAA;;CAGT,MAAM,QAAuB;AAC3B,QAAM,MAAA,QAAc,OAAO;AAC3B,QAAA,SAAe,KAAA;AAEf,QAAM,MAAA,YAAkB,OAAO;AAC/B,QAAA,aAAmB,KAAA;;CAGrB,MAAM,iBAAgC;AAEpC,OAAK,WADY,MAAM,KAAK,SAAS,EACb;;CAG1B,MAAM,WAA2C;AAC/C,QAAM,KAAK,OAAO;EAClB,MAAM,WAAW,MAAM,KAAK,SAAS;AAGrC,QAAA,aAAmB,MAAM,aACvB,YAHa,MAAM,mBAAmB,KAAK,SAAS,QAAQ,EAGxC;GAClB,SAAS;GACT,YAAY;GACZ,SAAS,CAAC,iCAAiC,KAAK,SAAS,SAAS,EAAE,oBAAoB,KAAK,QAAQ,CAAC;GACtG,MAAM,KAAK,QAAQ;GACnB,QAAQ;IACN,MAAM,KAAK,QAAQ;IACnB,MAAM,KAAK,QAAQ;IACnB,YAAY;IACb;GACF,CAAC,CACH;AAED,0BAAwB;GACtB,SAAS,KAAK;GACd,QAAQ,MAAA;GACR,UAAU,SAAS;GACnB,SAAS,SAAS;GACnB,CAAC;AAEF,QAAM,MAAA,WAAiB,QAAQ;EAE/B,MAAM,SAAS,kBAAkB,MAAA,WAAiB;AAElD,SAAO;GACL,aAAa;GACb,MAAM;GACN,aAAa,KAAK,QAAQ;GAC1B,WAAW;GACX,YAAY;GACZ,SAAS,OAAO,YACd,SAAS,QAAQ,KAAK,WAAW,CAAC,OAAO,KAAK,EAAE,YAAY,OAAO,gBAAgB,CAAC,CAAC,CACtF;GACF;;CAGH,MAAM,wBAAwD;AAC5D,QAAM,KAAK,OAAO;EAClB,MAAM,WAAW,MAAM,KAAK,SAAS;AAErC,QAAA,WAAiB,MAAA,YAAmB,MAAM,KAAK,qBAAqB;AACpE,QAAA,SAAe,MAAM,kBAAkB;GACrC,UAAU,MAAA;GACV,SAAS,KAAK;GACd,QAAQ,MAAM,yBAAyB,KAAK,SAAS,MAAA,SAAe,OAAO;GAC3E,SAAS,SAAS;GACnB,CAAC;AAEF,SAAO;GACL,aAAa,MAAA,OAAa;GAC1B,MAAM;GACN,aAAa,KAAK,QAAQ;GAC1B,WAAW,MAAA,OAAa;GACxB,YAAY;GACZ,SAAS,OAAO,YACd,OAAO,QAAQ,MAAA,SAAe,QAAQ,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,KAAK,EAAE,YAAY,IAAI,OAAO,UAAU,CAAC,CAAC,CAC1G;GACF;;CAGH,MAAM,sBAA+C;AACnD,MAAI;AACF,UAAO,MAAM,aAAa,KAAK,aAAa;UACtC;AACN,UAAO,KAAK,OAAO;;;CAIvB,MAAM,UAA0C;AAC9C,QAAA,WAAiB,MAAM,eAAe,KAAK,QAAQ;AACnD,OAAK,UAAU,MAAA,SAAe;AAC9B,SAAO,MAAA;;;AAIX,eAAe,yBAAyB,SAAgC,aAAqB;CAC3F,MAAM,OAAO,kBAAkB,SAAS,YAAY;CACpD,MAAM,WAAW,MAAM,KAAK,KAAK;AACjC,QAAO,qBAAqB,GAAG,cAAc,KAAK,CAAC,KAAK,KAAK,SAAS,UAAU;;AAGlF,SAAS,kBAAkB,SAAgC,aAA6B;AACtF,QAAO,QAAQ,QAAQ,MAAM,YAAY"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gdansk/vite",
3
3
  "private": false,
4
- "version": "0.4.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.13",
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.5.2",
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 { Plugin } from "vite";
1
+ import { type PluginOption } from "vite";
2
2
  import type { GdanskPluginOptions } from "./types";
3
- export declare function gdansk(options?: GdanskPluginOptions): Plugin;
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
- assets?: string;
6
+ buildDirectory?: string;
7
+ refresh?: boolean | string | string[] | RefreshConfig | RefreshConfig[];
4
8
  root?: string;
5
- widgetsRoot?: string;
9
+ widgetsDirectory?: string;
6
10
  host?: string;
7
11
  port?: number;
8
12
  }
9
13
  export interface ResolvedGdanskOptions {
10
- generatedDir: string;
11
- generatedDirPath: string;
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
- widgetsRoot: string;
19
- widgetsRootPath: string;
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
- clientSource: string;
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
- ssrEntry: string;
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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"}