@gdansk/vite 0.5.0 → 0.6.1
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/dist/assets/{ssr-C3v_roWy.js → ssr-CVrNqk3G.js} +56 -15
- package/dist/assets/ssr-CVrNqk3G.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/runtime.js +6 -2
- package/dist/runtime.js.map +1 -1
- package/package.json +1 -1
- package/types/types.d.ts +3 -1
- package/dist/assets/ssr-C3v_roWy.js.map +0 -1
|
@@ -135,11 +135,13 @@ function resolveOptions(options = {}, configRoot) {
|
|
|
135
135
|
const widgetsDirectory = options.widgetsDirectory ?? "widgets";
|
|
136
136
|
const buildDirectory = options.buildDirectory ?? "dist";
|
|
137
137
|
const host = options.host ?? "127.0.0.1";
|
|
138
|
+
const ssr = options.ssr ?? false;
|
|
138
139
|
return {
|
|
139
140
|
buildDirectory,
|
|
140
141
|
buildDirectoryPath: resolve(root, buildDirectory),
|
|
141
142
|
host,
|
|
142
143
|
root,
|
|
144
|
+
ssr,
|
|
143
145
|
ssrEndpoint: "/ssr",
|
|
144
146
|
port: options.port ?? 13714,
|
|
145
147
|
widgetsDirectory,
|
|
@@ -240,7 +242,7 @@ function createBuildConfig(options, prepared) {
|
|
|
240
242
|
sharedPlugins: true,
|
|
241
243
|
async buildApp(builder) {
|
|
242
244
|
if (prepared.widgets.length > 0) await builder.build(builder.environments.client);
|
|
243
|
-
await builder.build(builder.environments.ssr);
|
|
245
|
+
if (options.ssr) await builder.build(builder.environments.ssr);
|
|
244
246
|
await finalizeBuildOutputs(options, prepared.widgets);
|
|
245
247
|
}
|
|
246
248
|
},
|
|
@@ -252,10 +254,11 @@ function createBuildConfig(options, prepared) {
|
|
|
252
254
|
},
|
|
253
255
|
environments: {
|
|
254
256
|
client: { build: createClientBuildOptions(options, prepared) },
|
|
255
|
-
ssr: {
|
|
257
|
+
...options.ssr ? { ssr: {
|
|
256
258
|
consumer: "server",
|
|
257
|
-
build: createSSRBuildOptions(options, prepared)
|
|
258
|
-
|
|
259
|
+
build: createSSRBuildOptions(options, prepared),
|
|
260
|
+
resolve: { noExternal: true }
|
|
261
|
+
} } : {}
|
|
259
262
|
}
|
|
260
263
|
};
|
|
261
264
|
}
|
|
@@ -272,12 +275,13 @@ async function buildWidgets(options, prepared, config = {}) {
|
|
|
272
275
|
plugins: [createGdanskVirtualModulesPlugin(options, prepared)],
|
|
273
276
|
root: options.root
|
|
274
277
|
}));
|
|
275
|
-
await build(mergeConfig(config, {
|
|
278
|
+
if (options.ssr) await build(mergeConfig(config, {
|
|
276
279
|
appType: "custom",
|
|
277
280
|
build: createSSRBuildOptions(options, prepared),
|
|
278
281
|
configFile: false,
|
|
279
282
|
plugins: [createGdanskVirtualModulesPlugin(options, prepared)],
|
|
280
|
-
root: options.root
|
|
283
|
+
root: options.root,
|
|
284
|
+
ssr: { noExternal: true }
|
|
281
285
|
}));
|
|
282
286
|
return finalizeBuildOutputs(options, prepared.widgets);
|
|
283
287
|
}
|
|
@@ -321,14 +325,22 @@ function createSSRBuildOptions(options, prepared) {
|
|
|
321
325
|
}
|
|
322
326
|
async function finalizeBuildOutputs(options, widgets) {
|
|
323
327
|
const clientManifest = await readClientManifest(resolve(options.buildDirectoryPath, CLIENT_MANIFEST_FILE));
|
|
328
|
+
const widgetBuildData = await Promise.all(widgets.map(async (widget) => {
|
|
329
|
+
const manifestEntry = getClientManifestEntry(widget, clientManifest);
|
|
330
|
+
const fallbackCss = await pathExists(resolve(options.root, widget.clientCss)) ? [widget.clientCss] : [];
|
|
331
|
+
return {
|
|
332
|
+
collectedCss: manifestEntry ? collectTransitiveCssHrefs(manifestEntry, clientManifest) : fallbackCss,
|
|
333
|
+
manifestEntry,
|
|
334
|
+
widget
|
|
335
|
+
};
|
|
336
|
+
}));
|
|
337
|
+
const cssReferenceCounts = countCssReferences(widgetBuildData.map(({ collectedCss }) => collectedCss));
|
|
324
338
|
const manifest = {
|
|
325
339
|
outDir: options.buildDirectory,
|
|
326
340
|
root: options.root,
|
|
327
|
-
server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`),
|
|
328
|
-
widgets: Object.fromEntries(await Promise.all(
|
|
329
|
-
const
|
|
330
|
-
const fallbackCss = await pathExists(resolve(options.root, widget.clientCss)) ? [widget.clientCss] : [];
|
|
331
|
-
const css = manifestEntry ? await normalizeWidgetCssOutputs(options, widget, manifestEntry.css ?? []) : fallbackCss;
|
|
341
|
+
...options.ssr ? { server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`) } : {},
|
|
342
|
+
widgets: Object.fromEntries(await Promise.all(widgetBuildData.map(async ({ collectedCss, manifestEntry, widget }) => {
|
|
343
|
+
const css = await normalizeWidgetCssOutputs(options, widget, collectedCss, cssReferenceCounts);
|
|
332
344
|
return [widget.key, {
|
|
333
345
|
client: manifestEntry ? toBuildPath(options, manifestEntry.file) : widget.clientEntry,
|
|
334
346
|
css,
|
|
@@ -337,12 +349,40 @@ async function finalizeBuildOutputs(options, widgets) {
|
|
|
337
349
|
})))
|
|
338
350
|
};
|
|
339
351
|
await writeJson$1(resolve(options.buildDirectoryPath, GDANSK_MANIFEST_FILE), manifest);
|
|
340
|
-
await writeProductionServer(options);
|
|
352
|
+
if (options.ssr) await writeProductionServer(options);
|
|
341
353
|
return manifest;
|
|
342
354
|
}
|
|
343
355
|
function getClientManifestEntry(widget, manifest) {
|
|
344
356
|
return Object.values(manifest).find((entry) => entry.file === `${widget.key}/client.js`);
|
|
345
357
|
}
|
|
358
|
+
function collectTransitiveCssHrefs(manifestEntry, manifest) {
|
|
359
|
+
const css = [];
|
|
360
|
+
const seenCss = /* @__PURE__ */ new Set();
|
|
361
|
+
const visitedEntries = /* @__PURE__ */ new Set();
|
|
362
|
+
const visit = (entry) => {
|
|
363
|
+
if (visitedEntries.has(entry.file)) return;
|
|
364
|
+
visitedEntries.add(entry.file);
|
|
365
|
+
for (const imported of entry.imports ?? []) {
|
|
366
|
+
const importedEntry = resolveImportedManifestEntry(imported, manifest);
|
|
367
|
+
if (importedEntry) visit(importedEntry);
|
|
368
|
+
}
|
|
369
|
+
for (const href of entry.css ?? []) {
|
|
370
|
+
if (seenCss.has(href)) continue;
|
|
371
|
+
seenCss.add(href);
|
|
372
|
+
css.push(href);
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
visit(manifestEntry);
|
|
376
|
+
return css;
|
|
377
|
+
}
|
|
378
|
+
function resolveImportedManifestEntry(imported, manifest) {
|
|
379
|
+
return manifest[imported] ?? Object.values(manifest).find((entry) => entry.file === imported);
|
|
380
|
+
}
|
|
381
|
+
function countCssReferences(hrefLists) {
|
|
382
|
+
const counts = /* @__PURE__ */ new Map();
|
|
383
|
+
for (const hrefs of hrefLists) for (const href of hrefs) counts.set(href, (counts.get(href) ?? 0) + 1);
|
|
384
|
+
return counts;
|
|
385
|
+
}
|
|
346
386
|
async function readClientManifest(path) {
|
|
347
387
|
if (!await pathExists(path)) return {};
|
|
348
388
|
return JSON.parse(await readFile(path, "utf8"));
|
|
@@ -363,7 +403,7 @@ function findWidgetForAsset(widgets, assetCandidates) {
|
|
|
363
403
|
});
|
|
364
404
|
});
|
|
365
405
|
}
|
|
366
|
-
async function normalizeWidgetCssOutputs(options, widget, hrefs) {
|
|
406
|
+
async function normalizeWidgetCssOutputs(options, widget, hrefs, cssReferenceCounts) {
|
|
367
407
|
if (hrefs.length !== 1) return hrefs.map((href) => toBuildPath(options, href));
|
|
368
408
|
const [href] = hrefs;
|
|
369
409
|
const target = toOutputPath(options, widget.clientCss);
|
|
@@ -374,7 +414,7 @@ async function normalizeWidgetCssOutputs(options, widget, hrefs) {
|
|
|
374
414
|
const rewrittenCss = rewriteRelativeCssUrls(await readFile(sourcePath, "utf8"), posix.dirname(href), posix.dirname(target));
|
|
375
415
|
await mkdir(dirname(targetPath), { recursive: true });
|
|
376
416
|
await writeFile(targetPath, rewrittenCss);
|
|
377
|
-
await rm(sourcePath, { force: true });
|
|
417
|
+
if ((cssReferenceCounts.get(href) ?? 0) <= 1) await rm(sourcePath, { force: true });
|
|
378
418
|
return [toBuildPath(options, target)];
|
|
379
419
|
}
|
|
380
420
|
function rewriteRelativeCssUrls(css, fromDir, toDir) {
|
|
@@ -412,6 +452,7 @@ async function writeProductionServer(options) {
|
|
|
412
452
|
buildDirectory: options.buildDirectory,
|
|
413
453
|
host: options.host,
|
|
414
454
|
port: options.port,
|
|
455
|
+
ssr: options.ssr,
|
|
415
456
|
widgetsDirectory: options.widgetsDirectory
|
|
416
457
|
};
|
|
417
458
|
await writeFile(path, [
|
|
@@ -703,4 +744,4 @@ function writeJson(res, status, payload) {
|
|
|
703
744
|
//#endregion
|
|
704
745
|
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 };
|
|
705
746
|
|
|
706
|
-
//# sourceMappingURL=ssr-
|
|
747
|
+
//# sourceMappingURL=ssr-CVrNqk3G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-CVrNqk3G.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 ssr = options.ssr ?? false;\n const ssrEndpoint = \"/ssr\";\n\n return {\n buildDirectory,\n buildDirectoryPath: resolve(root, buildDirectory),\n host,\n root,\n ssr,\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 imports?: 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 if (options.ssr) {\n await builder.build(builder.environments.ssr);\n }\n\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 ...(options.ssr\n ? {\n ssr: {\n consumer: \"server\" as const,\n build: createSSRBuildOptions(options, prepared),\n resolve: {\n noExternal: true,\n },\n },\n }\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 if (options.ssr) {\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 ssr: {\n noExternal: true,\n },\n }),\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 const widgetBuildData = 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\n return {\n collectedCss: manifestEntry ? collectTransitiveCssHrefs(manifestEntry, clientManifest) : fallbackCss,\n manifestEntry,\n widget,\n };\n }),\n );\n const cssReferenceCounts = countCssReferences(widgetBuildData.map(({ collectedCss }) => collectedCss));\n\n const manifest: GdanskManifest = {\n outDir: options.buildDirectory,\n root: options.root,\n ...(options.ssr ? { server: toPosixPath(`${options.buildDirectory}/${SERVER_BUNDLE}`) } : {}),\n widgets: Object.fromEntries(\n await Promise.all(\n widgetBuildData.map(async ({ collectedCss, manifestEntry, widget }) => {\n const css = await normalizeWidgetCssOutputs(options, widget, collectedCss, cssReferenceCounts);\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 if (options.ssr) {\n await writeProductionServer(options);\n }\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\nfunction collectTransitiveCssHrefs(\n manifestEntry: ViteManifestEntry,\n manifest: Record<string, ViteManifestEntry>,\n): string[] {\n const css: string[] = [];\n const seenCss = new Set<string>();\n const visitedEntries = new Set<string>();\n\n const visit = (entry: ViteManifestEntry): void => {\n if (visitedEntries.has(entry.file)) {\n return;\n }\n\n visitedEntries.add(entry.file);\n\n for (const imported of entry.imports ?? []) {\n const importedEntry = resolveImportedManifestEntry(imported, manifest);\n if (importedEntry) {\n visit(importedEntry);\n }\n }\n\n for (const href of entry.css ?? []) {\n if (seenCss.has(href)) {\n continue;\n }\n\n seenCss.add(href);\n css.push(href);\n }\n };\n\n visit(manifestEntry);\n\n return css;\n}\n\nfunction resolveImportedManifestEntry(\n imported: string,\n manifest: Record<string, ViteManifestEntry>,\n): ViteManifestEntry | undefined {\n return manifest[imported] ?? Object.values(manifest).find((entry) => entry.file === imported);\n}\n\nfunction countCssReferences(hrefLists: string[][]): Map<string, number> {\n const counts = new Map<string, number>();\n\n for (const hrefs of hrefLists) {\n for (const href of hrefs) {\n counts.set(href, (counts.get(href) ?? 0) + 1);\n }\n }\n\n return counts;\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 cssReferenceCounts: ReadonlyMap<string, number>,\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 if ((cssReferenceCounts.get(href) ?? 0) <= 1) {\n await rm(sourcePath, { force: true });\n }\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 ssr: options.ssr,\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,4 @@
|
|
|
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-
|
|
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-CVrNqk3G.js";
|
|
2
2
|
import { mergeConfig } from "vite";
|
|
3
3
|
//#region src/plugin.ts
|
|
4
4
|
function gdansk(options = {}) {
|
package/dist/runtime.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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-
|
|
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-CVrNqk3G.js";
|
|
2
2
|
import { createServer, mergeConfig } from "vite";
|
|
3
3
|
import { stat } from "node:fs/promises";
|
|
4
4
|
import { resolve } from "node:path";
|
|
@@ -121,7 +121,9 @@ var GdanskRuntimeImpl = class {
|
|
|
121
121
|
async startProductionServer() {
|
|
122
122
|
await this.close();
|
|
123
123
|
const prepared = await this.prepare();
|
|
124
|
+
if (!this.options.ssr) throw new Error("Production SSR is disabled. Enable gdansk({ ssr: true }) before starting the SSR server.");
|
|
124
125
|
this.#manifest = this.#manifest ?? await this.loadOrBuildManifest();
|
|
126
|
+
if (!this.#manifest.server) throw new Error("Production SSR is enabled, but the build manifest has no server entry.");
|
|
125
127
|
this.#server = await startGdanskServer({
|
|
126
128
|
manifest: this.#manifest,
|
|
127
129
|
options: this.options,
|
|
@@ -139,7 +141,9 @@ var GdanskRuntimeImpl = class {
|
|
|
139
141
|
}
|
|
140
142
|
async loadOrBuildManifest() {
|
|
141
143
|
try {
|
|
142
|
-
|
|
144
|
+
const manifest = await readManifest(this.manifestPath);
|
|
145
|
+
if (this.options.ssr && !manifest.server) return this.build();
|
|
146
|
+
return manifest;
|
|
143
147
|
} catch {
|
|
144
148
|
return this.build();
|
|
145
149
|
}
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","names":["#manifest","#server","#viteServer","#prepared"],"sources":["../src/server.ts","../src/runtime.ts"],"sourcesContent":["import { serve } from \"@hono/node-server\";\nimport { serveStatic } from \"@hono/node-server/serve-static\";\nimport { Hono } from \"hono\";\n\nimport { HEALTH_ENDPOINT, processSSRRequest } from \"./ssr\";\nimport type { GdanskServerHandle, GdanskServerOptions } from \"./types\";\n\nexport async function startGdanskServer(options: GdanskServerOptions): Promise<GdanskServerHandle> {\n const app = new Hono();\n const outDirPrefix = `/${options.options.buildDirectory.replace(/^\\/+/, \"\")}`;\n\n app.get(HEALTH_ENDPOINT, (c) => c.json({ status: \"OK\" }));\n\n app.post(options.options.ssrEndpoint, async (c) => {\n const requestBody = await c.req.text();\n const result = await processSSRRequest({\n manifest: options.manifest,\n render: options.render,\n requestBody,\n widgets: options.widgets,\n });\n\n return c.json(result.payload, result.status);\n });\n\n app.use(\n `${outDirPrefix}/*`,\n serveStatic({\n onFound: (_, c) => {\n c.header(\"Access-Control-Allow-Origin\", \"*\");\n c.header(\"Cache-Control\", \"public, max-age=31536000, immutable\");\n },\n root: options.options.root,\n }),\n );\n\n let resolvedPort = options.options.port;\n\n const server = await new Promise<ReturnType<typeof serve>>((resolveServer) => {\n const instance = serve(\n {\n fetch: app.fetch,\n hostname: options.options.host,\n port: options.options.port,\n },\n (info) => {\n resolvedPort = info.port;\n resolveServer(instance);\n },\n );\n });\n\n const origin = `http://${options.options.host}:${resolvedPort}`;\n\n return {\n close: () =>\n new Promise<void>((resolveClose, rejectClose) => {\n server.close((error) => {\n if (error) {\n rejectClose(error);\n return;\n }\n\n resolveClose();\n });\n }),\n origin,\n port: resolvedPort,\n };\n}\n","import { stat } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { createServer, mergeConfig } from \"vite\";\n\nimport { buildWidgets, readManifest } from \"./build\";\nimport { loadUserViteConfig, prepareProject, resolveOptions } from \"./context\";\nimport { resolveViteOrigin } from \"./css\";\nimport { createRefreshPlugin } from \"./development\";\nimport { startGdanskServer } from \"./server\";\nimport { installDevSSRMiddleware, importRenderFunction } from \"./ssr\";\nimport type {\n GdanskManifest,\n GdanskPluginOptions,\n GdanskPreparedProject,\n GdanskRuntime,\n GdanskRuntimeMetadata,\n GdanskServerHandle,\n ResolvedGdanskOptions,\n WidgetDefinition,\n} from \"./types\";\nimport { createGdanskVirtualModulesPlugin } from \"./virtual\";\n\nexport async function createGdanskRuntime(options: GdanskPluginOptions = {}): Promise<GdanskRuntime> {\n const resolved = resolveOptions(options);\n const runtime = new GdanskRuntimeImpl(resolved);\n await runtime.refreshWidgets();\n return runtime;\n}\n\nclass GdanskRuntimeImpl implements GdanskRuntime {\n readonly manifestPath: string;\n readonly options: ResolvedGdanskOptions;\n widgets: WidgetDefinition[] = [];\n\n #manifest?: GdanskManifest;\n #prepared?: GdanskPreparedProject;\n #server?: GdanskServerHandle;\n #viteServer?: Awaited<ReturnType<typeof createServer>>;\n\n constructor(options: ResolvedGdanskOptions) {\n this.manifestPath = `${options.buildDirectoryPath}/gdansk-manifest.json`;\n this.options = options;\n }\n\n async build(): Promise<GdanskManifest> {\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"build\");\n\n this.#manifest = await buildWidgets(this.options, prepared, config);\n\n return this.#manifest;\n }\n\n async close(): Promise<void> {\n await this.#server?.close();\n this.#server = undefined;\n\n await this.#viteServer?.close();\n this.#viteServer = undefined;\n }\n\n async refreshWidgets(): Promise<void> {\n const prepared = await this.prepare();\n this.widgets = prepared.widgets;\n }\n\n async startDev(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n const config = await loadUserViteConfig(this.options, \"serve\");\n\n this.#viteServer = await createServer(\n mergeConfig(config, {\n appType: \"custom\",\n configFile: false,\n plugins: [createGdanskVirtualModulesPlugin(this.options, prepared), createRefreshPlugin(this.options)],\n root: this.options.root,\n server: {\n host: this.options.host,\n port: this.options.port,\n strictPort: true,\n },\n }),\n );\n\n installDevSSRMiddleware({\n options: this.options,\n server: this.#viteServer,\n ssrEntry: prepared.ssrEntryId,\n widgets: prepared.widgets,\n });\n\n await this.#viteServer.listen();\n\n const origin = resolveViteOrigin(this.#viteServer);\n\n return {\n assetOrigin: origin,\n mode: \"development\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: origin,\n viteOrigin: origin,\n widgets: Object.fromEntries(\n prepared.widgets.map((widget) => [widget.key, { clientPath: widget.clientDevEntry }]),\n ),\n };\n }\n\n async startProductionServer(): Promise<GdanskRuntimeMetadata> {\n await this.close();\n const prepared = await this.prepare();\n\n this.#manifest = this.#manifest ?? (await this.loadOrBuildManifest());\n this.#server = await startGdanskServer({\n manifest: this.#manifest,\n options: this.options,\n render: await loadServerRenderFunction(this.options, this.#manifest.server),\n widgets: prepared.widgets,\n });\n\n return {\n assetOrigin: this.#server.origin,\n mode: \"production\",\n ssrEndpoint: this.options.ssrEndpoint,\n ssrOrigin: this.#server.origin,\n viteOrigin: null,\n widgets: Object.fromEntries(\n Object.entries(this.#manifest.widgets).map(([key, widget]) => [key, { clientPath: `/${widget.client}` }]),\n ),\n };\n }\n\n async loadOrBuildManifest(): Promise<GdanskManifest> {\n try {\n return await readManifest(this.manifestPath);\n } catch {\n return this.build();\n }\n }\n\n async prepare(): Promise<GdanskPreparedProject> {\n this.#prepared = await prepareProject(this.options);\n this.widgets = this.#prepared.widgets;\n return this.#prepared;\n }\n}\n\nasync function loadServerRenderFunction(options: ResolvedGdanskOptions, serverEntry: string) {\n const path = resolveServerPath(options, serverEntry);\n const modified = await stat(path);\n return importRenderFunction(`${pathToFileURL(path).href}?t=${modified.mtimeMs}`);\n}\n\nfunction resolveServerPath(options: ResolvedGdanskOptions, serverEntry: string): string {\n return resolve(options.root, serverEntry);\n}\n"],"mappings":"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"}
|
|
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 if (!this.options.ssr) {\n throw new Error(\"Production SSR is disabled. Enable gdansk({ ssr: true }) before starting the SSR server.\");\n }\n\n this.#manifest = this.#manifest ?? (await this.loadOrBuildManifest());\n if (!this.#manifest.server) {\n throw new Error(\"Production SSR is enabled, but the build manifest has no server entry.\");\n }\n\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 const manifest = await readManifest(this.manifestPath);\n if (this.options.ssr && !manifest.server) {\n return this.build();\n }\n\n return manifest;\n } catch {\n return this.build();\n }\n }\n\n async prepare(): Promise<GdanskPreparedProject> {\n this.#prepared = await prepareProject(this.options);\n this.widgets = this.#prepared.widgets;\n return this.#prepared;\n }\n}\n\nasync function loadServerRenderFunction(options: ResolvedGdanskOptions, serverEntry: string) {\n const path = resolveServerPath(options, serverEntry);\n const modified = await stat(path);\n return importRenderFunction(`${pathToFileURL(path).href}?t=${modified.mtimeMs}`);\n}\n\nfunction resolveServerPath(options: ResolvedGdanskOptions, serverEntry: string): string {\n return resolve(options.root, serverEntry);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/types/types.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface GdanskPluginOptions {
|
|
|
6
6
|
buildDirectory?: string;
|
|
7
7
|
refresh?: boolean | string | string[] | RefreshConfig | RefreshConfig[];
|
|
8
8
|
root?: string;
|
|
9
|
+
ssr?: boolean;
|
|
9
10
|
widgetsDirectory?: string;
|
|
10
11
|
host?: string;
|
|
11
12
|
port?: number;
|
|
@@ -15,6 +16,7 @@ export interface ResolvedGdanskOptions {
|
|
|
15
16
|
buildDirectoryPath: string;
|
|
16
17
|
host: string;
|
|
17
18
|
root: string;
|
|
19
|
+
ssr: boolean;
|
|
18
20
|
ssrEndpoint: string;
|
|
19
21
|
port: number;
|
|
20
22
|
widgetsDirectory: string;
|
|
@@ -37,7 +39,7 @@ export interface ManifestWidget {
|
|
|
37
39
|
export interface GdanskManifest {
|
|
38
40
|
outDir: string;
|
|
39
41
|
root: string;
|
|
40
|
-
server
|
|
42
|
+
server?: string;
|
|
41
43
|
widgets: Record<string, ManifestWidget>;
|
|
42
44
|
}
|
|
43
45
|
export interface GdanskRuntimeMetadata {
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|