routup 5.1.1 → 5.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.
@@ -827,7 +827,7 @@ const HookName = {
827
827
  };
828
828
  //#endregion
829
829
  //#region src/hook/module.ts
830
- var HookManager = class {
830
+ var Hooks = class Hooks {
831
831
  items;
832
832
  constructor() {
833
833
  this.items = {};
@@ -857,6 +857,23 @@ var HookManager = class {
857
857
  }
858
858
  if (this.items[name].length === 0) delete this.items[name];
859
859
  }
860
+ /**
861
+ * Create a new `Hooks` instance seeded with the same listeners as this
862
+ * one.
863
+ *
864
+ * Listener functions are shared by reference; priority and ordering are
865
+ * preserved. Future mutations on the returned instance do not affect this
866
+ * one (and vice versa).
867
+ */
868
+ clone() {
869
+ const next = new Hooks();
870
+ const names = Object.keys(this.items);
871
+ for (const name of names) {
872
+ const entries = this.items[name];
873
+ for (const entry of entries) next.addListener(name, entry.fn, entry.priority);
874
+ }
875
+ return next;
876
+ }
860
877
  async trigger(name, event) {
861
878
  if (!this.items[name] || this.items[name].length === 0) return;
862
879
  try {
@@ -968,12 +985,12 @@ function matchHandlerMethod(handlerMethod, requestMethod) {
968
985
  //#region src/handler/module.ts
969
986
  var Handler = class {
970
987
  config;
971
- hookManager;
988
+ hooks;
972
989
  pathMatcher;
973
990
  method;
974
991
  constructor(handler) {
975
992
  this.config = handler;
976
- this.hookManager = new HookManager();
993
+ this.hooks = new Hooks();
977
994
  this.mountHooks();
978
995
  if (typeof handler.path === "string") this.config.path = withLeadingSlash(handler.path);
979
996
  this.pathMatcher = buildHandlerPathMatcher(this.config.path, !!this.config.method);
@@ -994,7 +1011,7 @@ var Handler = class {
994
1011
  ...pathMatch.params
995
1012
  };
996
1013
  }
997
- await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, event);
1014
+ await this.hooks.trigger(HookName.CHILD_DISPATCH_BEFORE, event);
998
1015
  if (event.dispatched) return;
999
1016
  let response;
1000
1017
  try {
@@ -1033,11 +1050,11 @@ var Handler = class {
1033
1050
  if (response) event.dispatched = true;
1034
1051
  } catch (e) {
1035
1052
  event.error = isError(e) ? e : createError(e);
1036
- await this.hookManager.trigger(HookName.ERROR, event);
1053
+ await this.hooks.trigger(HookName.ERROR, event);
1037
1054
  if (event.dispatched) event.error = void 0;
1038
1055
  else throw event.error;
1039
1056
  }
1040
- await this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, event);
1057
+ await this.hooks.trigger(HookName.CHILD_DISPATCH_AFTER, event);
1041
1058
  return response;
1042
1059
  }
1043
1060
  matchPath(path) {
@@ -1107,9 +1124,9 @@ var Handler = class {
1107
1124
  return Math.min(routerDefault, handlerOverride);
1108
1125
  }
1109
1126
  mountHooks() {
1110
- if (this.config.onBefore) this.hookManager.addListener(HookName.CHILD_DISPATCH_BEFORE, this.config.onBefore);
1111
- if (this.config.onAfter) this.hookManager.addListener(HookName.CHILD_DISPATCH_AFTER, this.config.onAfter);
1112
- if (this.config.onError) this.hookManager.addListener(HookName.ERROR, this.config.onError);
1127
+ if (this.config.onBefore) this.hooks.addListener(HookName.CHILD_DISPATCH_BEFORE, this.config.onBefore);
1128
+ if (this.config.onAfter) this.hooks.addListener(HookName.CHILD_DISPATCH_AFTER, this.config.onAfter);
1129
+ if (this.config.onError) this.hooks.addListener(HookName.ERROR, this.config.onError);
1113
1130
  }
1114
1131
  };
1115
1132
  //#endregion
@@ -1514,6 +1531,15 @@ function acceptsJson(request) {
1514
1531
  }
1515
1532
  //#endregion
1516
1533
  //#region src/router/module.ts
1534
+ const METHOD_TO_REGISTER = {
1535
+ [MethodName.GET]: "get",
1536
+ [MethodName.POST]: "post",
1537
+ [MethodName.PUT]: "put",
1538
+ [MethodName.PATCH]: "patch",
1539
+ [MethodName.DELETE]: "delete",
1540
+ [MethodName.HEAD]: "head",
1541
+ [MethodName.OPTIONS]: "options"
1542
+ };
1517
1543
  var Router = class Router {
1518
1544
  /**
1519
1545
  * A label for the router instance.
@@ -1534,11 +1560,11 @@ var Router = class Router {
1534
1560
  */
1535
1561
  pathMatcher;
1536
1562
  /**
1537
- * A hook manager.
1563
+ * Lifecycle hook registry.
1538
1564
  *
1539
1565
  * @protected
1540
1566
  */
1541
- hookManager;
1567
+ hooks;
1542
1568
  /**
1543
1569
  * Normalized options for this router instance.
1544
1570
  */
@@ -1551,9 +1577,11 @@ var Router = class Router {
1551
1577
  plugins = /* @__PURE__ */ new Map();
1552
1578
  constructor(input = {}) {
1553
1579
  this.name = input.name;
1554
- this.hookManager = new HookManager();
1555
- this._options = normalizeRouterOptions(input);
1556
- this.pathMatcher = buildRouterPathMatcher(input.path);
1580
+ const { hooks = new Hooks(), plugins = /* @__PURE__ */ new Map(), ...options } = input;
1581
+ this.hooks = hooks;
1582
+ this.plugins = new Map(plugins);
1583
+ this._options = normalizeRouterOptions(options);
1584
+ this.pathMatcher = buildRouterPathMatcher(options.path);
1557
1585
  markInstanceof(this, RouterSymbol);
1558
1586
  }
1559
1587
  matchPath(path) {
@@ -1636,7 +1664,7 @@ var Router = class Router {
1636
1664
  await this.executePipelineStepFinish(context);
1637
1665
  }
1638
1666
  async executePipelineStepStart(context) {
1639
- await this.hookManager.trigger(HookName.REQUEST, context.event);
1667
+ await this.hooks.trigger(HookName.REQUEST, context.event);
1640
1668
  if (context.event.dispatched) context.step = RouterPipelineStep.FINISH;
1641
1669
  else context.step = RouterPipelineStep.LOOKUP;
1642
1670
  }
@@ -1653,7 +1681,7 @@ var Router = class Router {
1653
1681
  const method = entry.method ?? handler.method;
1654
1682
  if (method) context.event.methodsAllowed.add(method);
1655
1683
  if (matchHandlerMethod(method, context.event.method)) {
1656
- await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
1684
+ await this.hooks.trigger(HookName.CHILD_MATCH, context.event);
1657
1685
  if (context.event.dispatched) context.step = RouterPipelineStep.FINISH;
1658
1686
  else context.step = RouterPipelineStep.CHILD_BEFORE;
1659
1687
  return;
@@ -1663,7 +1691,7 @@ var Router = class Router {
1663
1691
  continue;
1664
1692
  }
1665
1693
  if (entry.pathMatcher ? entry.pathMatcher.test(context.event.path) : entry.data.matchPath(context.event.path)) {
1666
- await this.hookManager.trigger(HookName.CHILD_MATCH, context.event);
1694
+ await this.hooks.trigger(HookName.CHILD_MATCH, context.event);
1667
1695
  if (context.event.dispatched) context.step = RouterPipelineStep.FINISH;
1668
1696
  else context.step = RouterPipelineStep.CHILD_BEFORE;
1669
1697
  return;
@@ -1673,12 +1701,12 @@ var Router = class Router {
1673
1701
  context.step = RouterPipelineStep.FINISH;
1674
1702
  }
1675
1703
  async executePipelineStepChildBefore(context) {
1676
- await this.hookManager.trigger(HookName.CHILD_DISPATCH_BEFORE, context.event);
1704
+ await this.hooks.trigger(HookName.CHILD_DISPATCH_BEFORE, context.event);
1677
1705
  if (context.event.dispatched) context.step = RouterPipelineStep.FINISH;
1678
1706
  else context.step = RouterPipelineStep.CHILD_DISPATCH;
1679
1707
  }
1680
1708
  async executePipelineStepChildAfter(context) {
1681
- await this.hookManager.trigger(HookName.CHILD_DISPATCH_AFTER, context.event);
1709
+ await this.hooks.trigger(HookName.CHILD_DISPATCH_AFTER, context.event);
1682
1710
  if (context.event.dispatched) context.step = RouterPipelineStep.FINISH;
1683
1711
  else context.step = RouterPipelineStep.LOOKUP;
1684
1712
  }
@@ -1729,7 +1757,7 @@ var Router = class Router {
1729
1757
  }
1730
1758
  } catch (e) {
1731
1759
  event.error = createError(e);
1732
- await this.hookManager.trigger(HookName.ERROR, event);
1760
+ await this.hooks.trigger(HookName.ERROR, event);
1733
1761
  }
1734
1762
  if (!event.dispatched) {
1735
1763
  event.path = savedPath;
@@ -1740,7 +1768,7 @@ var Router = class Router {
1740
1768
  context.step = RouterPipelineStep.CHILD_AFTER;
1741
1769
  }
1742
1770
  async executePipelineStepFinish(context) {
1743
- if (context.event.error || context.event.dispatched) return this.hookManager.trigger(HookName.RESPONSE, context.event);
1771
+ if (context.event.error || context.event.dispatched) return this.hooks.trigger(HookName.RESPONSE, context.event);
1744
1772
  if (!context.event.dispatched && context.event.routerPath.length === 1 && context.event.method && context.event.method === MethodName.OPTIONS) {
1745
1773
  if (context.event.methodsAllowed.has(MethodName.GET)) context.event.methodsAllowed.add(MethodName.HEAD);
1746
1774
  const options = [...context.event.methodsAllowed].map((key) => key.toUpperCase()).join(",");
@@ -1752,7 +1780,7 @@ var Router = class Router {
1752
1780
  });
1753
1781
  context.event.dispatched = true;
1754
1782
  }
1755
- return this.hookManager.trigger(HookName.RESPONSE, context.event);
1783
+ return this.hooks.trigger(HookName.RESPONSE, context.event);
1756
1784
  }
1757
1785
  async dispatch(event) {
1758
1786
  const savedPath = event.path;
@@ -1838,6 +1866,7 @@ var Router = class Router {
1838
1866
  type: RouterStackEntryType.HANDLER,
1839
1867
  data: handler,
1840
1868
  method,
1869
+ path,
1841
1870
  pathMatcher: buildHandlerPathMatcher(path ?? handler.path, true)
1842
1871
  });
1843
1872
  }
@@ -1853,6 +1882,7 @@ var Router = class Router {
1853
1882
  this.stack.push({
1854
1883
  type: RouterStackEntryType.ROUTER,
1855
1884
  data: item,
1885
+ path,
1856
1886
  pathMatcher: buildRouterPathMatcher(path)
1857
1887
  });
1858
1888
  continue;
@@ -1864,7 +1894,8 @@ var Router = class Router {
1864
1894
  });
1865
1895
  this.stack.push({
1866
1896
  type: RouterStackEntryType.HANDLER,
1867
- data: handler
1897
+ data: handler,
1898
+ path
1868
1899
  });
1869
1900
  continue;
1870
1901
  }
@@ -1872,6 +1903,7 @@ var Router = class Router {
1872
1903
  this.stack.push({
1873
1904
  type: RouterStackEntryType.HANDLER,
1874
1905
  data: item,
1906
+ path,
1875
1907
  pathMatcher: buildHandlerPathMatcher(path, !!item.method)
1876
1908
  });
1877
1909
  continue;
@@ -1903,19 +1935,59 @@ var Router = class Router {
1903
1935
  this.plugins.set(plugin.name, plugin.version);
1904
1936
  return this;
1905
1937
  }
1938
+ /**
1939
+ * Return a new `Router` that mirrors this one but owns independent
1940
+ * mountable state.
1941
+ *
1942
+ * The new router has:
1943
+ * - a fresh `stack` array of shallow-copied entries (handlers and child
1944
+ * routers are shared by reference; only the wrapping entries are new)
1945
+ * - the same `pathMatcher` reference (it is stateless)
1946
+ * - a fresh `Hooks` instance seeded with the current listeners
1947
+ * - a shallow copy of `_options`
1948
+ * - a fresh `plugins` map with the same entries
1949
+ *
1950
+ * Use this when the same logical router needs to be mounted under
1951
+ * multiple paths — each mount can receive its own clone so subsequent
1952
+ * mutations on one mount do not bleed into the others.
1953
+ */
1954
+ clone() {
1955
+ const next = new Router({
1956
+ ...this._options,
1957
+ hooks: this.hooks.clone(),
1958
+ plugins: this.plugins
1959
+ });
1960
+ for (const entry of this.stack) {
1961
+ if (entry.type === RouterStackEntryType.ROUTER) {
1962
+ const data = entry.data.clone();
1963
+ if (entry.path) next.use(entry.path, data);
1964
+ else next.use(data);
1965
+ continue;
1966
+ }
1967
+ if (entry.method) {
1968
+ const register = METHOD_TO_REGISTER[entry.method];
1969
+ if (entry.path) next[register](entry.path, entry.data);
1970
+ else next[register](entry.data);
1971
+ continue;
1972
+ }
1973
+ if (entry.path) next.use(entry.path, entry.data);
1974
+ else next.use(entry.data);
1975
+ }
1976
+ return next;
1977
+ }
1906
1978
  on(name, fn, priority) {
1907
- return this.hookManager.addListener(name, fn, priority);
1979
+ return this.hooks.addListener(name, fn, priority);
1908
1980
  }
1909
1981
  off(name, fn) {
1910
1982
  if (typeof fn === "undefined") {
1911
- this.hookManager.removeListener(name);
1983
+ this.hooks.removeListener(name);
1912
1984
  return this;
1913
1985
  }
1914
- this.hookManager.removeListener(name, fn);
1986
+ this.hooks.removeListener(name, fn);
1915
1987
  return this;
1916
1988
  }
1917
1989
  };
1918
1990
  //#endregion
1919
1991
  export { setResponseHeaderAttachment as $, Handler as A, sendRedirect as B, fromWebHandler as C, fromNodeMiddleware as D, fromNodeHandler as E, HandlerSymbol as F, getRequestHeader as G, getRequestAcceptableContentType as H, HandlerType as I, sendAccepted as J, sendFile as K, DispatcherEvent as L, matchHandlerMethod as M, isPath as N, defineErrorHandler as O, PathMatcher as P, setResponseHeaderContentType as Q, RoutupEvent as R, isHandlerOptions as S, isWebHandlerProvider as T, getRequestAcceptableContentTypes as U, sendFormat as V, useRequestNegotiator as W, createError as X, toResponse as Y, isError as Z, getRequestAcceptableEncodings as _, PluginInstallError as a, serializeEventStreamMessage as at, isRequestCacheable as b, isPluginError as c, setResponseCacheHeaders as ct, getRequestIP as d, setResponseHeaderInline as et, getRequestHostName as f, getRequestAcceptableEncoding as g, getRequestAcceptableLanguages as h, PluginNotInstalledError as i, createEventStream as it, buildHandlerPathMatcher as j, defineCoreHandler as k, PluginErrorCode as l, HeaderName as lt, getRequestAcceptableLanguage as m, normalizeRouterOptions as n, appendResponseHeader as nt, PluginAlreadyInstalledError as o, ErrorSymbol as ot, matchRequestContentType as p, sendCreated as q, isPlugin as r, appendResponseHeaderDirective as rt, PluginError as s, RoutupError as st, Router as t, setResponseContentTypeByFileName as tt, getRequestProtocol as u, MethodName as ut, getRequestAcceptableCharset as v, isWebHandler as w, isHandler as x, getRequestAcceptableCharsets as y, sendStream as z };
1920
1992
 
1921
- //# sourceMappingURL=src-DFLGrih4.mjs.map
1993
+ //# sourceMappingURL=src-DX0rndew.mjs.map