mokup 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/webpack.cjs CHANGED
@@ -1,16 +1,15 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- const node_module = require('node:module');
6
3
  const process = require('node:process');
7
- const chokidar = require('@mokup/shared/chokidar');
4
+ const scanner = require('./shared/mokup.i875Kuim.cjs');
5
+ const logger = require('@mokup/shared/logger');
8
6
  const esbuild = require('@mokup/shared/esbuild');
7
+ const node_module = require('node:module');
9
8
  const pathe = require('@mokup/shared/pathe');
10
- const sw = require('./shared/mokup.B-yfMz5B.cjs');
9
+ const chokidar = require('@mokup/shared/chokidar');
10
+ require('node:fs');
11
11
  require('node:buffer');
12
12
  require('@mokup/shared/hono');
13
- require('node:fs');
14
13
  require('node:url');
15
14
  require('@mokup/shared/jsonc-parser');
16
15
  require('@mokup/runtime');
@@ -20,8 +19,141 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
20
19
 
21
20
  const chokidar__default = /*#__PURE__*/_interopDefaultCompat(chokidar);
22
21
 
23
- const pluginName = "mokup:webpack";
24
- const lifecycleBaseName = "mokup-sw-lifecycle.js";
22
+ async function bundleScript(params) {
23
+ const result = await esbuild.build({
24
+ stdin: {
25
+ contents: params.code,
26
+ resolveDir: params.root,
27
+ sourcefile: params.sourceName,
28
+ loader: "js"
29
+ },
30
+ absWorkingDir: params.root,
31
+ bundle: true,
32
+ platform: "browser",
33
+ format: "esm",
34
+ target: "es2020",
35
+ write: false
36
+ });
37
+ return result.outputFiles[0]?.text ?? "";
38
+ }
39
+
40
+ function buildSwLifecycleScript(params) {
41
+ const {
42
+ importPath,
43
+ swConfig,
44
+ unregisterConfig,
45
+ hasSwEntries,
46
+ hasSwRoutes,
47
+ resolveRequestPath,
48
+ resolveRegisterScope
49
+ } = params;
50
+ const shouldUnregister = unregisterConfig.unregister === true || !hasSwEntries;
51
+ if (shouldUnregister) {
52
+ const path2 = resolveRequestPath(unregisterConfig.path);
53
+ const scope2 = resolveRegisterScope(unregisterConfig.scope);
54
+ return [
55
+ `import { unregisterMokupServiceWorker } from ${JSON.stringify(importPath)}`,
56
+ "(async () => {",
57
+ ` await unregisterMokupServiceWorker({ path: ${JSON.stringify(path2)}, scope: ${JSON.stringify(scope2)} })`,
58
+ "})()"
59
+ ].join("\n");
60
+ }
61
+ if (!swConfig || swConfig.register === false) {
62
+ return null;
63
+ }
64
+ if (!hasSwRoutes) {
65
+ return null;
66
+ }
67
+ const path = resolveRequestPath(swConfig.path);
68
+ const scope = resolveRegisterScope(swConfig.scope);
69
+ return [
70
+ `import { registerMokupServiceWorker } from ${JSON.stringify(importPath)}`,
71
+ "(async () => {",
72
+ ` const registration = await registerMokupServiceWorker({ path: ${JSON.stringify(path)}, scope: ${JSON.stringify(scope)} })`,
73
+ " if (import.meta.hot && registration) {",
74
+ " import.meta.hot.on('mokup:routes-changed', () => {",
75
+ " registration.update()",
76
+ " })",
77
+ " }",
78
+ "})()"
79
+ ].join("\n");
80
+ }
81
+
82
+ function createBundleBuilder(params) {
83
+ const {
84
+ bundleState,
85
+ state,
86
+ root,
87
+ swConfig,
88
+ unregisterConfig,
89
+ hasSwEntries,
90
+ hasSwRoutes,
91
+ resolveRequestPath,
92
+ resolveRegisterScope,
93
+ resolveModulePath,
94
+ refreshRoutes,
95
+ logger
96
+ } = params;
97
+ let buildPromise = null;
98
+ const rebuildBundles = async () => {
99
+ const lifecycle = buildSwLifecycleScript({
100
+ importPath: "mokup/sw",
101
+ swConfig,
102
+ unregisterConfig,
103
+ hasSwEntries,
104
+ hasSwRoutes: hasSwRoutes(),
105
+ resolveRequestPath,
106
+ resolveRegisterScope
107
+ });
108
+ bundleState.swLifecycleBundle = lifecycle ? await bundleScript({
109
+ code: lifecycle,
110
+ root: root(),
111
+ sourceName: "mokup-sw-lifecycle.js"
112
+ }) : null;
113
+ if (swConfig && hasSwRoutes()) {
114
+ const swScript = scanner.buildSwScript({
115
+ routes: state.swRoutes,
116
+ root: root(),
117
+ runtimeImportPath: "mokup/runtime",
118
+ basePaths: swConfig.basePaths ?? [],
119
+ resolveModulePath
120
+ });
121
+ bundleState.swBundle = await bundleScript({
122
+ code: swScript,
123
+ root: root(),
124
+ sourceName: "mokup-sw.js"
125
+ });
126
+ } else {
127
+ bundleState.swBundle = null;
128
+ }
129
+ };
130
+ const ensureBuilt = async () => {
131
+ if (!buildPromise) {
132
+ buildPromise = (async () => {
133
+ await refreshRoutes();
134
+ await rebuildBundles();
135
+ })().catch((error) => {
136
+ logger.error("Failed to build mokup bundles:", error);
137
+ }).finally(() => {
138
+ buildPromise = null;
139
+ });
140
+ }
141
+ await buildPromise;
142
+ };
143
+ return { rebuildBundles, ensureBuilt };
144
+ }
145
+
146
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('webpack.cjs', document.baseURI).href)));
147
+ function resolveHtmlWebpackPlugin() {
148
+ try {
149
+ const mod = require$1("html-webpack-plugin");
150
+ const plugin = mod.default ?? mod;
151
+ return plugin;
152
+ } catch {
153
+ return null;
154
+ }
155
+ }
156
+
25
157
  const legacyEntryKeys = [
26
158
  "dir",
27
159
  "prefix",
@@ -58,6 +190,7 @@ function normalizeOptions(options) {
58
190
  const list = Array.isArray(entries) ? entries : entries ? [entries] : [{}];
59
191
  return list.length > 0 ? list : [{}];
60
192
  }
193
+
61
194
  function normalizeBase(base) {
62
195
  if (!base) {
63
196
  return "/";
@@ -120,118 +253,18 @@ function joinPublicPath(publicPath, fileName) {
120
253
  const normalized = publicPath.endsWith("/") ? publicPath : `${publicPath}/`;
121
254
  return `${normalized}${fileName}`;
122
255
  }
123
- function buildSwLifecycleScript(params) {
124
- const { base, importPath, swConfig, unregisterConfig, hasSwEntries, hasSwRoutes } = params;
125
- const shouldUnregister = unregisterConfig.unregister === true || !hasSwEntries;
126
- if (shouldUnregister) {
127
- const path2 = resolveRegisterPath(base, unregisterConfig.path);
128
- const scope2 = resolveRegisterScope(base, unregisterConfig.scope);
129
- return [
130
- `import { unregisterMokupServiceWorker } from ${JSON.stringify(importPath)}`,
131
- "(async () => {",
132
- ` await unregisterMokupServiceWorker({ path: ${JSON.stringify(path2)}, scope: ${JSON.stringify(scope2)} })`,
133
- "})()"
134
- ].join("\n");
135
- }
136
- if (!swConfig || swConfig.register === false) {
137
- return null;
138
- }
139
- if (!hasSwRoutes) {
140
- return null;
141
- }
142
- const path = resolveRegisterPath(base, swConfig.path);
143
- const scope = resolveRegisterScope(base, swConfig.scope);
144
- return [
145
- `import { registerMokupServiceWorker } from ${JSON.stringify(importPath)}`,
146
- "(async () => {",
147
- ` const registration = await registerMokupServiceWorker({ path: ${JSON.stringify(path)}, scope: ${JSON.stringify(scope)} })`,
148
- " if (import.meta.hot && registration) {",
149
- " import.meta.hot.on('mokup:routes-changed', () => {",
150
- " registration.update()",
151
- " })",
152
- " }",
153
- "})()"
154
- ].join("\n");
155
- }
156
256
  function resolveModuleFilePath(file, root) {
157
257
  const absolute = pathe.isAbsolute(file) ? file : pathe.resolve(root, file);
158
- const normalized = sw.toPosix(absolute);
258
+ const normalized = scanner.toPosix(absolute);
159
259
  if (/^[a-z]:\//i.test(normalized)) {
160
260
  return `file:///${normalized}`;
161
261
  }
162
262
  return normalized;
163
263
  }
164
- async function bundleScript(params) {
165
- const result = await esbuild.build({
166
- stdin: {
167
- contents: params.code,
168
- resolveDir: params.root,
169
- sourcefile: params.sourceName,
170
- loader: "js"
171
- },
172
- absWorkingDir: params.root,
173
- bundle: true,
174
- platform: "browser",
175
- format: "esm",
176
- target: "es2020",
177
- write: false
178
- });
179
- return result.outputFiles[0]?.text ?? "";
180
- }
181
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('webpack.cjs', document.baseURI).href)));
182
- function resolveHtmlWebpackPlugin() {
183
- try {
184
- const mod = require$1("html-webpack-plugin");
185
- const plugin = mod.default ?? mod;
186
- return plugin;
187
- } catch {
188
- return null;
189
- }
190
- }
191
- function createMokupWebpackPlugin(options = {}) {
192
- const normalizedOptions = normalizeMokupOptions(options);
193
- const optionList = normalizeOptions(normalizedOptions);
194
- const logEnabled = optionList.every((entry) => entry.log !== false);
195
- const watchEnabled = optionList.every((entry) => entry.watch !== false);
196
- const playgroundConfig = sw.resolvePlaygroundOptions(normalizedOptions.playground);
197
- const logger = sw.createLogger(logEnabled);
198
- const hasSwEntries = optionList.some((entry) => entry.mode === "sw");
199
- const swConfig = sw.resolveSwConfig(optionList, logger);
200
- const unregisterConfig = sw.resolveSwUnregisterConfig(optionList, logger);
201
- let root = process.cwd();
202
- let base = "/";
203
- let assetsDir = "assets";
204
- let routes = [];
205
- let serverRoutes = [];
206
- let swRoutes = [];
207
- let disabledRoutes = [];
208
- let ignoredRoutes = [];
209
- let configFiles = [];
210
- let disabledConfigFiles = [];
211
- let app = null;
212
- let watcher = null;
213
- let watchingCompiler = null;
214
- let swLifecycleBundle = null;
215
- let swBundle = null;
216
- let swLifecycleFileName = `${assetsDir}/${lifecycleBaseName}`;
217
- let warnedHtml = false;
218
- let buildPromise = null;
219
- const resolveAllDirs = () => {
220
- const dirs = [];
221
- const seen = /* @__PURE__ */ new Set();
222
- for (const entry of optionList) {
223
- for (const dir of sw.resolveDirs(entry.dir, root)) {
224
- if (seen.has(dir)) {
225
- continue;
226
- }
227
- seen.add(dir);
228
- dirs.push(dir);
229
- }
230
- }
231
- return dirs;
232
- };
233
- const hasSwRoutes = () => !!swConfig && swRoutes.length > 0;
234
- const refreshRoutes = async () => {
264
+
265
+ function createRouteRefresher(params) {
266
+ const { state, optionList, root, logger } = params;
267
+ return async () => {
235
268
  const collected = [];
236
269
  const collectedServer = [];
237
270
  const collectedSw = [];
@@ -239,9 +272,8 @@ function createMokupWebpackPlugin(options = {}) {
239
272
  const collectedIgnored = [];
240
273
  const collectedConfigs = [];
241
274
  for (const entry of optionList) {
242
- const dirs = sw.resolveDirs(entry.dir, root);
243
275
  const scanParams = {
244
- dirs,
276
+ dirs: scanner.resolveDirs(entry.dir, root()),
245
277
  prefix: entry.prefix ?? "",
246
278
  logger,
247
279
  onSkip: (info) => collectedDisabled.push(info),
@@ -257,7 +289,7 @@ function createMokupWebpackPlugin(options = {}) {
257
289
  if (typeof entry.ignorePrefix !== "undefined") {
258
290
  scanParams.ignorePrefix = entry.ignorePrefix;
259
291
  }
260
- const scanned = await sw.scanRoutes(scanParams);
292
+ const scanned = await scanner.scanRoutes(scanParams);
261
293
  collected.push(...scanned);
262
294
  if (entry.mode === "sw") {
263
295
  collectedSw.push(...scanned);
@@ -268,69 +300,121 @@ function createMokupWebpackPlugin(options = {}) {
268
300
  collectedServer.push(...scanned);
269
301
  }
270
302
  }
271
- routes = sw.sortRoutes(collected);
272
- serverRoutes = sw.sortRoutes(collectedServer);
273
- swRoutes = sw.sortRoutes(collectedSw);
274
- disabledRoutes = collectedDisabled;
275
- ignoredRoutes = collectedIgnored;
303
+ state.routes = scanner.sortRoutes(collected);
304
+ state.serverRoutes = scanner.sortRoutes(collectedServer);
305
+ state.swRoutes = scanner.sortRoutes(collectedSw);
306
+ state.disabledRoutes = collectedDisabled;
307
+ state.ignoredRoutes = collectedIgnored;
276
308
  const configMap = new Map(collectedConfigs.map((entry) => [entry.file, entry]));
277
309
  const resolvedConfigs = Array.from(configMap.values());
278
- configFiles = resolvedConfigs.filter((entry) => entry.enabled);
279
- disabledConfigFiles = resolvedConfigs.filter((entry) => !entry.enabled);
280
- app = serverRoutes.length > 0 ? sw.createHonoApp(serverRoutes) : null;
310
+ state.configFiles = resolvedConfigs.filter((entry) => entry.enabled);
311
+ state.disabledConfigFiles = resolvedConfigs.filter((entry) => !entry.enabled);
312
+ state.app = state.serverRoutes.length > 0 ? scanner.createHonoApp(state.serverRoutes) : null;
281
313
  };
282
- const rebuildBundles = async () => {
283
- const lifecycle = buildSwLifecycleScript({
284
- base,
285
- importPath: "mokup/sw",
286
- swConfig,
287
- unregisterConfig,
288
- hasSwEntries,
289
- hasSwRoutes: hasSwRoutes()
290
- });
291
- swLifecycleBundle = lifecycle ? await bundleScript({
292
- code: lifecycle,
293
- root,
294
- sourceName: lifecycleBaseName
295
- }) : null;
296
- if (swConfig && hasSwRoutes()) {
297
- const swScript = sw.buildSwScript({
298
- routes: swRoutes,
299
- root,
300
- runtimeImportPath: "mokup/runtime",
301
- basePaths: swConfig.basePaths ?? [],
302
- resolveModulePath: resolveModuleFilePath
303
- });
304
- swBundle = await bundleScript({
305
- code: swScript,
306
- root,
307
- sourceName: "mokup-sw.js"
308
- });
309
- } else {
310
- swBundle = null;
314
+ }
315
+
316
+ function createWebpackWatcher(params) {
317
+ if (!params.enabled || params.dirs.length === 0) {
318
+ return null;
319
+ }
320
+ const watcher = chokidar__default.watch(params.dirs, { ignoreInitial: true });
321
+ const scheduleRefresh = scanner.createDebouncer(80, () => {
322
+ void params.onRefresh();
323
+ });
324
+ watcher.on("add", (file) => {
325
+ if (scanner.isInDirs(file, params.dirs)) {
326
+ scheduleRefresh();
327
+ }
328
+ });
329
+ watcher.on("change", (file) => {
330
+ if (scanner.isInDirs(file, params.dirs)) {
331
+ scheduleRefresh();
311
332
  }
333
+ });
334
+ watcher.on("unlink", (file) => {
335
+ if (scanner.isInDirs(file, params.dirs)) {
336
+ scheduleRefresh();
337
+ }
338
+ });
339
+ return watcher;
340
+ }
341
+
342
+ const pluginName = "mokup:webpack";
343
+ const lifecycleBaseName = "mokup-sw-lifecycle.js";
344
+ function createMokupWebpackPlugin(options = {}) {
345
+ const normalizedOptions = normalizeMokupOptions(options);
346
+ const optionList = normalizeOptions(normalizedOptions);
347
+ const logEnabled = optionList.every((entry) => entry.log !== false);
348
+ const watchEnabled = optionList.every((entry) => entry.watch !== false);
349
+ const playgroundConfig = scanner.resolvePlaygroundOptions(normalizedOptions.playground);
350
+ const logger$1 = logger.createLogger(logEnabled);
351
+ const hasSwEntries = optionList.some((entry) => entry.mode === "sw");
352
+ const swConfig = scanner.resolveSwConfig(optionList, logger$1);
353
+ const unregisterConfig = scanner.resolveSwUnregisterConfig(optionList, logger$1);
354
+ let root = process.cwd();
355
+ let base = "/";
356
+ let assetsDir = "assets";
357
+ const state = {
358
+ routes: [],
359
+ serverRoutes: [],
360
+ swRoutes: [],
361
+ disabledRoutes: [],
362
+ ignoredRoutes: [],
363
+ configFiles: [],
364
+ disabledConfigFiles: [],
365
+ app: null
312
366
  };
313
- const ensureBuilt = async () => {
314
- if (!buildPromise) {
315
- buildPromise = (async () => {
316
- await refreshRoutes();
317
- await rebuildBundles();
318
- })().catch((error) => {
319
- logger.error("Failed to build mokup bundles:", error);
320
- }).finally(() => {
321
- buildPromise = null;
322
- });
367
+ let watcher = null;
368
+ let watchingCompiler = null;
369
+ const bundleState = {
370
+ swLifecycleBundle: null,
371
+ swBundle: null
372
+ };
373
+ let swLifecycleFileName = `${assetsDir}/${lifecycleBaseName}`;
374
+ let warnedHtml = false;
375
+ const resolveAllDirs = () => {
376
+ const dirs = [];
377
+ const seen = /* @__PURE__ */ new Set();
378
+ for (const entry of optionList) {
379
+ for (const dir of scanner.resolveDirs(entry.dir, root)) {
380
+ if (seen.has(dir)) {
381
+ continue;
382
+ }
383
+ seen.add(dir);
384
+ dirs.push(dir);
385
+ }
323
386
  }
324
- await buildPromise;
387
+ return dirs;
325
388
  };
326
- const playgroundMiddleware = sw.createPlaygroundMiddleware({
327
- getRoutes: () => routes,
328
- getDisabledRoutes: () => disabledRoutes,
329
- getIgnoredRoutes: () => ignoredRoutes,
330
- getConfigFiles: () => configFiles,
331
- getDisabledConfigFiles: () => disabledConfigFiles,
389
+ const hasSwRoutes = () => !!swConfig && state.swRoutes.length > 0;
390
+ const refreshRoutes = createRouteRefresher({
391
+ state,
392
+ optionList,
393
+ root: () => root,
394
+ logger: logger$1
395
+ });
396
+ const { rebuildBundles, ensureBuilt } = createBundleBuilder({
397
+ bundleState,
398
+ state,
399
+ root: () => root,
400
+ swConfig,
401
+ unregisterConfig,
402
+ hasSwEntries,
403
+ hasSwRoutes,
404
+ resolveRequestPath: (path) => resolveRegisterPath(base, path),
405
+ resolveRegisterScope: (scope) => resolveRegisterScope(base, scope),
406
+ resolveModulePath: resolveModuleFilePath,
407
+ refreshRoutes,
408
+ logger: logger$1
409
+ });
410
+ const playgroundMiddleware = scanner.createPlaygroundMiddleware({
411
+ getRoutes: () => state.routes,
412
+ getDisabledRoutes: () => state.disabledRoutes,
413
+ getIgnoredRoutes: () => state.ignoredRoutes,
414
+ getConfigFiles: () => state.configFiles,
415
+ getDisabledConfigFiles: () => state.disabledConfigFiles,
332
416
  config: playgroundConfig,
333
- logger,
417
+ logger: logger$1,
334
418
  getDirs: () => resolveAllDirs(),
335
419
  getServer: () => ({ config: { base, root } })
336
420
  });
@@ -345,7 +429,7 @@ function createMokupWebpackPlugin(options = {}) {
345
429
  return next();
346
430
  }
347
431
  await ensureBuilt();
348
- if (!swBundle) {
432
+ if (!bundleState.swBundle) {
349
433
  res.statusCode = 500;
350
434
  res.setHeader("Content-Type", "text/plain; charset=utf-8");
351
435
  res.end("Failed to generate mokup service worker.");
@@ -354,9 +438,9 @@ function createMokupWebpackPlugin(options = {}) {
354
438
  res.statusCode = 200;
355
439
  res.setHeader("Content-Type", "application/javascript; charset=utf-8");
356
440
  res.setHeader("Cache-Control", "no-cache");
357
- res.end(swBundle);
441
+ res.end(bundleState.swBundle);
358
442
  };
359
- const mockMiddleware = sw.createMiddleware(() => app, logger);
443
+ const mockMiddleware = scanner.createMiddleware(() => state.app, logger$1);
360
444
  return {
361
445
  apply(compiler) {
362
446
  root = compiler.context ?? process.cwd();
@@ -376,7 +460,7 @@ function createMokupWebpackPlugin(options = {}) {
376
460
  if (HtmlWebpackPlugin) {
377
461
  const hooks = HtmlWebpackPlugin.getHooks(compilation);
378
462
  const injectTag = () => {
379
- if (!swLifecycleBundle) {
463
+ if (!bundleState.swLifecycleBundle) {
380
464
  return;
381
465
  }
382
466
  const tagBase = {
@@ -416,25 +500,25 @@ function createMokupWebpackPlugin(options = {}) {
416
500
  injectTag();
417
501
  } else if (!warnedHtml) {
418
502
  warnedHtml = true;
419
- logger.warn("html-webpack-plugin not found; skip SW lifecycle injection.");
503
+ logger$1.warn("html-webpack-plugin not found; skip SW lifecycle injection.");
420
504
  }
421
505
  compilation.hooks.processAssets.tapPromise(
422
506
  { name: pluginName, stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS },
423
507
  async () => {
424
508
  await ensureBuilt();
425
- if (swLifecycleBundle) {
509
+ if (bundleState.swLifecycleBundle) {
426
510
  const RawSource = compiler.webpack.sources.RawSource;
427
- const source = new RawSource(swLifecycleBundle);
511
+ const source = new RawSource(bundleState.swLifecycleBundle);
428
512
  if (compilation.getAsset(swLifecycleFileName)) {
429
513
  compilation.updateAsset(swLifecycleFileName, source);
430
514
  } else {
431
515
  compilation.emitAsset(swLifecycleFileName, source);
432
516
  }
433
517
  }
434
- if (swBundle && swConfig) {
518
+ if (bundleState.swBundle && swConfig) {
435
519
  const fileName = swConfig.path.startsWith("/") ? swConfig.path.slice(1) : swConfig.path;
436
520
  const RawSource = compiler.webpack.sources.RawSource;
437
- const source = new RawSource(swBundle);
521
+ const source = new RawSource(bundleState.swBundle);
438
522
  if (compilation.getAsset(fileName)) {
439
523
  compilation.updateAsset(fileName, source);
440
524
  } else {
@@ -459,30 +543,19 @@ function createMokupWebpackPlugin(options = {}) {
459
543
  );
460
544
  if (!watcher && watchEnabled) {
461
545
  const dirs = resolveAllDirs();
462
- const fsWatcher = chokidar__default.watch(dirs, { ignoreInitial: true });
463
- watcher = fsWatcher;
464
- const scheduleRefresh = sw.createDebouncer(80, () => {
465
- void refreshRoutes().then(rebuildBundles).then(() => {
466
- if (watchingCompiler?.watching) {
467
- watchingCompiler.watching.invalidate();
546
+ watcher = createWebpackWatcher({
547
+ enabled: watchEnabled,
548
+ dirs,
549
+ onRefresh: async () => {
550
+ try {
551
+ await refreshRoutes();
552
+ await rebuildBundles();
553
+ if (watchingCompiler?.watching) {
554
+ watchingCompiler.watching.invalidate();
555
+ }
556
+ } catch (error) {
557
+ logger$1.error("Failed to refresh mokup routes:", error);
468
558
  }
469
- }).catch((error) => {
470
- logger.error("Failed to refresh mokup routes:", error);
471
- });
472
- });
473
- fsWatcher.on("add", (file) => {
474
- if (sw.isInDirs(file, dirs)) {
475
- scheduleRefresh();
476
- }
477
- });
478
- fsWatcher.on("change", (file) => {
479
- if (sw.isInDirs(file, dirs)) {
480
- scheduleRefresh();
481
- }
482
- });
483
- fsWatcher.on("unlink", (file) => {
484
- if (sw.isInDirs(file, dirs)) {
485
- scheduleRefresh();
486
559
  }
487
560
  });
488
561
  }
@@ -498,4 +571,3 @@ function createMokupWebpackPlugin(options = {}) {
498
571
  }
499
572
 
500
573
  exports.createMokupWebpackPlugin = createMokupWebpackPlugin;
501
- exports.default = createMokupWebpackPlugin;
@@ -1,5 +1,5 @@
1
- import { MokupPluginOptions } from './index.cjs';
2
- export { HttpMethod, RequestHandler, RouteDirectoryConfig, RouteResponse, RouteRule, RuntimeMode, ServiceWorkerOptions, VitePluginOptions, VitePluginOptionsInput } from './index.cjs';
1
+ import { M as MokupPluginOptions } from './shared/mokup.CWQ8woZc.cjs';
2
+ export { H as HttpMethod, a as MiddlewarePosition, b as MiddlewareRegistry, R as RequestHandler, c as RouteDirectoryConfig, d as RouteResponse, e as RouteRule, f as RuntimeMode, S as ServiceWorkerOptions, V as VitePluginOptions, g as VitePluginOptionsInput } from './shared/mokup.CWQ8woZc.cjs';
3
3
  import { IncomingMessage, ServerResponse } from 'node:http';
4
4
  export { Context, MiddlewareHandler } from '@mokup/shared/hono';
5
5
  export { PlaygroundOptionsInput } from '@mokup/shared';
@@ -82,8 +82,40 @@ interface WebpackCompiler {
82
82
  };
83
83
  };
84
84
  }
85
+
86
+ /**
87
+ * Create the mokup webpack plugin for webpack-dev-server.
88
+ *
89
+ * @param options - Plugin options.
90
+ * @returns Webpack plugin instance.
91
+ *
92
+ * @example
93
+ * import { createMokupWebpackPlugin } from 'mokup/webpack'
94
+ *
95
+ * export default {
96
+ * plugins: [createMokupWebpackPlugin({ entries: { dir: 'mock' } })],
97
+ * }
98
+ */
85
99
  declare function createMokupWebpackPlugin(options?: MokupPluginOptions): WebpackPluginInstance;
86
100
 
87
- // @ts-ignore
88
- export = createMokupWebpackPlugin;
101
+ /**
102
+ * Webpack plugin options (alias of MokupPluginOptions).
103
+ *
104
+ * @example
105
+ * import type { WebpackPluginOptions } from 'mokup/webpack'
106
+ *
107
+ * const options: WebpackPluginOptions = { entries: { dir: 'mock' } }
108
+ */
109
+ type WebpackPluginOptions = MokupPluginOptions;
110
+ /**
111
+ * Webpack plugin options input (alias of MokupPluginOptions).
112
+ *
113
+ * @example
114
+ * import type { WebpackPluginOptionsInput } from 'mokup/webpack'
115
+ *
116
+ * const options: WebpackPluginOptionsInput = { entries: { dir: 'mock' } }
117
+ */
118
+ type WebpackPluginOptionsInput = MokupPluginOptions;
119
+
89
120
  export { MokupPluginOptions, createMokupWebpackPlugin };
121
+ export type { WebpackPluginOptions, WebpackPluginOptionsInput };