prepared-router.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // src/router/reg-exp-router/prepared-router.ts
  2. import { METHOD_NAME_ALL } from "../../router.js";
  3. import { match, emptyParam } from "./matcher.js";
  4. import { RegExpRouter } from "./router.js";
  5. var PreparedRegExpRouter = class {
  6. name = "PreparedRegExpRouter";
  7. #matchers;
  8. #relocateMap;
  9. constructor(matchers, relocateMap) {
  10. this.#matchers = matchers;
  11. this.#relocateMap = relocateMap;
  12. }
  13. #addWildcard(method, handlerData) {
  14. const matcher = this.#matchers[method];
  15. matcher[1].forEach((list) => list && list.push(handlerData));
  16. Object.values(matcher[2]).forEach((list) => list[0].push(handlerData));
  17. }
  18. #addPath(method, path, handler, indexes, map) {
  19. const matcher = this.#matchers[method];
  20. if (!map) {
  21. matcher[2][path][0].push([handler, {}]);
  22. } else {
  23. indexes.forEach((index) => {
  24. if (typeof index === "number") {
  25. matcher[1][index].push([handler, map]);
  26. } else {
  27. ;
  28. matcher[2][index || path][0].push([handler, map]);
  29. }
  30. });
  31. }
  32. }
  33. add(method, path, handler) {
  34. if (!this.#matchers[method]) {
  35. const all = this.#matchers[METHOD_NAME_ALL];
  36. const staticMap = {};
  37. for (const key in all[2]) {
  38. staticMap[key] = [all[2][key][0].slice(), emptyParam];
  39. }
  40. this.#matchers[method] = [
  41. all[0],
  42. all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
  43. staticMap
  44. ];
  45. }
  46. if (path === "/*" || path === "*") {
  47. const handlerData = [handler, {}];
  48. if (method === METHOD_NAME_ALL) {
  49. for (const m in this.#matchers) {
  50. this.#addWildcard(m, handlerData);
  51. }
  52. } else {
  53. this.#addWildcard(method, handlerData);
  54. }
  55. return;
  56. }
  57. const data = this.#relocateMap[path];
  58. if (!data) {
  59. throw new Error(`Path ${path} is not registered`);
  60. }
  61. for (const [indexes, map] of data) {
  62. if (method === METHOD_NAME_ALL) {
  63. for (const m in this.#matchers) {
  64. this.#addPath(m, path, handler, indexes, map);
  65. }
  66. } else {
  67. this.#addPath(method, path, handler, indexes, map);
  68. }
  69. }
  70. }
  71. buildAllMatchers() {
  72. return this.#matchers;
  73. }
  74. match = match;
  75. };
  76. var buildInitParams = ({ paths }) => {
  77. const RegExpRouterWithMatcherExport = class extends RegExpRouter {
  78. buildAndExportAllMatchers() {
  79. return this.buildAllMatchers();
  80. }
  81. };
  82. const router = new RegExpRouterWithMatcherExport();
  83. for (const path of paths) {
  84. router.add(METHOD_NAME_ALL, path, path);
  85. }
  86. const matchers = router.buildAndExportAllMatchers();
  87. const all = matchers[METHOD_NAME_ALL];
  88. const relocateMap = {};
  89. for (const path of paths) {
  90. if (path === "/*" || path === "*") {
  91. continue;
  92. }
  93. all[1].forEach((list, i) => {
  94. list.forEach(([p, map]) => {
  95. if (p === path) {
  96. if (relocateMap[path]) {
  97. relocateMap[path][0][1] = {
  98. ...relocateMap[path][0][1],
  99. ...map
  100. };
  101. } else {
  102. relocateMap[path] = [[[], map]];
  103. }
  104. if (relocateMap[path][0][0].findIndex((j) => j === i) === -1) {
  105. relocateMap[path][0][0].push(i);
  106. }
  107. }
  108. });
  109. });
  110. for (const path2 in all[2]) {
  111. all[2][path2][0].forEach(([p]) => {
  112. if (p === path) {
  113. relocateMap[path] ||= [[[]]];
  114. const value = path2 === path ? "" : path2;
  115. if (relocateMap[path][0][0].findIndex((v) => v === value) === -1) {
  116. relocateMap[path][0][0].push(value);
  117. }
  118. }
  119. });
  120. }
  121. }
  122. for (let i = 0, len = all[1].length; i < len; i++) {
  123. all[1][i] = all[1][i] ? [] : 0;
  124. }
  125. for (const path in all[2]) {
  126. all[2][path][0] = [];
  127. }
  128. return [matchers, relocateMap];
  129. };
  130. var serializeInitParams = ([matchers, relocateMap]) => {
  131. const matchersStr = JSON.stringify(
  132. matchers,
  133. (_, value) => value instanceof RegExp ? `##${value.toString()}##` : value
  134. ).replace(/"##(.+?)##"/g, (_, str) => str.replace(/\\\\/g, "\\"));
  135. const relocateMapStr = JSON.stringify(relocateMap);
  136. return `[${matchersStr},${relocateMapStr}]`;
  137. };
  138. export {
  139. PreparedRegExpRouter,
  140. buildInitParams,
  141. serializeInitParams
  142. };