@bleedingdev/modern-js-server 3.9.0-ultramodern.1 → 3.9.0-ultramodern.11

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.
@@ -43,7 +43,6 @@ const external_node_path_namespaceObject = require("node:path");
43
43
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
44
44
  const server_core_namespaceObject = require("@modern-js/server-core");
45
45
  const node_namespaceObject = require("@modern-js/server-core/node");
46
- const runtime_lifecycle_namespaceObject = require("@modern-js/server-runtime-extensions/runtime-lifecycle");
47
46
  const utils_namespaceObject = require("@modern-js/utils");
48
47
  const external_dev_js_namespaceObject = require("./dev.js");
49
48
  const reloadManager_js_namespaceObject = require("./dev-tools/reloadManager.js");
@@ -98,12 +97,17 @@ async function createDevServer(options, applyPlugins) {
98
97
  builderDevServer
99
98
  }, compiler)
100
99
  ]);
101
- const handle = await (0, runtime_lifecycle_namespaceObject.initializeDisposableServerRuntime)(runtimeServer, runtimeServer.handle, async ()=>{
100
+ try {
102
101
  await applyPlugins(runtimeServer, runtimeOptions, nodeServer);
103
102
  await runtimeServer.init();
104
- });
103
+ } catch (error) {
104
+ await runtimeServer.dispose().catch((disposeError)=>{
105
+ utils_namespaceObject.logger.error(disposeError);
106
+ });
107
+ throw error;
108
+ }
105
109
  nextRuntimeServer = runtimeServer;
106
- return handle;
110
+ return (0, reloadManager_js_namespaceObject.createDrainingHandle)(runtimeServer.handle, ()=>runtimeServer.dispose());
107
111
  };
108
112
  const pendingReloadFiles = new Set();
109
113
  const reloadManager = (0, reloadManager_js_namespaceObject.createReloadManager)({
@@ -122,8 +126,18 @@ async function createDevServer(options, applyPlugins) {
122
126
  const httpsOptions = await genHttpsOptions(devHttpsOption, pwd);
123
127
  nodeServer = await (0, node_namespaceObject.createNodeServer)(reloadManager.handle, httpsOptions, isHttp2);
124
128
  } else nodeServer = await (0, node_namespaceObject.createNodeServer)(reloadManager.handle);
125
- reloadManager.setHandle(await buildRuntimeServer());
126
- currentRuntimeServer = nextRuntimeServer;
129
+ try {
130
+ reloadManager.setHandle(await buildRuntimeServer());
131
+ currentRuntimeServer = nextRuntimeServer;
132
+ } catch (error) {
133
+ reloadManager.close();
134
+ const cleanup = await Promise.allSettled([
135
+ Promise.resolve().then(()=>builderDevServer?.close()),
136
+ Promise.resolve().then(()=>nodeServer.close())
137
+ ]);
138
+ for (const result of cleanup)if ('rejected' === result.status) utils_namespaceObject.logger.error(result.reason);
139
+ throw error;
140
+ }
127
141
  (0, external_dev_js_namespaceObject.setupDevInfra)({
128
142
  config,
129
143
  pwd,
@@ -29,6 +29,7 @@ var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  ReloadManager: ()=>ReloadManager,
32
+ createDrainingHandle: ()=>createDrainingHandle,
32
33
  createReloadManager: ()=>createReloadManager
33
34
  });
34
35
  const utils_namespaceObject = require("@modern-js/utils");
@@ -71,6 +72,35 @@ function _class_private_method_init(obj, privateSet) {
71
72
  _check_private_redeclaration(obj, privateSet);
72
73
  privateSet.add(obj);
73
74
  }
75
+ function createDrainingHandle(handle, dispose) {
76
+ let activeRequests = 0;
77
+ let retired = false;
78
+ let resolveDrained;
79
+ let disposePromise;
80
+ return Object.assign(async (request, ...args)=>{
81
+ if (retired) throw new Error('Cannot dispatch through a retired server runtime.');
82
+ activeRequests += 1;
83
+ try {
84
+ return await handle(request, ...args);
85
+ } finally{
86
+ activeRequests -= 1;
87
+ if (0 === activeRequests) resolveDrained?.();
88
+ }
89
+ }, {
90
+ dispose: ()=>{
91
+ if (!disposePromise) {
92
+ retired = true;
93
+ disposePromise = Promise.resolve().then(async ()=>{
94
+ if (activeRequests > 0) await new Promise((resolve)=>{
95
+ resolveDrained = resolve;
96
+ });
97
+ await dispose();
98
+ });
99
+ }
100
+ return disposePromise;
101
+ }
102
+ });
103
+ }
74
104
  const DEFAULT_DEBOUNCE_MS = 300;
75
105
  const notReadyHandle = ()=>new Response('Dev server is starting…', {
76
106
  status: 503,
@@ -123,7 +153,7 @@ class ReloadManager {
123
153
  clearTimeout(_class_private_field_get(this, _debounceTimer));
124
154
  _class_private_field_set(this, _debounceTimer, null);
125
155
  }
126
- _class_private_method_get(this, _dispose, dispose).call(this, _class_private_field_get(this, _current));
156
+ _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, _class_private_field_get(this, _current));
127
157
  }
128
158
  constructor(options){
129
159
  _class_private_method_init(this, _runLoop);
@@ -198,15 +228,18 @@ async function runLoop() {
198
228
  _class_private_method_get(this, _reportBuildError, reportBuildError).call(this, error);
199
229
  continue;
200
230
  }
201
- if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, dispose).call(this, next);
231
+ if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, next);
202
232
  const previous = _class_private_field_get(this, _current);
203
233
  _class_private_field_set(this, _current, next);
204
234
  try {
205
- null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
206
- } catch (callbackError) {
207
- _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
235
+ try {
236
+ null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
237
+ } catch (callbackError) {
238
+ _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
239
+ }
240
+ } finally{
241
+ await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, previous);
208
242
  }
209
- await _class_private_method_get(this, _dispose, dispose).call(this, previous);
210
243
  }while (_class_private_field_get(this, _pending) && !_class_private_field_get(this, _closed));
211
244
  }
212
245
  function reportBuildError(error) {
@@ -217,7 +250,7 @@ function reportReloadCallbackError(error) {
217
250
  if (_class_private_field_get(this, _onReloadError)) _class_private_field_get(this, _onReloadError).call(this, error);
218
251
  else utils_namespaceObject.logger.warn(`[dev-server] onReload callback failed after a successful swap (handle is already active):\n${error instanceof Error ? error.stack ?? error.message : error}`);
219
252
  }
220
- async function dispose(handle) {
253
+ async function reloadManager_dispose(handle) {
221
254
  try {
222
255
  await handle.dispose?.();
223
256
  } catch (error) {
@@ -228,9 +261,11 @@ function createReloadManager(options) {
228
261
  return new ReloadManager(options);
229
262
  }
230
263
  exports.ReloadManager = __webpack_exports__.ReloadManager;
264
+ exports.createDrainingHandle = __webpack_exports__.createDrainingHandle;
231
265
  exports.createReloadManager = __webpack_exports__.createReloadManager;
232
266
  for(var __rspack_i in __webpack_exports__)if (-1 === [
233
267
  "ReloadManager",
268
+ "createDrainingHandle",
234
269
  "createReloadManager"
235
270
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
236
271
  Object.defineProperty(exports, '__esModule', {
@@ -69,34 +69,28 @@ class DependencyTree {
69
69
  for (const treeNode of this.tree.values()){
70
70
  const { parent } = treeNode.module;
71
71
  const { children } = treeNode.module;
72
- if (parent && !this.shouldIgnore(parent.filename)) {
72
+ if (parent) {
73
73
  const parentTreeNode = this.tree.get(parent.filename);
74
74
  if (parentTreeNode) treeNode.parent.add(parentTreeNode);
75
75
  }
76
76
  children?.forEach((child)=>{
77
- if (!this.shouldIgnore(child.filename)) {
78
- const childTreeNode = this.tree.get(child.filename);
79
- if (childTreeNode) {
80
- treeNode.children.add(childTreeNode);
81
- childTreeNode.parent.add(treeNode);
82
- }
77
+ const childTreeNode = this.tree.get(child.filename);
78
+ if (childTreeNode) {
79
+ treeNode.children.add(childTreeNode);
80
+ childTreeNode.parent.add(treeNode);
83
81
  }
84
82
  });
85
83
  }
86
84
  }
87
85
  shouldIgnore(path) {
88
86
  const matchPath = path && external_node_path_default().isAbsolute(path) ? external_node_path_default().relative(process.cwd(), path) : path;
89
- return !matchPath || Boolean(this.ignore.find((rule)=>external_minimatch_namespaceObject.match([
90
- matchPath
91
- ], rule, {
92
- dot: true
93
- }).length > 0));
87
+ return !matchPath || this.ignore.some((rule)=>rule.match(matchPath));
94
88
  }
95
89
  constructor(){
96
90
  this.tree = new Map();
97
- this.ignore = [
98
- ...defaultIgnores
99
- ];
91
+ this.ignore = defaultIgnores.map((rule)=>new external_minimatch_namespaceObject.Minimatch(rule, {
92
+ dot: true
93
+ }));
100
94
  }
101
95
  }
102
96
  exports.DependencyTree = __webpack_exports__.DependencyTree;
@@ -49,7 +49,7 @@ const external_dependencyTree_js_namespaceObject = require("./dependencyTree.js"
49
49
  const external_statsCache_js_namespaceObject = require("./statsCache.js");
50
50
  const defaultWatchOptions = {
51
51
  ignoreInitial: true,
52
- ignored: /api\/typings\/.*/
52
+ ignored: /api\/typings\/.*|(?:^|[/\\])node_modules(?:[/\\]|$)/
53
53
  };
54
54
  const getWatchedFiles = (watcher)=>{
55
55
  const watched = watcher.getWatched();
@@ -1,10 +1,9 @@
1
1
  import node_path from "node:path";
2
2
  import { createServerBase } from "@modern-js/server-core";
3
3
  import { createNodeServer, loadServerRuntimeConfig } from "@modern-js/server-core/node";
4
- import { initializeDisposableServerRuntime } from "@modern-js/server-runtime-extensions/runtime-lifecycle";
5
4
  import { logger } from "@modern-js/utils";
6
5
  import { devRuntimeMiddlewarePlugin, setupDevInfra } from "./dev.mjs";
7
- import { createReloadManager } from "./dev-tools/reloadManager.mjs";
6
+ import { createDrainingHandle, createReloadManager } from "./dev-tools/reloadManager.mjs";
8
7
  import { createRuntimeServerOptions } from "./dev-tools/runtimeOptions.mjs";
9
8
  import { getDevAssetPrefix, getDevOptions } from "./helpers/index.mjs";
10
9
  async function createDevServer(options, applyPlugins) {
@@ -56,12 +55,17 @@ async function createDevServer(options, applyPlugins) {
56
55
  builderDevServer
57
56
  }, compiler)
58
57
  ]);
59
- const handle = await initializeDisposableServerRuntime(runtimeServer, runtimeServer.handle, async ()=>{
58
+ try {
60
59
  await applyPlugins(runtimeServer, runtimeOptions, nodeServer);
61
60
  await runtimeServer.init();
62
- });
61
+ } catch (error) {
62
+ await runtimeServer.dispose().catch((disposeError)=>{
63
+ logger.error(disposeError);
64
+ });
65
+ throw error;
66
+ }
63
67
  nextRuntimeServer = runtimeServer;
64
- return handle;
68
+ return createDrainingHandle(runtimeServer.handle, ()=>runtimeServer.dispose());
65
69
  };
66
70
  const pendingReloadFiles = new Set();
67
71
  const reloadManager = createReloadManager({
@@ -80,8 +84,18 @@ async function createDevServer(options, applyPlugins) {
80
84
  const httpsOptions = await genHttpsOptions(devHttpsOption, pwd);
81
85
  nodeServer = await createNodeServer(reloadManager.handle, httpsOptions, isHttp2);
82
86
  } else nodeServer = await createNodeServer(reloadManager.handle);
83
- reloadManager.setHandle(await buildRuntimeServer());
84
- currentRuntimeServer = nextRuntimeServer;
87
+ try {
88
+ reloadManager.setHandle(await buildRuntimeServer());
89
+ currentRuntimeServer = nextRuntimeServer;
90
+ } catch (error) {
91
+ reloadManager.close();
92
+ const cleanup = await Promise.allSettled([
93
+ Promise.resolve().then(()=>builderDevServer?.close()),
94
+ Promise.resolve().then(()=>nodeServer.close())
95
+ ]);
96
+ for (const result of cleanup)if ('rejected' === result.status) logger.error(result.reason);
97
+ throw error;
98
+ }
85
99
  setupDevInfra({
86
100
  config,
87
101
  pwd,
@@ -38,6 +38,35 @@ function _class_private_method_init(obj, privateSet) {
38
38
  _check_private_redeclaration(obj, privateSet);
39
39
  privateSet.add(obj);
40
40
  }
41
+ function createDrainingHandle(handle, dispose) {
42
+ let activeRequests = 0;
43
+ let retired = false;
44
+ let resolveDrained;
45
+ let disposePromise;
46
+ return Object.assign(async (request, ...args)=>{
47
+ if (retired) throw new Error('Cannot dispatch through a retired server runtime.');
48
+ activeRequests += 1;
49
+ try {
50
+ return await handle(request, ...args);
51
+ } finally{
52
+ activeRequests -= 1;
53
+ if (0 === activeRequests) resolveDrained?.();
54
+ }
55
+ }, {
56
+ dispose: ()=>{
57
+ if (!disposePromise) {
58
+ retired = true;
59
+ disposePromise = Promise.resolve().then(async ()=>{
60
+ if (activeRequests > 0) await new Promise((resolve)=>{
61
+ resolveDrained = resolve;
62
+ });
63
+ await dispose();
64
+ });
65
+ }
66
+ return disposePromise;
67
+ }
68
+ });
69
+ }
41
70
  const DEFAULT_DEBOUNCE_MS = 300;
42
71
  const notReadyHandle = ()=>new Response('Dev server is starting…', {
43
72
  status: 503,
@@ -90,7 +119,7 @@ class ReloadManager {
90
119
  clearTimeout(_class_private_field_get(this, _debounceTimer));
91
120
  _class_private_field_set(this, _debounceTimer, null);
92
121
  }
93
- _class_private_method_get(this, _dispose, dispose).call(this, _class_private_field_get(this, _current));
122
+ _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, _class_private_field_get(this, _current));
94
123
  }
95
124
  constructor(options){
96
125
  _class_private_method_init(this, _runLoop);
@@ -165,15 +194,18 @@ async function runLoop() {
165
194
  _class_private_method_get(this, _reportBuildError, reportBuildError).call(this, error);
166
195
  continue;
167
196
  }
168
- if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, dispose).call(this, next);
197
+ if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, next);
169
198
  const previous = _class_private_field_get(this, _current);
170
199
  _class_private_field_set(this, _current, next);
171
200
  try {
172
- null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
173
- } catch (callbackError) {
174
- _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
201
+ try {
202
+ null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
203
+ } catch (callbackError) {
204
+ _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
205
+ }
206
+ } finally{
207
+ await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, previous);
175
208
  }
176
- await _class_private_method_get(this, _dispose, dispose).call(this, previous);
177
209
  }while (_class_private_field_get(this, _pending) && !_class_private_field_get(this, _closed))
178
210
  }
179
211
  function reportBuildError(error) {
@@ -184,7 +216,7 @@ function reportReloadCallbackError(error) {
184
216
  if (_class_private_field_get(this, _onReloadError)) _class_private_field_get(this, _onReloadError).call(this, error);
185
217
  else logger.warn(`[dev-server] onReload callback failed after a successful swap (handle is already active):\n${error instanceof Error ? error.stack ?? error.message : error}`);
186
218
  }
187
- async function dispose(handle) {
219
+ async function reloadManager_dispose(handle) {
188
220
  try {
189
221
  await handle.dispose?.();
190
222
  } catch (error) {
@@ -194,4 +226,4 @@ async function dispose(handle) {
194
226
  function createReloadManager(options) {
195
227
  return new ReloadManager(options);
196
228
  }
197
- export { ReloadManager, createReloadManager };
229
+ export { ReloadManager, createDrainingHandle, createReloadManager };
@@ -26,34 +26,28 @@ class DependencyTree {
26
26
  for (const treeNode of this.tree.values()){
27
27
  const { parent } = treeNode.module;
28
28
  const { children } = treeNode.module;
29
- if (parent && !this.shouldIgnore(parent.filename)) {
29
+ if (parent) {
30
30
  const parentTreeNode = this.tree.get(parent.filename);
31
31
  if (parentTreeNode) treeNode.parent.add(parentTreeNode);
32
32
  }
33
33
  children?.forEach((child)=>{
34
- if (!this.shouldIgnore(child.filename)) {
35
- const childTreeNode = this.tree.get(child.filename);
36
- if (childTreeNode) {
37
- treeNode.children.add(childTreeNode);
38
- childTreeNode.parent.add(treeNode);
39
- }
34
+ const childTreeNode = this.tree.get(child.filename);
35
+ if (childTreeNode) {
36
+ treeNode.children.add(childTreeNode);
37
+ childTreeNode.parent.add(treeNode);
40
38
  }
41
39
  });
42
40
  }
43
41
  }
44
42
  shouldIgnore(path) {
45
43
  const matchPath = path && node_path.isAbsolute(path) ? node_path.relative(process.cwd(), path) : path;
46
- return !matchPath || Boolean(this.ignore.find((rule)=>__rspack_external_minimatch.match([
47
- matchPath
48
- ], rule, {
49
- dot: true
50
- }).length > 0));
44
+ return !matchPath || this.ignore.some((rule)=>rule.match(matchPath));
51
45
  }
52
46
  constructor(){
53
47
  this.tree = new Map();
54
- this.ignore = [
55
- ...defaultIgnores
56
- ];
48
+ this.ignore = defaultIgnores.map((rule)=>new __rspack_external_minimatch.Minimatch(rule, {
49
+ dot: true
50
+ }));
57
51
  }
58
52
  }
59
53
  export { DependencyTree, defaultIgnores };
@@ -4,7 +4,7 @@ import { DependencyTree } from "./dependencyTree.mjs";
4
4
  import { StatsCache } from "./statsCache.mjs";
5
5
  const defaultWatchOptions = {
6
6
  ignoreInitial: true,
7
- ignored: /api\/typings\/.*/
7
+ ignored: /api\/typings\/.*|(?:^|[/\\])node_modules(?:[/\\]|$)/
8
8
  };
9
9
  const getWatchedFiles = (watcher)=>{
10
10
  const watched = watcher.getWatched();
@@ -2,10 +2,9 @@ import "node:module";
2
2
  import node_path from "node:path";
3
3
  import { createServerBase } from "@modern-js/server-core";
4
4
  import { createNodeServer, loadServerRuntimeConfig } from "@modern-js/server-core/node";
5
- import { initializeDisposableServerRuntime } from "@modern-js/server-runtime-extensions/runtime-lifecycle";
6
5
  import { logger } from "@modern-js/utils";
7
6
  import { devRuntimeMiddlewarePlugin, setupDevInfra } from "./dev.mjs";
8
- import { createReloadManager } from "./dev-tools/reloadManager.mjs";
7
+ import { createDrainingHandle, createReloadManager } from "./dev-tools/reloadManager.mjs";
9
8
  import { createRuntimeServerOptions } from "./dev-tools/runtimeOptions.mjs";
10
9
  import { getDevAssetPrefix, getDevOptions } from "./helpers/index.mjs";
11
10
  async function createDevServer(options, applyPlugins) {
@@ -57,12 +56,17 @@ async function createDevServer(options, applyPlugins) {
57
56
  builderDevServer
58
57
  }, compiler)
59
58
  ]);
60
- const handle = await initializeDisposableServerRuntime(runtimeServer, runtimeServer.handle, async ()=>{
59
+ try {
61
60
  await applyPlugins(runtimeServer, runtimeOptions, nodeServer);
62
61
  await runtimeServer.init();
63
- });
62
+ } catch (error) {
63
+ await runtimeServer.dispose().catch((disposeError)=>{
64
+ logger.error(disposeError);
65
+ });
66
+ throw error;
67
+ }
64
68
  nextRuntimeServer = runtimeServer;
65
- return handle;
69
+ return createDrainingHandle(runtimeServer.handle, ()=>runtimeServer.dispose());
66
70
  };
67
71
  const pendingReloadFiles = new Set();
68
72
  const reloadManager = createReloadManager({
@@ -81,8 +85,18 @@ async function createDevServer(options, applyPlugins) {
81
85
  const httpsOptions = await genHttpsOptions(devHttpsOption, pwd);
82
86
  nodeServer = await createNodeServer(reloadManager.handle, httpsOptions, isHttp2);
83
87
  } else nodeServer = await createNodeServer(reloadManager.handle);
84
- reloadManager.setHandle(await buildRuntimeServer());
85
- currentRuntimeServer = nextRuntimeServer;
88
+ try {
89
+ reloadManager.setHandle(await buildRuntimeServer());
90
+ currentRuntimeServer = nextRuntimeServer;
91
+ } catch (error) {
92
+ reloadManager.close();
93
+ const cleanup = await Promise.allSettled([
94
+ Promise.resolve().then(()=>builderDevServer?.close()),
95
+ Promise.resolve().then(()=>nodeServer.close())
96
+ ]);
97
+ for (const result of cleanup)if ('rejected' === result.status) logger.error(result.reason);
98
+ throw error;
99
+ }
86
100
  setupDevInfra({
87
101
  config,
88
102
  pwd,
@@ -39,6 +39,35 @@ function _class_private_method_init(obj, privateSet) {
39
39
  _check_private_redeclaration(obj, privateSet);
40
40
  privateSet.add(obj);
41
41
  }
42
+ function createDrainingHandle(handle, dispose) {
43
+ let activeRequests = 0;
44
+ let retired = false;
45
+ let resolveDrained;
46
+ let disposePromise;
47
+ return Object.assign(async (request, ...args)=>{
48
+ if (retired) throw new Error('Cannot dispatch through a retired server runtime.');
49
+ activeRequests += 1;
50
+ try {
51
+ return await handle(request, ...args);
52
+ } finally{
53
+ activeRequests -= 1;
54
+ if (0 === activeRequests) resolveDrained?.();
55
+ }
56
+ }, {
57
+ dispose: ()=>{
58
+ if (!disposePromise) {
59
+ retired = true;
60
+ disposePromise = Promise.resolve().then(async ()=>{
61
+ if (activeRequests > 0) await new Promise((resolve)=>{
62
+ resolveDrained = resolve;
63
+ });
64
+ await dispose();
65
+ });
66
+ }
67
+ return disposePromise;
68
+ }
69
+ });
70
+ }
42
71
  const DEFAULT_DEBOUNCE_MS = 300;
43
72
  const notReadyHandle = ()=>new Response('Dev server is starting…', {
44
73
  status: 503,
@@ -91,7 +120,7 @@ class ReloadManager {
91
120
  clearTimeout(_class_private_field_get(this, _debounceTimer));
92
121
  _class_private_field_set(this, _debounceTimer, null);
93
122
  }
94
- _class_private_method_get(this, _dispose, dispose).call(this, _class_private_field_get(this, _current));
123
+ _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, _class_private_field_get(this, _current));
95
124
  }
96
125
  constructor(options){
97
126
  _class_private_method_init(this, _runLoop);
@@ -166,15 +195,18 @@ async function runLoop() {
166
195
  _class_private_method_get(this, _reportBuildError, reportBuildError).call(this, error);
167
196
  continue;
168
197
  }
169
- if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, dispose).call(this, next);
198
+ if (_class_private_field_get(this, _closed)) return void await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, next);
170
199
  const previous = _class_private_field_get(this, _current);
171
200
  _class_private_field_set(this, _current, next);
172
201
  try {
173
- null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
174
- } catch (callbackError) {
175
- _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
202
+ try {
203
+ null == (_this = _class_private_field_get(_this1 = this, _onReload)) || _this.call(_this1, next);
204
+ } catch (callbackError) {
205
+ _class_private_method_get(this, _reportReloadCallbackError, reportReloadCallbackError).call(this, callbackError);
206
+ }
207
+ } finally{
208
+ await _class_private_method_get(this, _dispose, reloadManager_dispose).call(this, previous);
176
209
  }
177
- await _class_private_method_get(this, _dispose, dispose).call(this, previous);
178
210
  }while (_class_private_field_get(this, _pending) && !_class_private_field_get(this, _closed));
179
211
  }
180
212
  function reportBuildError(error) {
@@ -185,7 +217,7 @@ function reportReloadCallbackError(error) {
185
217
  if (_class_private_field_get(this, _onReloadError)) _class_private_field_get(this, _onReloadError).call(this, error);
186
218
  else logger.warn(`[dev-server] onReload callback failed after a successful swap (handle is already active):\n${error instanceof Error ? error.stack ?? error.message : error}`);
187
219
  }
188
- async function dispose(handle) {
220
+ async function reloadManager_dispose(handle) {
189
221
  try {
190
222
  await handle.dispose?.();
191
223
  } catch (error) {
@@ -195,4 +227,4 @@ async function dispose(handle) {
195
227
  function createReloadManager(options) {
196
228
  return new ReloadManager(options);
197
229
  }
198
- export { ReloadManager, createReloadManager };
230
+ export { ReloadManager, createDrainingHandle, createReloadManager };
@@ -27,34 +27,28 @@ class DependencyTree {
27
27
  for (const treeNode of this.tree.values()){
28
28
  const { parent } = treeNode.module;
29
29
  const { children } = treeNode.module;
30
- if (parent && !this.shouldIgnore(parent.filename)) {
30
+ if (parent) {
31
31
  const parentTreeNode = this.tree.get(parent.filename);
32
32
  if (parentTreeNode) treeNode.parent.add(parentTreeNode);
33
33
  }
34
34
  children?.forEach((child)=>{
35
- if (!this.shouldIgnore(child.filename)) {
36
- const childTreeNode = this.tree.get(child.filename);
37
- if (childTreeNode) {
38
- treeNode.children.add(childTreeNode);
39
- childTreeNode.parent.add(treeNode);
40
- }
35
+ const childTreeNode = this.tree.get(child.filename);
36
+ if (childTreeNode) {
37
+ treeNode.children.add(childTreeNode);
38
+ childTreeNode.parent.add(treeNode);
41
39
  }
42
40
  });
43
41
  }
44
42
  }
45
43
  shouldIgnore(path) {
46
44
  const matchPath = path && node_path.isAbsolute(path) ? node_path.relative(process.cwd(), path) : path;
47
- return !matchPath || Boolean(this.ignore.find((rule)=>__rspack_external_minimatch.match([
48
- matchPath
49
- ], rule, {
50
- dot: true
51
- }).length > 0));
45
+ return !matchPath || this.ignore.some((rule)=>rule.match(matchPath));
52
46
  }
53
47
  constructor(){
54
48
  this.tree = new Map();
55
- this.ignore = [
56
- ...defaultIgnores
57
- ];
49
+ this.ignore = defaultIgnores.map((rule)=>new __rspack_external_minimatch.Minimatch(rule, {
50
+ dot: true
51
+ }));
58
52
  }
59
53
  }
60
54
  export { DependencyTree, defaultIgnores };
@@ -6,7 +6,7 @@ import { DependencyTree } from "./dependencyTree.mjs";
6
6
  import { StatsCache } from "./statsCache.mjs";
7
7
  const defaultWatchOptions = {
8
8
  ignoreInitial: true,
9
- ignored: /api\/typings\/.*/
9
+ ignored: /api\/typings\/.*|(?:^|[/\\])node_modules(?:[/\\]|$)/
10
10
  };
11
11
  const getWatchedFiles = (watcher)=>{
12
12
  const watched = watcher.getWatched();
@@ -5,6 +5,13 @@
5
5
  export type ReloadableHandle = ((request: Request, ...args: any[]) => Response | Promise<Response>) & {
6
6
  dispose?: () => void | Promise<void>;
7
7
  };
8
+ /**
9
+ * Retire a request handle before waiting for its active handler promises.
10
+ * This preserves handler completion semantics; response streams are not drained.
11
+ */
12
+ export declare function createDrainingHandle(handle: ReloadableHandle, dispose: () => void | Promise<void>): ReloadableHandle & {
13
+ dispose: () => Promise<void>;
14
+ };
8
15
  export interface ReloadManagerOptions {
9
16
  /**
10
17
  * The handle used before the first successful build. Optional: when omitted
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.9.0-ultramodern.1",
20
+ "version": "3.9.0-ultramodern.11",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -38,28 +38,27 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.1",
42
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.1",
43
- "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.1",
44
- "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.1",
45
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.1",
46
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.1",
41
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.11",
42
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.11",
43
+ "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.11",
44
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.11",
45
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.11",
47
46
  "@swc/helpers": "^0.5.23",
48
47
  "connect-history-api-fallback": "^2.0.0",
49
48
  "http-compression": "1.1.3",
50
- "minimatch": "^10.2.5",
49
+ "minimatch": "^10.2.6",
51
50
  "path-to-regexp": "^8.4.2",
52
51
  "ws": "^8.21.3"
53
52
  },
54
53
  "devDependencies": {
55
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.1",
54
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.11",
56
55
  "@rslib/core": "1.0.0",
57
56
  "@scripts/rstest-config": "2.66.0",
58
57
  "@types/connect-history-api-fallback": "^1.5.4",
59
- "@types/node": "^26.2.0",
58
+ "@types/node": "^26.4.1",
60
59
  "@types/ws": "^8.18.1",
61
60
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
62
- "node-mocks-http": "^1.18.0",
61
+ "node-mocks-http": "^1.18.1",
63
62
  "tsconfig-paths": "4.2.0",
64
63
  "websocket": "^1.0.35"
65
64
  },