mokup 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -246,6 +246,34 @@ function buildManifestData(params) {
246
246
  };
247
247
  }
248
248
 
249
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.CYGG6ENd.cjs', document.baseURI).href)));
250
+ const mimeTypes = {
251
+ ".html": "text/html; charset=utf-8",
252
+ ".css": "text/css; charset=utf-8",
253
+ ".js": "text/javascript; charset=utf-8",
254
+ ".map": "application/json; charset=utf-8",
255
+ ".json": "application/json; charset=utf-8",
256
+ ".svg": "image/svg+xml",
257
+ ".png": "image/png",
258
+ ".jpg": "image/jpeg",
259
+ ".jpeg": "image/jpeg",
260
+ ".ico": "image/x-icon"
261
+ };
262
+ function resolvePlaygroundDist() {
263
+ const pkgPath = require$1.resolve("@mokup/playground/package.json");
264
+ return pathe.join(pkgPath, "..", "dist");
265
+ }
266
+ function sendJson(res, data, statusCode = 200) {
267
+ res.statusCode = statusCode;
268
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
269
+ res.end(JSON.stringify(data, null, 2));
270
+ }
271
+ function sendFile(res, content, contentType) {
272
+ res.statusCode = 200;
273
+ res.setHeader("Content-Type", contentType);
274
+ res.end(content);
275
+ }
276
+
249
277
  function normalizePlaygroundPath(value) {
250
278
  if (!value) {
251
279
  return "/__mokup";
@@ -272,43 +300,16 @@ function resolvePlaygroundRequestPath(base, playgroundPath) {
272
300
  }
273
301
  function resolvePlaygroundOptions(playground) {
274
302
  if (playground === false) {
275
- return { enabled: false, path: "/__mokup" };
303
+ return { enabled: false, path: "/__mokup", build: false };
276
304
  }
277
305
  if (playground && typeof playground === "object") {
278
306
  return {
279
307
  enabled: playground.enabled !== false,
280
- path: normalizePlaygroundPath(playground.path)
308
+ path: normalizePlaygroundPath(playground.path),
309
+ build: playground.build === true
281
310
  };
282
311
  }
283
- return { enabled: true, path: "/__mokup" };
284
- }
285
-
286
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.i875Kuim.cjs', document.baseURI).href)));
287
- const mimeTypes = {
288
- ".html": "text/html; charset=utf-8",
289
- ".css": "text/css; charset=utf-8",
290
- ".js": "text/javascript; charset=utf-8",
291
- ".map": "application/json; charset=utf-8",
292
- ".json": "application/json; charset=utf-8",
293
- ".svg": "image/svg+xml",
294
- ".png": "image/png",
295
- ".jpg": "image/jpeg",
296
- ".jpeg": "image/jpeg",
297
- ".ico": "image/x-icon"
298
- };
299
- function resolvePlaygroundDist() {
300
- const pkgPath = require$1.resolve("@mokup/playground/package.json");
301
- return pathe.join(pkgPath, "..", "dist");
302
- }
303
- function sendJson(res, data, statusCode = 200) {
304
- res.statusCode = statusCode;
305
- res.setHeader("Content-Type", "application/json; charset=utf-8");
306
- res.end(JSON.stringify(data, null, 2));
307
- }
308
- function sendFile(res, content, contentType) {
309
- res.statusCode = 200;
310
- res.setHeader("Content-Type", contentType);
311
- res.end(content);
312
+ return { enabled: true, path: "/__mokup", build: false };
312
313
  }
313
314
 
314
315
  function toPosixPath(value) {
@@ -774,6 +775,7 @@ function resolveSwUnregisterConfig(options, logger) {
774
775
  function buildSwScript(params) {
775
776
  const { routes, root } = params;
776
777
  const runtimeImportPath = params.runtimeImportPath ?? "mokup/runtime";
778
+ const loggerImportPath = params.loggerImportPath ?? "@mokup/shared/logger";
777
779
  const basePaths = params.basePaths ?? [];
778
780
  const resolveModulePath = params.resolveModulePath ?? toViteImportPath;
779
781
  const { manifest, modules } = buildManifestData({
@@ -782,7 +784,7 @@ function buildSwScript(params) {
782
784
  resolveModulePath
783
785
  });
784
786
  const imports = [
785
- "import { createLogger } from '@mokup/shared/logger'",
787
+ `import { createLogger } from ${JSON.stringify(loggerImportPath)}`,
786
788
  `import { createRuntimeApp, handle } from ${JSON.stringify(runtimeImportPath)}`
787
789
  ];
788
790
  const moduleEntries = [];
@@ -1315,7 +1317,7 @@ function isConfigFile(file) {
1315
1317
  return configExtensions.includes(ext);
1316
1318
  }
1317
1319
 
1318
- const sourceRoot = pathe.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.i875Kuim.cjs', document.baseURI).href))));
1320
+ const sourceRoot = pathe.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.CYGG6ENd.cjs', document.baseURI).href))));
1319
1321
  const mokupSourceEntry = pathe.resolve(sourceRoot, "../index.ts");
1320
1322
  const mokupViteSourceEntry = pathe.resolve(sourceRoot, "../vite.ts");
1321
1323
  const hasMokupSourceEntry = node_fs.existsSync(mokupSourceEntry);
@@ -1340,7 +1342,7 @@ const workspaceResolvePlugin = createWorkspaceResolvePlugin();
1340
1342
  async function loadModule(file) {
1341
1343
  const ext = pathe.extname(file).toLowerCase();
1342
1344
  if (ext === ".cjs") {
1343
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.i875Kuim.cjs', document.baseURI).href)));
1345
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('shared/mokup.CYGG6ENd.cjs', document.baseURI).href)));
1344
1346
  delete require$1.cache[file];
1345
1347
  return require$1(file);
1346
1348
  }
@@ -2062,11 +2064,21 @@ exports.createDebouncer = createDebouncer;
2062
2064
  exports.createHonoApp = createHonoApp;
2063
2065
  exports.createMiddleware = createMiddleware;
2064
2066
  exports.createPlaygroundMiddleware = createPlaygroundMiddleware;
2067
+ exports.injectPlaygroundSw = injectPlaygroundSw;
2065
2068
  exports.isInDirs = isInDirs;
2069
+ exports.normalizePlaygroundPath = normalizePlaygroundPath;
2066
2070
  exports.resolveDirs = resolveDirs;
2071
+ exports.resolveGroupRoot = resolveGroupRoot;
2072
+ exports.resolveGroups = resolveGroups;
2073
+ exports.resolvePlaygroundDist = resolvePlaygroundDist;
2067
2074
  exports.resolvePlaygroundOptions = resolvePlaygroundOptions;
2075
+ exports.resolvePlaygroundRequestPath = resolvePlaygroundRequestPath;
2068
2076
  exports.resolveSwConfig = resolveSwConfig;
2069
2077
  exports.resolveSwUnregisterConfig = resolveSwUnregisterConfig;
2070
2078
  exports.scanRoutes = scanRoutes;
2071
2079
  exports.sortRoutes = sortRoutes;
2080
+ exports.toPlaygroundConfigFile = toPlaygroundConfigFile;
2081
+ exports.toPlaygroundDisabledRoute = toPlaygroundDisabledRoute;
2082
+ exports.toPlaygroundIgnoredRoute = toPlaygroundIgnoredRoute;
2083
+ exports.toPlaygroundRoute = toPlaygroundRoute;
2072
2084
  exports.toPosix = toPosix;
@@ -243,6 +243,34 @@ function buildManifestData(params) {
243
243
  };
244
244
  }
245
245
 
246
+ const require$1 = createRequire(import.meta.url);
247
+ const mimeTypes = {
248
+ ".html": "text/html; charset=utf-8",
249
+ ".css": "text/css; charset=utf-8",
250
+ ".js": "text/javascript; charset=utf-8",
251
+ ".map": "application/json; charset=utf-8",
252
+ ".json": "application/json; charset=utf-8",
253
+ ".svg": "image/svg+xml",
254
+ ".png": "image/png",
255
+ ".jpg": "image/jpeg",
256
+ ".jpeg": "image/jpeg",
257
+ ".ico": "image/x-icon"
258
+ };
259
+ function resolvePlaygroundDist() {
260
+ const pkgPath = require$1.resolve("@mokup/playground/package.json");
261
+ return join(pkgPath, "..", "dist");
262
+ }
263
+ function sendJson(res, data, statusCode = 200) {
264
+ res.statusCode = statusCode;
265
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
266
+ res.end(JSON.stringify(data, null, 2));
267
+ }
268
+ function sendFile(res, content, contentType) {
269
+ res.statusCode = 200;
270
+ res.setHeader("Content-Type", contentType);
271
+ res.end(content);
272
+ }
273
+
246
274
  function normalizePlaygroundPath(value) {
247
275
  if (!value) {
248
276
  return "/__mokup";
@@ -269,43 +297,16 @@ function resolvePlaygroundRequestPath(base, playgroundPath) {
269
297
  }
270
298
  function resolvePlaygroundOptions(playground) {
271
299
  if (playground === false) {
272
- return { enabled: false, path: "/__mokup" };
300
+ return { enabled: false, path: "/__mokup", build: false };
273
301
  }
274
302
  if (playground && typeof playground === "object") {
275
303
  return {
276
304
  enabled: playground.enabled !== false,
277
- path: normalizePlaygroundPath(playground.path)
305
+ path: normalizePlaygroundPath(playground.path),
306
+ build: playground.build === true
278
307
  };
279
308
  }
280
- return { enabled: true, path: "/__mokup" };
281
- }
282
-
283
- const require$1 = createRequire(import.meta.url);
284
- const mimeTypes = {
285
- ".html": "text/html; charset=utf-8",
286
- ".css": "text/css; charset=utf-8",
287
- ".js": "text/javascript; charset=utf-8",
288
- ".map": "application/json; charset=utf-8",
289
- ".json": "application/json; charset=utf-8",
290
- ".svg": "image/svg+xml",
291
- ".png": "image/png",
292
- ".jpg": "image/jpeg",
293
- ".jpeg": "image/jpeg",
294
- ".ico": "image/x-icon"
295
- };
296
- function resolvePlaygroundDist() {
297
- const pkgPath = require$1.resolve("@mokup/playground/package.json");
298
- return join(pkgPath, "..", "dist");
299
- }
300
- function sendJson(res, data, statusCode = 200) {
301
- res.statusCode = statusCode;
302
- res.setHeader("Content-Type", "application/json; charset=utf-8");
303
- res.end(JSON.stringify(data, null, 2));
304
- }
305
- function sendFile(res, content, contentType) {
306
- res.statusCode = 200;
307
- res.setHeader("Content-Type", contentType);
308
- res.end(content);
309
+ return { enabled: true, path: "/__mokup", build: false };
309
310
  }
310
311
 
311
312
  function toPosixPath(value) {
@@ -771,6 +772,7 @@ function resolveSwUnregisterConfig(options, logger) {
771
772
  function buildSwScript(params) {
772
773
  const { routes, root } = params;
773
774
  const runtimeImportPath = params.runtimeImportPath ?? "mokup/runtime";
775
+ const loggerImportPath = params.loggerImportPath ?? "@mokup/shared/logger";
774
776
  const basePaths = params.basePaths ?? [];
775
777
  const resolveModulePath = params.resolveModulePath ?? toViteImportPath;
776
778
  const { manifest, modules } = buildManifestData({
@@ -779,7 +781,7 @@ function buildSwScript(params) {
779
781
  resolveModulePath
780
782
  });
781
783
  const imports = [
782
- "import { createLogger } from '@mokup/shared/logger'",
784
+ `import { createLogger } from ${JSON.stringify(loggerImportPath)}`,
783
785
  `import { createRuntimeApp, handle } from ${JSON.stringify(runtimeImportPath)}`
784
786
  ];
785
787
  const moduleEntries = [];
@@ -2053,4 +2055,4 @@ async function scanRoutes(params) {
2053
2055
  return sortRoutes(routes);
2054
2056
  }
2055
2057
 
2056
- export { sortRoutes as a, buildSwScript as b, createHonoApp as c, createDebouncer as d, resolvePlaygroundOptions as e, resolveSwConfig as f, resolveSwUnregisterConfig as g, createPlaygroundMiddleware as h, isInDirs as i, createMiddleware as j, buildManifestData as k, resolveDirs as r, scanRoutes as s, toPosix as t };
2058
+ export { sortRoutes as a, buildSwScript as b, createHonoApp as c, createDebouncer as d, resolvePlaygroundOptions as e, resolveSwConfig as f, resolveSwUnregisterConfig as g, createPlaygroundMiddleware as h, isInDirs as i, createMiddleware as j, buildManifestData as k, resolvePlaygroundDist as l, injectPlaygroundSw as m, normalizePlaygroundPath as n, resolveGroupRoot as o, resolveGroups as p, resolvePlaygroundRequestPath as q, resolveDirs as r, scanRoutes as s, toPosix as t, toPlaygroundConfigFile as u, toPlaygroundIgnoredRoute as v, toPlaygroundDisabledRoute as w, toPlaygroundRoute as x };
package/dist/vite.cjs CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const process = require('node:process');
4
- const scanner = require('./shared/mokup.i875Kuim.cjs');
4
+ const scanner = require('./shared/mokup.CYGG6ENd.cjs');
5
+ const node_fs = require('node:fs');
6
+ const pathe = require('@mokup/shared/pathe');
5
7
  const logger = require('@mokup/shared/logger');
6
8
  const pc = require('picocolors');
7
9
  const node_path = require('node:path');
8
10
  const chokidar = require('@mokup/shared/chokidar');
9
- const node_fs = require('node:fs');
10
11
  const node_url = require('node:url');
11
- require('@mokup/shared/pathe');
12
12
  require('node:module');
13
13
  require('node:buffer');
14
14
  require('@mokup/shared/hono');
@@ -64,6 +64,79 @@ function buildBundleModule(params) {
64
64
  return lines.join("\n");
65
65
  }
66
66
 
67
+ function resolvePlaygroundOutDir(outDir, playgroundPath) {
68
+ const normalized = scanner.normalizePlaygroundPath(playgroundPath);
69
+ const trimmed = normalized.replace(/^\/+/, "");
70
+ return trimmed ? pathe.join(outDir, pathe.normalize(trimmed)) : outDir;
71
+ }
72
+ function stripSwLifecycle(html) {
73
+ return html.replace(
74
+ /<script[^>]*mokup-sw-lifecycle\.js[^>]*><\/script>\s*/gi,
75
+ ""
76
+ );
77
+ }
78
+ async function writeRoutesPayload(params, targetDir) {
79
+ const baseRoot = scanner.resolveGroupRoot(params.dirs, params.root);
80
+ const groups = scanner.resolveGroups(params.dirs, baseRoot);
81
+ const basePath = scanner.resolvePlaygroundRequestPath(params.base, params.playgroundPath);
82
+ const payload = {
83
+ basePath,
84
+ root: baseRoot,
85
+ count: params.routes.length,
86
+ groups: groups.map((group) => ({ key: group.key, label: group.label })),
87
+ routes: params.routes.map((route) => scanner.toPlaygroundRoute(route, baseRoot, groups)),
88
+ disabled: params.disabledRoutes.map(
89
+ (route) => scanner.toPlaygroundDisabledRoute(route, baseRoot, groups)
90
+ ),
91
+ ignored: params.ignoredRoutes.map(
92
+ (route) => scanner.toPlaygroundIgnoredRoute(route, baseRoot, groups)
93
+ ),
94
+ configs: params.configFiles.map((entry) => scanner.toPlaygroundConfigFile(entry, baseRoot, groups)),
95
+ disabledConfigs: params.disabledConfigFiles.map(
96
+ (entry) => scanner.toPlaygroundConfigFile(entry, baseRoot, groups)
97
+ )
98
+ };
99
+ await node_fs.promises.writeFile(
100
+ pathe.join(targetDir, "routes"),
101
+ JSON.stringify(payload, null, 2),
102
+ "utf8"
103
+ );
104
+ }
105
+ async function updateIndexHtml(targetDir, swScript) {
106
+ const indexPath = pathe.join(targetDir, "index.html");
107
+ const html = await node_fs.promises.readFile(indexPath, "utf8");
108
+ const cleaned = stripSwLifecycle(html);
109
+ const output = swScript ? scanner.injectPlaygroundSw(cleaned, swScript) : cleaned;
110
+ await node_fs.promises.writeFile(indexPath, output, "utf8");
111
+ }
112
+ async function removeLegacySwAsset(targetDir) {
113
+ const legacyFiles = [
114
+ pathe.join(targetDir, "assets", "mokup-sw-lifecycle.js"),
115
+ pathe.join(targetDir, "assets", "mokup-sw-lifecycle.js.map")
116
+ ];
117
+ await Promise.all(legacyFiles.map((file) => node_fs.promises.rm(file, { force: true })));
118
+ }
119
+ async function writePlaygroundBuild(params) {
120
+ const distDir = scanner.resolvePlaygroundDist();
121
+ const targetDir = resolvePlaygroundOutDir(params.outDir, params.playgroundPath);
122
+ if (targetDir === params.outDir) {
123
+ params.logger.error("Playground build path resolves to the Vite outDir. Aborting output.");
124
+ return;
125
+ }
126
+ try {
127
+ await node_fs.promises.stat(distDir);
128
+ } catch (error) {
129
+ params.logger.error("Failed to locate playground assets:", error);
130
+ return;
131
+ }
132
+ await node_fs.promises.rm(targetDir, { recursive: true, force: true });
133
+ await node_fs.promises.mkdir(params.outDir, { recursive: true });
134
+ await node_fs.promises.cp(distDir, targetDir, { recursive: true });
135
+ await removeLegacySwAsset(targetDir);
136
+ await updateIndexHtml(targetDir, params.swScript);
137
+ await writeRoutesPayload(params, targetDir);
138
+ }
139
+
67
140
  const legacyEntryKeys = [
68
141
  "dir",
69
142
  "prefix",
@@ -148,6 +221,10 @@ function resolveSwRuntimeImportPath(base) {
148
221
  const normalizedBase = normalizeBase(base);
149
222
  return `${normalizedBase}@id/mokup/runtime`;
150
223
  }
224
+ function resolveSwLoggerImportPath(base) {
225
+ const normalizedBase = normalizeBase(base);
226
+ return `${normalizedBase}@id/@mokup/shared/logger`;
227
+ }
151
228
 
152
229
  function buildRouteSignature(routes, disabledRoutes, ignoredRoutes, configFiles, disabledConfigFiles) {
153
230
  return routes.map(
@@ -316,6 +393,47 @@ function addMiddlewareFirst(server, middleware) {
316
393
  server.middlewares.use(middleware);
317
394
  }
318
395
 
396
+ const portPattern = /:(?<port>\d{2,5})/g;
397
+ const escapeCode = 27;
398
+ function stripAnsi(value) {
399
+ let output = "";
400
+ for (let index = 0; index < value.length; index += 1) {
401
+ const code = value.charCodeAt(index);
402
+ if (code === escapeCode && value[index + 1] === "[") {
403
+ index += 1;
404
+ while (index < value.length && value[index] !== "m") {
405
+ index += 1;
406
+ }
407
+ continue;
408
+ }
409
+ output += value[index];
410
+ }
411
+ return output;
412
+ }
413
+ function formatOutputLine(line, options) {
414
+ const { arrowToken, formattedArrow, labels, formatLabel, formatPort } = options;
415
+ let output = formattedArrow ? line.replaceAll(arrowToken, formattedArrow) : line;
416
+ if (labels && formatLabel) {
417
+ for (const label of labels) {
418
+ output = output.replaceAll(label, formatLabel(label));
419
+ }
420
+ }
421
+ if (formatPort) {
422
+ output = output.replace(portPattern, (_match, port) => `:${formatPort(port)}`);
423
+ }
424
+ return output;
425
+ }
426
+
427
+ const arrowToken = "\u279C";
428
+ const playgroundLabel = "Mokup Playground";
429
+ const coloredArrow = pc__default.green(arrowToken);
430
+ const formatOptions = {
431
+ arrowToken,
432
+ formattedArrow: coloredArrow,
433
+ labels: [playgroundLabel],
434
+ formatLabel: pc__default.bold,
435
+ formatPort: pc__default.bold
436
+ };
319
437
  function patchPlaygroundPrintUrls(server, playgroundPath) {
320
438
  const originalPrintUrls = server.printUrls.bind(server);
321
439
  const patchPrintUrls = () => {
@@ -340,18 +458,22 @@ function patchPlaygroundPrintUrls(server, playgroundPath) {
340
458
  const localUrl = server.resolvedUrls?.local?.[0];
341
459
  const outputUrl = formatPlaygroundUrl(localUrl, playgroundPath);
342
460
  const coloredUrl = pc__default.magenta(outputUrl);
343
- const playgroundLine = ` \u279C Mokup Playground: ${coloredUrl}`;
344
- const ansiEscape = "\x1B";
345
- const ansiPattern = new RegExp(`${ansiEscape}\\[[0-9;]*m`, "g");
346
- const stripAnsi = (value) => value.replace(ansiPattern, "");
461
+ const playgroundLine = ` ${arrowToken} ${playgroundLabel}: ${coloredUrl}`;
462
+ const arrowPrefix = ` ${arrowToken} `;
347
463
  const findIndex = (needle) => lines.findIndex((args) => stripAnsi(args[0]).includes(needle));
348
- const networkIndex = findIndex(" \u279C Network:");
349
- const localIndex = findIndex(" \u279C Local:");
464
+ const networkIndex = findIndex(`${arrowPrefix}Network:`);
465
+ const localIndex = findIndex(`${arrowPrefix}Local:`);
350
466
  const insertIndex = networkIndex >= 0 ? networkIndex + 1 : localIndex >= 0 ? localIndex + 1 : lines.length;
351
467
  const outputLines = lines.slice();
352
468
  outputLines.splice(insertIndex, 0, [playgroundLine]);
353
469
  for (const args of outputLines) {
354
- originalInfo(...args);
470
+ if (typeof args[0] === "string") {
471
+ const nextArgs = args.slice();
472
+ nextArgs[0] = formatOutputLine(nextArgs[0], formatOptions);
473
+ originalInfo(...nextArgs);
474
+ } else {
475
+ originalInfo(...args);
476
+ }
355
477
  }
356
478
  };
357
479
  Object.defineProperty(server, "printUrls", {
@@ -476,6 +598,7 @@ async function configureDevServer(params) {
476
598
  routes: state.swRoutes,
477
599
  root,
478
600
  runtimeImportPath: resolveSwRuntimeImportPath(base),
601
+ loggerImportPath: resolveSwLoggerImportPath(base),
479
602
  basePaths: swConfig?.basePaths ?? []
480
603
  });
481
604
  res.statusCode = 200;
@@ -564,17 +687,35 @@ async function configurePreviewServer(params) {
564
687
  }
565
688
 
566
689
  const swModuleCandidates = [
567
- new URL("../../sw.ts", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite.cjs', document.baseURI).href))),
568
- new URL("../../sw.js", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite.cjs', document.baseURI).href)))
690
+ "dist/sw.mjs",
691
+ "dist/sw.js",
692
+ "src/sw.ts",
693
+ "src/sw.js"
569
694
  ];
695
+ function resolvePackageRoot() {
696
+ const moduleDir = node_path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite.cjs', document.baseURI).href))));
697
+ let current = moduleDir;
698
+ for (let index = 0; index < 6; index += 1) {
699
+ if (node_fs.existsSync(node_path.resolve(current, "package.json"))) {
700
+ return current;
701
+ }
702
+ const parent = node_path.dirname(current);
703
+ if (parent === current) {
704
+ break;
705
+ }
706
+ current = parent;
707
+ }
708
+ return moduleDir;
709
+ }
570
710
  const localSwModulePath = (() => {
711
+ const packageRoot = resolvePackageRoot();
571
712
  for (const candidate of swModuleCandidates) {
572
- const filePath = node_url.fileURLToPath(candidate);
713
+ const filePath = node_path.resolve(packageRoot, candidate);
573
714
  if (node_fs.existsSync(filePath)) {
574
715
  return filePath;
575
716
  }
576
717
  }
577
- return node_url.fileURLToPath(swModuleCandidates[0] ?? new URL("../../sw.ts", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite.cjs', document.baseURI).href))));
718
+ return node_path.resolve(packageRoot, "src/sw.ts");
578
719
  })();
579
720
  async function resolveSwModuleImport(context) {
580
721
  const resolved = await context.resolve("mokup/sw");
@@ -628,12 +769,102 @@ function buildSwLifecycleScript(params) {
628
769
  "})()"
629
770
  ].join("\n");
630
771
  }
772
+ function buildSwLifecycleInlineScript(params) {
773
+ const {
774
+ swConfig,
775
+ unregisterConfig,
776
+ hasSwEntries,
777
+ hasSwRoutes,
778
+ resolveRequestPath,
779
+ resolveRegisterScope
780
+ } = params;
781
+ const shouldUnregister = unregisterConfig.unregister === true || !hasSwEntries;
782
+ if (shouldUnregister) {
783
+ const path2 = resolveRequestPath(unregisterConfig.path);
784
+ const scope2 = resolveRegisterScope(unregisterConfig.scope);
785
+ return [
786
+ "(async () => {",
787
+ " if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {",
788
+ " return",
789
+ " }",
790
+ ` const path = ${JSON.stringify(path2)}`,
791
+ ` const scope = ${JSON.stringify(scope2)}`,
792
+ " const origin = window.location.origin",
793
+ " const normalizeScope = (value) => {",
794
+ " const url = new URL(value, origin)",
795
+ " if (!url.pathname.endsWith('/')) {",
796
+ " url.pathname = url.pathname + '/'",
797
+ " }",
798
+ " return url.href",
799
+ " }",
800
+ " const pathUrl = new URL(path, origin)",
801
+ " const scopeUrl = normalizeScope(scope)",
802
+ " const matchesScript = (scriptUrl) => {",
803
+ " if (!scriptUrl) {",
804
+ " return false",
805
+ " }",
806
+ " try {",
807
+ " const parsed = new URL(scriptUrl)",
808
+ " return parsed.origin === origin && parsed.pathname === pathUrl.pathname",
809
+ " }",
810
+ " catch {",
811
+ " return false",
812
+ " }",
813
+ " }",
814
+ " try {",
815
+ " const registrations = await navigator.serviceWorker.getRegistrations()",
816
+ " for (const registration of registrations) {",
817
+ " if (registration.scope !== scopeUrl) {",
818
+ " continue",
819
+ " }",
820
+ " const scriptUrls = [",
821
+ " registration.active?.scriptURL,",
822
+ " registration.waiting?.scriptURL,",
823
+ " registration.installing?.scriptURL,",
824
+ " ]",
825
+ " if (scriptUrls.some(matchesScript)) {",
826
+ " await registration.unregister()",
827
+ " }",
828
+ " }",
829
+ " }",
830
+ " catch (error) {",
831
+ " console.warn('Failed to unregister service worker:', error)",
832
+ " }",
833
+ "})()"
834
+ ].join("\n");
835
+ }
836
+ if (!swConfig || swConfig.register === false) {
837
+ return null;
838
+ }
839
+ if (!hasSwRoutes) {
840
+ return null;
841
+ }
842
+ const path = resolveRequestPath(swConfig.path);
843
+ const scope = resolveRegisterScope(swConfig.scope);
844
+ return [
845
+ "(async () => {",
846
+ " if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {",
847
+ " return",
848
+ " }",
849
+ ` const path = ${JSON.stringify(path)}`,
850
+ ` const scope = ${JSON.stringify(scope)}`,
851
+ " try {",
852
+ " await navigator.serviceWorker.register(path, { type: 'module', scope })",
853
+ " }",
854
+ " catch (error) {",
855
+ " console.warn('Failed to register service worker:', error)",
856
+ " }",
857
+ "})()"
858
+ ].join("\n");
859
+ }
631
860
 
632
861
  function createMokupPlugin(options = {}) {
633
862
  let root = process.cwd();
634
863
  let base = "/";
635
864
  let command = "serve";
636
865
  let assetsDir = "assets";
866
+ let outDir = "dist";
867
+ let isSsrBuild = false;
637
868
  const state = {
638
869
  routes: [],
639
870
  serverRoutes: [],
@@ -852,6 +1083,8 @@ function createMokupPlugin(options = {}) {
852
1083
  base = config.base ?? "/";
853
1084
  command = config.command;
854
1085
  assetsDir = config.build.assetsDir ?? "assets";
1086
+ outDir = config.build.outDir ?? "dist";
1087
+ isSsrBuild = !!config.build.ssr;
855
1088
  },
856
1089
  async configureServer(server) {
857
1090
  currentServer = server;
@@ -891,9 +1124,35 @@ function createMokupPlugin(options = {}) {
891
1124
  previewWatcher = null;
892
1125
  });
893
1126
  },
894
- closeBundle() {
1127
+ async closeBundle() {
895
1128
  previewWatcher?.close();
896
1129
  previewWatcher = null;
1130
+ if (command !== "build" || isSsrBuild || !playgroundConfig.enabled || playgroundConfig.build !== true) {
1131
+ return;
1132
+ }
1133
+ await refreshRoutes();
1134
+ const swScript = buildSwLifecycleInlineScript({
1135
+ swConfig,
1136
+ unregisterConfig,
1137
+ hasSwEntries,
1138
+ hasSwRoutes: hasSwRoutes(),
1139
+ resolveRequestPath: resolveSwRequestPath,
1140
+ resolveRegisterScope: resolveSwRegisterScope
1141
+ });
1142
+ await writePlaygroundBuild({
1143
+ outDir,
1144
+ base,
1145
+ playgroundPath: playgroundConfig.path,
1146
+ root,
1147
+ routes: state.routes,
1148
+ disabledRoutes: state.disabledRoutes,
1149
+ ignoredRoutes: state.ignoredRoutes,
1150
+ configFiles: state.configFiles,
1151
+ disabledConfigFiles: state.disabledConfigFiles,
1152
+ dirs: resolveAllDirs(),
1153
+ swScript,
1154
+ logger: logger$1
1155
+ });
897
1156
  }
898
1157
  };
899
1158
  }
package/dist/vite.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import { cwd } from 'node:process';
2
- import { k as buildManifestData, r as resolveDirs, s as scanRoutes, a as sortRoutes, c as createHonoApp, i as isInDirs, d as createDebouncer, b as buildSwScript, j as createMiddleware, e as resolvePlaygroundOptions, f as resolveSwConfig, g as resolveSwUnregisterConfig, h as createPlaygroundMiddleware } from './shared/mokup.Bp9u3JKA.mjs';
2
+ import { k as buildManifestData, l as resolvePlaygroundDist, n as normalizePlaygroundPath, m as injectPlaygroundSw, o as resolveGroupRoot, p as resolveGroups, q as resolvePlaygroundRequestPath, u as toPlaygroundConfigFile, v as toPlaygroundIgnoredRoute, w as toPlaygroundDisabledRoute, x as toPlaygroundRoute, r as resolveDirs, s as scanRoutes, a as sortRoutes, c as createHonoApp, i as isInDirs, d as createDebouncer, b as buildSwScript, j as createMiddleware, e as resolvePlaygroundOptions, f as resolveSwConfig, g as resolveSwUnregisterConfig, h as createPlaygroundMiddleware } from './shared/mokup.ClsvLg8n.mjs';
3
+ import { promises, existsSync } from 'node:fs';
4
+ import { join, normalize } from '@mokup/shared/pathe';
3
5
  import { createLogger } from '@mokup/shared/logger';
4
6
  import pc from 'picocolors';
5
- import { isAbsolute, resolve } from 'node:path';
7
+ import { isAbsolute, resolve, dirname } from 'node:path';
6
8
  import chokidar from '@mokup/shared/chokidar';
7
- import { existsSync } from 'node:fs';
8
9
  import { fileURLToPath } from 'node:url';
9
- import '@mokup/shared/pathe';
10
10
  import 'node:module';
11
11
  import 'node:buffer';
12
12
  import '@mokup/shared/hono';
@@ -56,6 +56,79 @@ function buildBundleModule(params) {
56
56
  return lines.join("\n");
57
57
  }
58
58
 
59
+ function resolvePlaygroundOutDir(outDir, playgroundPath) {
60
+ const normalized = normalizePlaygroundPath(playgroundPath);
61
+ const trimmed = normalized.replace(/^\/+/, "");
62
+ return trimmed ? join(outDir, normalize(trimmed)) : outDir;
63
+ }
64
+ function stripSwLifecycle(html) {
65
+ return html.replace(
66
+ /<script[^>]*mokup-sw-lifecycle\.js[^>]*><\/script>\s*/gi,
67
+ ""
68
+ );
69
+ }
70
+ async function writeRoutesPayload(params, targetDir) {
71
+ const baseRoot = resolveGroupRoot(params.dirs, params.root);
72
+ const groups = resolveGroups(params.dirs, baseRoot);
73
+ const basePath = resolvePlaygroundRequestPath(params.base, params.playgroundPath);
74
+ const payload = {
75
+ basePath,
76
+ root: baseRoot,
77
+ count: params.routes.length,
78
+ groups: groups.map((group) => ({ key: group.key, label: group.label })),
79
+ routes: params.routes.map((route) => toPlaygroundRoute(route, baseRoot, groups)),
80
+ disabled: params.disabledRoutes.map(
81
+ (route) => toPlaygroundDisabledRoute(route, baseRoot, groups)
82
+ ),
83
+ ignored: params.ignoredRoutes.map(
84
+ (route) => toPlaygroundIgnoredRoute(route, baseRoot, groups)
85
+ ),
86
+ configs: params.configFiles.map((entry) => toPlaygroundConfigFile(entry, baseRoot, groups)),
87
+ disabledConfigs: params.disabledConfigFiles.map(
88
+ (entry) => toPlaygroundConfigFile(entry, baseRoot, groups)
89
+ )
90
+ };
91
+ await promises.writeFile(
92
+ join(targetDir, "routes"),
93
+ JSON.stringify(payload, null, 2),
94
+ "utf8"
95
+ );
96
+ }
97
+ async function updateIndexHtml(targetDir, swScript) {
98
+ const indexPath = join(targetDir, "index.html");
99
+ const html = await promises.readFile(indexPath, "utf8");
100
+ const cleaned = stripSwLifecycle(html);
101
+ const output = swScript ? injectPlaygroundSw(cleaned, swScript) : cleaned;
102
+ await promises.writeFile(indexPath, output, "utf8");
103
+ }
104
+ async function removeLegacySwAsset(targetDir) {
105
+ const legacyFiles = [
106
+ join(targetDir, "assets", "mokup-sw-lifecycle.js"),
107
+ join(targetDir, "assets", "mokup-sw-lifecycle.js.map")
108
+ ];
109
+ await Promise.all(legacyFiles.map((file) => promises.rm(file, { force: true })));
110
+ }
111
+ async function writePlaygroundBuild(params) {
112
+ const distDir = resolvePlaygroundDist();
113
+ const targetDir = resolvePlaygroundOutDir(params.outDir, params.playgroundPath);
114
+ if (targetDir === params.outDir) {
115
+ params.logger.error("Playground build path resolves to the Vite outDir. Aborting output.");
116
+ return;
117
+ }
118
+ try {
119
+ await promises.stat(distDir);
120
+ } catch (error) {
121
+ params.logger.error("Failed to locate playground assets:", error);
122
+ return;
123
+ }
124
+ await promises.rm(targetDir, { recursive: true, force: true });
125
+ await promises.mkdir(params.outDir, { recursive: true });
126
+ await promises.cp(distDir, targetDir, { recursive: true });
127
+ await removeLegacySwAsset(targetDir);
128
+ await updateIndexHtml(targetDir, params.swScript);
129
+ await writeRoutesPayload(params, targetDir);
130
+ }
131
+
59
132
  const legacyEntryKeys = [
60
133
  "dir",
61
134
  "prefix",
@@ -140,6 +213,10 @@ function resolveSwRuntimeImportPath(base) {
140
213
  const normalizedBase = normalizeBase(base);
141
214
  return `${normalizedBase}@id/mokup/runtime`;
142
215
  }
216
+ function resolveSwLoggerImportPath(base) {
217
+ const normalizedBase = normalizeBase(base);
218
+ return `${normalizedBase}@id/@mokup/shared/logger`;
219
+ }
143
220
 
144
221
  function buildRouteSignature(routes, disabledRoutes, ignoredRoutes, configFiles, disabledConfigFiles) {
145
222
  return routes.map(
@@ -308,6 +385,47 @@ function addMiddlewareFirst(server, middleware) {
308
385
  server.middlewares.use(middleware);
309
386
  }
310
387
 
388
+ const portPattern = /:(?<port>\d{2,5})/g;
389
+ const escapeCode = 27;
390
+ function stripAnsi(value) {
391
+ let output = "";
392
+ for (let index = 0; index < value.length; index += 1) {
393
+ const code = value.charCodeAt(index);
394
+ if (code === escapeCode && value[index + 1] === "[") {
395
+ index += 1;
396
+ while (index < value.length && value[index] !== "m") {
397
+ index += 1;
398
+ }
399
+ continue;
400
+ }
401
+ output += value[index];
402
+ }
403
+ return output;
404
+ }
405
+ function formatOutputLine(line, options) {
406
+ const { arrowToken, formattedArrow, labels, formatLabel, formatPort } = options;
407
+ let output = formattedArrow ? line.replaceAll(arrowToken, formattedArrow) : line;
408
+ if (labels && formatLabel) {
409
+ for (const label of labels) {
410
+ output = output.replaceAll(label, formatLabel(label));
411
+ }
412
+ }
413
+ if (formatPort) {
414
+ output = output.replace(portPattern, (_match, port) => `:${formatPort(port)}`);
415
+ }
416
+ return output;
417
+ }
418
+
419
+ const arrowToken = "\u279C";
420
+ const playgroundLabel = "Mokup Playground";
421
+ const coloredArrow = pc.green(arrowToken);
422
+ const formatOptions = {
423
+ arrowToken,
424
+ formattedArrow: coloredArrow,
425
+ labels: [playgroundLabel],
426
+ formatLabel: pc.bold,
427
+ formatPort: pc.bold
428
+ };
311
429
  function patchPlaygroundPrintUrls(server, playgroundPath) {
312
430
  const originalPrintUrls = server.printUrls.bind(server);
313
431
  const patchPrintUrls = () => {
@@ -332,18 +450,22 @@ function patchPlaygroundPrintUrls(server, playgroundPath) {
332
450
  const localUrl = server.resolvedUrls?.local?.[0];
333
451
  const outputUrl = formatPlaygroundUrl(localUrl, playgroundPath);
334
452
  const coloredUrl = pc.magenta(outputUrl);
335
- const playgroundLine = ` \u279C Mokup Playground: ${coloredUrl}`;
336
- const ansiEscape = "\x1B";
337
- const ansiPattern = new RegExp(`${ansiEscape}\\[[0-9;]*m`, "g");
338
- const stripAnsi = (value) => value.replace(ansiPattern, "");
453
+ const playgroundLine = ` ${arrowToken} ${playgroundLabel}: ${coloredUrl}`;
454
+ const arrowPrefix = ` ${arrowToken} `;
339
455
  const findIndex = (needle) => lines.findIndex((args) => stripAnsi(args[0]).includes(needle));
340
- const networkIndex = findIndex(" \u279C Network:");
341
- const localIndex = findIndex(" \u279C Local:");
456
+ const networkIndex = findIndex(`${arrowPrefix}Network:`);
457
+ const localIndex = findIndex(`${arrowPrefix}Local:`);
342
458
  const insertIndex = networkIndex >= 0 ? networkIndex + 1 : localIndex >= 0 ? localIndex + 1 : lines.length;
343
459
  const outputLines = lines.slice();
344
460
  outputLines.splice(insertIndex, 0, [playgroundLine]);
345
461
  for (const args of outputLines) {
346
- originalInfo(...args);
462
+ if (typeof args[0] === "string") {
463
+ const nextArgs = args.slice();
464
+ nextArgs[0] = formatOutputLine(nextArgs[0], formatOptions);
465
+ originalInfo(...nextArgs);
466
+ } else {
467
+ originalInfo(...args);
468
+ }
347
469
  }
348
470
  };
349
471
  Object.defineProperty(server, "printUrls", {
@@ -468,6 +590,7 @@ async function configureDevServer(params) {
468
590
  routes: state.swRoutes,
469
591
  root,
470
592
  runtimeImportPath: resolveSwRuntimeImportPath(base),
593
+ loggerImportPath: resolveSwLoggerImportPath(base),
471
594
  basePaths: swConfig?.basePaths ?? []
472
595
  });
473
596
  res.statusCode = 200;
@@ -556,17 +679,35 @@ async function configurePreviewServer(params) {
556
679
  }
557
680
 
558
681
  const swModuleCandidates = [
559
- new URL("../../sw.ts", import.meta.url),
560
- new URL("../../sw.js", import.meta.url)
682
+ "dist/sw.mjs",
683
+ "dist/sw.js",
684
+ "src/sw.ts",
685
+ "src/sw.js"
561
686
  ];
687
+ function resolvePackageRoot() {
688
+ const moduleDir = dirname(fileURLToPath(import.meta.url));
689
+ let current = moduleDir;
690
+ for (let index = 0; index < 6; index += 1) {
691
+ if (existsSync(resolve(current, "package.json"))) {
692
+ return current;
693
+ }
694
+ const parent = dirname(current);
695
+ if (parent === current) {
696
+ break;
697
+ }
698
+ current = parent;
699
+ }
700
+ return moduleDir;
701
+ }
562
702
  const localSwModulePath = (() => {
703
+ const packageRoot = resolvePackageRoot();
563
704
  for (const candidate of swModuleCandidates) {
564
- const filePath = fileURLToPath(candidate);
705
+ const filePath = resolve(packageRoot, candidate);
565
706
  if (existsSync(filePath)) {
566
707
  return filePath;
567
708
  }
568
709
  }
569
- return fileURLToPath(swModuleCandidates[0] ?? new URL("../../sw.ts", import.meta.url));
710
+ return resolve(packageRoot, "src/sw.ts");
570
711
  })();
571
712
  async function resolveSwModuleImport(context) {
572
713
  const resolved = await context.resolve("mokup/sw");
@@ -620,12 +761,102 @@ function buildSwLifecycleScript(params) {
620
761
  "})()"
621
762
  ].join("\n");
622
763
  }
764
+ function buildSwLifecycleInlineScript(params) {
765
+ const {
766
+ swConfig,
767
+ unregisterConfig,
768
+ hasSwEntries,
769
+ hasSwRoutes,
770
+ resolveRequestPath,
771
+ resolveRegisterScope
772
+ } = params;
773
+ const shouldUnregister = unregisterConfig.unregister === true || !hasSwEntries;
774
+ if (shouldUnregister) {
775
+ const path2 = resolveRequestPath(unregisterConfig.path);
776
+ const scope2 = resolveRegisterScope(unregisterConfig.scope);
777
+ return [
778
+ "(async () => {",
779
+ " if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {",
780
+ " return",
781
+ " }",
782
+ ` const path = ${JSON.stringify(path2)}`,
783
+ ` const scope = ${JSON.stringify(scope2)}`,
784
+ " const origin = window.location.origin",
785
+ " const normalizeScope = (value) => {",
786
+ " const url = new URL(value, origin)",
787
+ " if (!url.pathname.endsWith('/')) {",
788
+ " url.pathname = url.pathname + '/'",
789
+ " }",
790
+ " return url.href",
791
+ " }",
792
+ " const pathUrl = new URL(path, origin)",
793
+ " const scopeUrl = normalizeScope(scope)",
794
+ " const matchesScript = (scriptUrl) => {",
795
+ " if (!scriptUrl) {",
796
+ " return false",
797
+ " }",
798
+ " try {",
799
+ " const parsed = new URL(scriptUrl)",
800
+ " return parsed.origin === origin && parsed.pathname === pathUrl.pathname",
801
+ " }",
802
+ " catch {",
803
+ " return false",
804
+ " }",
805
+ " }",
806
+ " try {",
807
+ " const registrations = await navigator.serviceWorker.getRegistrations()",
808
+ " for (const registration of registrations) {",
809
+ " if (registration.scope !== scopeUrl) {",
810
+ " continue",
811
+ " }",
812
+ " const scriptUrls = [",
813
+ " registration.active?.scriptURL,",
814
+ " registration.waiting?.scriptURL,",
815
+ " registration.installing?.scriptURL,",
816
+ " ]",
817
+ " if (scriptUrls.some(matchesScript)) {",
818
+ " await registration.unregister()",
819
+ " }",
820
+ " }",
821
+ " }",
822
+ " catch (error) {",
823
+ " console.warn('Failed to unregister service worker:', error)",
824
+ " }",
825
+ "})()"
826
+ ].join("\n");
827
+ }
828
+ if (!swConfig || swConfig.register === false) {
829
+ return null;
830
+ }
831
+ if (!hasSwRoutes) {
832
+ return null;
833
+ }
834
+ const path = resolveRequestPath(swConfig.path);
835
+ const scope = resolveRegisterScope(swConfig.scope);
836
+ return [
837
+ "(async () => {",
838
+ " if (typeof window === 'undefined' || !('serviceWorker' in navigator)) {",
839
+ " return",
840
+ " }",
841
+ ` const path = ${JSON.stringify(path)}`,
842
+ ` const scope = ${JSON.stringify(scope)}`,
843
+ " try {",
844
+ " await navigator.serviceWorker.register(path, { type: 'module', scope })",
845
+ " }",
846
+ " catch (error) {",
847
+ " console.warn('Failed to register service worker:', error)",
848
+ " }",
849
+ "})()"
850
+ ].join("\n");
851
+ }
623
852
 
624
853
  function createMokupPlugin(options = {}) {
625
854
  let root = cwd();
626
855
  let base = "/";
627
856
  let command = "serve";
628
857
  let assetsDir = "assets";
858
+ let outDir = "dist";
859
+ let isSsrBuild = false;
629
860
  const state = {
630
861
  routes: [],
631
862
  serverRoutes: [],
@@ -844,6 +1075,8 @@ function createMokupPlugin(options = {}) {
844
1075
  base = config.base ?? "/";
845
1076
  command = config.command;
846
1077
  assetsDir = config.build.assetsDir ?? "assets";
1078
+ outDir = config.build.outDir ?? "dist";
1079
+ isSsrBuild = !!config.build.ssr;
847
1080
  },
848
1081
  async configureServer(server) {
849
1082
  currentServer = server;
@@ -883,9 +1116,35 @@ function createMokupPlugin(options = {}) {
883
1116
  previewWatcher = null;
884
1117
  });
885
1118
  },
886
- closeBundle() {
1119
+ async closeBundle() {
887
1120
  previewWatcher?.close();
888
1121
  previewWatcher = null;
1122
+ if (command !== "build" || isSsrBuild || !playgroundConfig.enabled || playgroundConfig.build !== true) {
1123
+ return;
1124
+ }
1125
+ await refreshRoutes();
1126
+ const swScript = buildSwLifecycleInlineScript({
1127
+ swConfig,
1128
+ unregisterConfig,
1129
+ hasSwEntries,
1130
+ hasSwRoutes: hasSwRoutes(),
1131
+ resolveRequestPath: resolveSwRequestPath,
1132
+ resolveRegisterScope: resolveSwRegisterScope
1133
+ });
1134
+ await writePlaygroundBuild({
1135
+ outDir,
1136
+ base,
1137
+ playgroundPath: playgroundConfig.path,
1138
+ root,
1139
+ routes: state.routes,
1140
+ disabledRoutes: state.disabledRoutes,
1141
+ ignoredRoutes: state.ignoredRoutes,
1142
+ configFiles: state.configFiles,
1143
+ disabledConfigFiles: state.disabledConfigFiles,
1144
+ dirs: resolveAllDirs(),
1145
+ swScript,
1146
+ logger
1147
+ });
889
1148
  }
890
1149
  };
891
1150
  }
package/dist/webpack.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  const process = require('node:process');
4
- const scanner = require('./shared/mokup.i875Kuim.cjs');
4
+ const scanner = require('./shared/mokup.CYGG6ENd.cjs');
5
+ require('node:fs');
6
+ const pathe = require('@mokup/shared/pathe');
5
7
  const logger = require('@mokup/shared/logger');
6
8
  const esbuild = require('@mokup/shared/esbuild');
7
9
  const node_module = require('node:module');
8
- const pathe = require('@mokup/shared/pathe');
9
10
  const chokidar = require('@mokup/shared/chokidar');
10
- require('node:fs');
11
11
  require('node:buffer');
12
12
  require('@mokup/shared/hono');
13
13
  require('node:url');
package/dist/webpack.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { cwd } from 'node:process';
2
- import { b as buildSwScript, t as toPosix, r as resolveDirs, s as scanRoutes, a as sortRoutes, c as createHonoApp, i as isInDirs, d as createDebouncer, e as resolvePlaygroundOptions, f as resolveSwConfig, g as resolveSwUnregisterConfig, h as createPlaygroundMiddleware, j as createMiddleware } from './shared/mokup.Bp9u3JKA.mjs';
2
+ import { b as buildSwScript, t as toPosix, r as resolveDirs, s as scanRoutes, a as sortRoutes, c as createHonoApp, i as isInDirs, d as createDebouncer, e as resolvePlaygroundOptions, f as resolveSwConfig, g as resolveSwUnregisterConfig, h as createPlaygroundMiddleware, j as createMiddleware } from './shared/mokup.ClsvLg8n.mjs';
3
+ import 'node:fs';
4
+ import { isAbsolute, resolve } from '@mokup/shared/pathe';
3
5
  import { createLogger } from '@mokup/shared/logger';
4
6
  import { build } from '@mokup/shared/esbuild';
5
7
  import { createRequire } from 'node:module';
6
- import { isAbsolute, resolve } from '@mokup/shared/pathe';
7
8
  import chokidar from '@mokup/shared/chokidar';
8
- import 'node:fs';
9
9
  import 'node:buffer';
10
10
  import '@mokup/shared/hono';
11
11
  import 'node:url';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mokup",
3
3
  "type": "module",
4
- "version": "2.1.0",
4
+ "version": "2.2.0",
5
5
  "description": "Mock utilities and Vite plugin for mokup.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://mokup.icebreaker.top",
@@ -92,11 +92,11 @@
92
92
  },
93
93
  "dependencies": {
94
94
  "picocolors": "^1.1.1",
95
- "@mokup/cli": "1.0.6",
96
- "@mokup/playground": "0.0.11",
97
- "@mokup/runtime": "1.0.3",
98
- "@mokup/server": "1.1.3",
99
- "@mokup/shared": "1.0.2"
95
+ "@mokup/cli": "1.0.8",
96
+ "@mokup/playground": "0.0.13",
97
+ "@mokup/runtime": "1.0.4",
98
+ "@mokup/server": "1.1.5",
99
+ "@mokup/shared": "1.1.0"
100
100
  },
101
101
  "devDependencies": {
102
102
  "@types/node": "^25.0.10",