@tanstack/router-core 1.121.0-alpha.27 → 1.121.0-alpha.28

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.
Files changed (165) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +31 -1
  3. package/dist/cjs/RouterProvider.d.cts +2 -1
  4. package/dist/cjs/defer.cjs +1 -1
  5. package/dist/cjs/defer.cjs.map +1 -1
  6. package/dist/cjs/global.d.cts +7 -0
  7. package/dist/cjs/index.cjs +1 -2
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/index.d.cts +6 -6
  10. package/dist/cjs/link.cjs.map +1 -1
  11. package/dist/cjs/link.d.cts +12 -0
  12. package/dist/cjs/lru-cache.cjs +62 -0
  13. package/dist/cjs/lru-cache.cjs.map +1 -0
  14. package/dist/cjs/lru-cache.d.cts +5 -0
  15. package/dist/cjs/not-found.cjs +1 -1
  16. package/dist/cjs/not-found.cjs.map +1 -1
  17. package/dist/cjs/path.cjs +316 -148
  18. package/dist/cjs/path.cjs.map +1 -1
  19. package/dist/cjs/path.d.cts +18 -24
  20. package/dist/cjs/qss.cjs.map +1 -1
  21. package/dist/cjs/redirect.cjs +3 -0
  22. package/dist/cjs/redirect.cjs.map +1 -1
  23. package/dist/cjs/route.cjs +6 -12
  24. package/dist/cjs/route.cjs.map +1 -1
  25. package/dist/cjs/route.d.cts +29 -9
  26. package/dist/cjs/router.cjs +453 -272
  27. package/dist/cjs/router.cjs.map +1 -1
  28. package/dist/cjs/router.d.cts +55 -85
  29. package/dist/cjs/scroll-restoration.cjs +20 -13
  30. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  31. package/dist/cjs/scroll-restoration.d.cts +9 -1
  32. package/dist/cjs/searchMiddleware.cjs.map +1 -1
  33. package/dist/cjs/searchParams.cjs.map +1 -1
  34. package/dist/cjs/ssr/client.cjs +10 -0
  35. package/dist/cjs/ssr/client.cjs.map +1 -0
  36. package/dist/cjs/ssr/client.d.cts +5 -0
  37. package/dist/cjs/ssr/createRequestHandler.cjs +50 -0
  38. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -0
  39. package/dist/cjs/ssr/createRequestHandler.d.cts +9 -0
  40. package/dist/cjs/ssr/handlerCallback.cjs +7 -0
  41. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -0
  42. package/dist/cjs/ssr/handlerCallback.d.cts +9 -0
  43. package/dist/cjs/ssr/headers.cjs +39 -0
  44. package/dist/cjs/ssr/headers.cjs.map +1 -0
  45. package/dist/cjs/ssr/headers.d.cts +5 -0
  46. package/dist/cjs/ssr/json.cjs +14 -0
  47. package/dist/cjs/ssr/json.cjs.map +1 -0
  48. package/dist/cjs/ssr/json.d.cts +4 -0
  49. package/dist/cjs/ssr/seroval-plugins.cjs +34 -0
  50. package/dist/cjs/ssr/seroval-plugins.cjs.map +1 -0
  51. package/dist/cjs/ssr/seroval-plugins.d.cts +10 -0
  52. package/dist/cjs/ssr/server.cjs +13 -0
  53. package/dist/cjs/ssr/server.cjs.map +1 -0
  54. package/dist/cjs/ssr/server.d.cts +6 -0
  55. package/dist/cjs/ssr/ssr-client.cjs +159 -0
  56. package/dist/cjs/ssr/ssr-client.cjs.map +1 -0
  57. package/dist/cjs/ssr/ssr-client.d.cts +29 -0
  58. package/dist/cjs/ssr/ssr-server.cjs +107 -0
  59. package/dist/cjs/ssr/ssr-server.cjs.map +1 -0
  60. package/dist/cjs/ssr/ssr-server.d.cts +18 -0
  61. package/dist/cjs/ssr/transformStreamWithRouter.cjs +183 -0
  62. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -0
  63. package/dist/cjs/ssr/transformStreamWithRouter.d.cts +6 -0
  64. package/dist/cjs/ssr/tsrScript.cjs +4 -0
  65. package/dist/cjs/ssr/tsrScript.cjs.map +1 -0
  66. package/dist/cjs/ssr/tsrScript.d.cts +0 -0
  67. package/dist/cjs/utils.cjs +7 -25
  68. package/dist/cjs/utils.cjs.map +1 -1
  69. package/dist/cjs/utils.d.cts +1 -6
  70. package/dist/esm/Matches.d.ts +31 -1
  71. package/dist/esm/Matches.js.map +1 -1
  72. package/dist/esm/RouterProvider.d.ts +2 -1
  73. package/dist/esm/defer.js +1 -1
  74. package/dist/esm/defer.js.map +1 -1
  75. package/dist/esm/global.d.ts +7 -0
  76. package/dist/esm/index.d.ts +6 -6
  77. package/dist/esm/index.js +2 -3
  78. package/dist/esm/link.d.ts +12 -0
  79. package/dist/esm/link.js.map +1 -1
  80. package/dist/esm/lru-cache.d.ts +5 -0
  81. package/dist/esm/lru-cache.js +62 -0
  82. package/dist/esm/lru-cache.js.map +1 -0
  83. package/dist/esm/not-found.js +1 -1
  84. package/dist/esm/not-found.js.map +1 -1
  85. package/dist/esm/path.d.ts +18 -24
  86. package/dist/esm/path.js +316 -148
  87. package/dist/esm/path.js.map +1 -1
  88. package/dist/esm/qss.js.map +1 -1
  89. package/dist/esm/redirect.js +3 -0
  90. package/dist/esm/redirect.js.map +1 -1
  91. package/dist/esm/route.d.ts +29 -9
  92. package/dist/esm/route.js +6 -12
  93. package/dist/esm/route.js.map +1 -1
  94. package/dist/esm/router.d.ts +55 -85
  95. package/dist/esm/router.js +462 -281
  96. package/dist/esm/router.js.map +1 -1
  97. package/dist/esm/scroll-restoration.d.ts +9 -1
  98. package/dist/esm/scroll-restoration.js +20 -13
  99. package/dist/esm/scroll-restoration.js.map +1 -1
  100. package/dist/esm/searchMiddleware.js.map +1 -1
  101. package/dist/esm/searchParams.js.map +1 -1
  102. package/dist/esm/ssr/client.d.ts +5 -0
  103. package/dist/esm/ssr/client.js +10 -0
  104. package/dist/esm/ssr/client.js.map +1 -0
  105. package/dist/esm/ssr/createRequestHandler.d.ts +9 -0
  106. package/dist/esm/ssr/createRequestHandler.js +50 -0
  107. package/dist/esm/ssr/createRequestHandler.js.map +1 -0
  108. package/dist/esm/ssr/handlerCallback.d.ts +9 -0
  109. package/dist/esm/ssr/handlerCallback.js +7 -0
  110. package/dist/esm/ssr/handlerCallback.js.map +1 -0
  111. package/dist/esm/ssr/headers.d.ts +5 -0
  112. package/dist/esm/ssr/headers.js +39 -0
  113. package/dist/esm/ssr/headers.js.map +1 -0
  114. package/dist/esm/ssr/json.d.ts +4 -0
  115. package/dist/esm/ssr/json.js +14 -0
  116. package/dist/esm/ssr/json.js.map +1 -0
  117. package/dist/esm/ssr/seroval-plugins.d.ts +10 -0
  118. package/dist/esm/ssr/seroval-plugins.js +34 -0
  119. package/dist/esm/ssr/seroval-plugins.js.map +1 -0
  120. package/dist/esm/ssr/server.d.ts +6 -0
  121. package/dist/esm/ssr/server.js +13 -0
  122. package/dist/esm/ssr/server.js.map +1 -0
  123. package/dist/esm/ssr/ssr-client.d.ts +29 -0
  124. package/dist/esm/ssr/ssr-client.js +159 -0
  125. package/dist/esm/ssr/ssr-client.js.map +1 -0
  126. package/dist/esm/ssr/ssr-server.d.ts +18 -0
  127. package/dist/esm/ssr/ssr-server.js +107 -0
  128. package/dist/esm/ssr/ssr-server.js.map +1 -0
  129. package/dist/esm/ssr/transformStreamWithRouter.d.ts +6 -0
  130. package/dist/esm/ssr/transformStreamWithRouter.js +183 -0
  131. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -0
  132. package/dist/esm/ssr/tsrScript.d.ts +0 -0
  133. package/dist/esm/ssr/tsrScript.js +5 -0
  134. package/dist/esm/ssr/tsrScript.js.map +1 -0
  135. package/dist/esm/utils.d.ts +1 -6
  136. package/dist/esm/utils.js +8 -26
  137. package/dist/esm/utils.js.map +1 -1
  138. package/package.json +29 -2
  139. package/src/Matches.ts +40 -1
  140. package/src/RouterProvider.ts +2 -1
  141. package/src/global.ts +9 -0
  142. package/src/index.ts +12 -20
  143. package/src/link.ts +12 -0
  144. package/src/lru-cache.ts +68 -0
  145. package/src/path.ts +424 -174
  146. package/src/redirect.ts +3 -0
  147. package/src/route.ts +44 -13
  148. package/src/router.ts +580 -312
  149. package/src/scroll-restoration.ts +30 -18
  150. package/src/ssr/client.ts +5 -0
  151. package/src/ssr/createRequestHandler.ts +74 -0
  152. package/src/ssr/handlerCallback.ts +15 -0
  153. package/src/ssr/headers.ts +51 -0
  154. package/src/ssr/json.ts +18 -0
  155. package/src/ssr/seroval-plugins.ts +43 -0
  156. package/src/ssr/server.ts +10 -0
  157. package/src/ssr/ssr-client.ts +242 -0
  158. package/src/ssr/ssr-server.ts +132 -0
  159. package/src/ssr/transformStreamWithRouter.ts +259 -0
  160. package/src/ssr/tsrScript.ts +7 -0
  161. package/src/utils.ts +10 -39
  162. package/src/vite-env.d.ts +4 -0
  163. package/dist/cjs/serializer.d.cts +0 -22
  164. package/dist/esm/serializer.d.ts +0 -22
  165. package/src/serializer.ts +0 -32
package/dist/cjs/path.cjs CHANGED
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const utils = require("./utils.cjs");
4
+ const SEGMENT_TYPE_PATHNAME = 0;
5
+ const SEGMENT_TYPE_PARAM = 1;
6
+ const SEGMENT_TYPE_WILDCARD = 2;
7
+ const SEGMENT_TYPE_OPTIONAL_PARAM = 3;
4
8
  function joinPaths(paths) {
5
9
  return cleanPath(
6
10
  paths.filter((val) => {
@@ -21,7 +25,7 @@ function trimPath(path) {
21
25
  return trimPathRight(trimPathLeft(path));
22
26
  }
23
27
  function removeTrailingSlash(value, basepath) {
24
- if ((value == null ? void 0 : value.endsWith("/")) && value !== "/" && value !== `${basepath}/`) {
28
+ if (value?.endsWith("/") && value !== "/" && value !== `${basepath}/`) {
25
29
  return value.slice(0, -1);
26
30
  }
27
31
  return value;
@@ -29,83 +33,108 @@ function removeTrailingSlash(value, basepath) {
29
33
  function exactPathTest(pathName1, pathName2, basepath) {
30
34
  return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
31
35
  }
36
+ function segmentToString(segment) {
37
+ const { type, value } = segment;
38
+ if (type === SEGMENT_TYPE_PATHNAME) {
39
+ return value;
40
+ }
41
+ const { prefixSegment, suffixSegment } = segment;
42
+ if (type === SEGMENT_TYPE_PARAM) {
43
+ const param = value.substring(1);
44
+ if (prefixSegment && suffixSegment) {
45
+ return `${prefixSegment}{$${param}}${suffixSegment}`;
46
+ } else if (prefixSegment) {
47
+ return `${prefixSegment}{$${param}}`;
48
+ } else if (suffixSegment) {
49
+ return `{$${param}}${suffixSegment}`;
50
+ }
51
+ }
52
+ if (type === SEGMENT_TYPE_OPTIONAL_PARAM) {
53
+ const param = value.substring(1);
54
+ if (prefixSegment && suffixSegment) {
55
+ return `${prefixSegment}{-$${param}}${suffixSegment}`;
56
+ } else if (prefixSegment) {
57
+ return `${prefixSegment}{-$${param}}`;
58
+ } else if (suffixSegment) {
59
+ return `{-$${param}}${suffixSegment}`;
60
+ }
61
+ return `{-$${param}}`;
62
+ }
63
+ if (type === SEGMENT_TYPE_WILDCARD) {
64
+ if (prefixSegment && suffixSegment) {
65
+ return `${prefixSegment}{$}${suffixSegment}`;
66
+ } else if (prefixSegment) {
67
+ return `${prefixSegment}{$}`;
68
+ } else if (suffixSegment) {
69
+ return `{$}${suffixSegment}`;
70
+ }
71
+ }
72
+ return value;
73
+ }
32
74
  function resolvePath({
33
75
  basepath,
34
76
  base,
35
77
  to,
36
78
  trailingSlash = "never",
37
- caseSensitive
79
+ caseSensitive,
80
+ parseCache
38
81
  }) {
39
- var _a, _b;
40
82
  base = removeBasepath(basepath, base, caseSensitive);
41
83
  to = removeBasepath(basepath, to, caseSensitive);
42
- let baseSegments = parsePathname(base);
43
- const toSegments = parsePathname(to);
44
- if (baseSegments.length > 1 && ((_a = utils.last(baseSegments)) == null ? void 0 : _a.value) === "/") {
84
+ let baseSegments = parsePathname(base, parseCache).slice();
85
+ const toSegments = parsePathname(to, parseCache);
86
+ if (baseSegments.length > 1 && utils.last(baseSegments)?.value === "/") {
45
87
  baseSegments.pop();
46
88
  }
47
- toSegments.forEach((toSegment, index) => {
48
- if (toSegment.value === "/") {
89
+ for (let index = 0, length = toSegments.length; index < length; index++) {
90
+ const toSegment = toSegments[index];
91
+ const value = toSegment.value;
92
+ if (value === "/") {
49
93
  if (!index) {
50
94
  baseSegments = [toSegment];
51
- } else if (index === toSegments.length - 1) {
95
+ } else if (index === length - 1) {
52
96
  baseSegments.push(toSegment);
53
97
  } else ;
54
- } else if (toSegment.value === "..") {
98
+ } else if (value === "..") {
55
99
  baseSegments.pop();
56
- } else if (toSegment.value === ".") ;
100
+ } else if (value === ".") ;
57
101
  else {
58
102
  baseSegments.push(toSegment);
59
103
  }
60
- });
104
+ }
61
105
  if (baseSegments.length > 1) {
62
- if (((_b = utils.last(baseSegments)) == null ? void 0 : _b.value) === "/") {
106
+ if (utils.last(baseSegments).value === "/") {
63
107
  if (trailingSlash === "never") {
64
108
  baseSegments.pop();
65
109
  }
66
110
  } else if (trailingSlash === "always") {
67
- baseSegments.push({ type: "pathname", value: "/" });
111
+ baseSegments.push({ type: SEGMENT_TYPE_PATHNAME, value: "/" });
68
112
  }
69
113
  }
70
- const segmentValues = baseSegments.map((segment) => {
71
- if (segment.type === "param") {
72
- const param = segment.value.substring(1);
73
- if (segment.prefixSegment && segment.suffixSegment) {
74
- return `${segment.prefixSegment}{$${param}}${segment.suffixSegment}`;
75
- } else if (segment.prefixSegment) {
76
- return `${segment.prefixSegment}{$${param}}`;
77
- } else if (segment.suffixSegment) {
78
- return `{$${param}}${segment.suffixSegment}`;
79
- }
80
- }
81
- if (segment.type === "wildcard") {
82
- if (segment.prefixSegment && segment.suffixSegment) {
83
- return `${segment.prefixSegment}{$}${segment.suffixSegment}`;
84
- } else if (segment.prefixSegment) {
85
- return `${segment.prefixSegment}{$}`;
86
- } else if (segment.suffixSegment) {
87
- return `{$}${segment.suffixSegment}`;
88
- }
89
- }
90
- return segment.value;
91
- });
114
+ const segmentValues = baseSegments.map(segmentToString);
92
115
  const joined = joinPaths([basepath, ...segmentValues]);
93
- return cleanPath(joined);
116
+ return joined;
94
117
  }
118
+ const parsePathname = (pathname, cache) => {
119
+ if (!pathname) return [];
120
+ const cached = cache?.get(pathname);
121
+ if (cached) return cached;
122
+ const parsed = baseParsePathname(pathname);
123
+ cache?.set(pathname, parsed);
124
+ return parsed;
125
+ };
95
126
  const PARAM_RE = /^\$.{1,}$/;
96
127
  const PARAM_W_CURLY_BRACES_RE = /^(.*?)\{(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/;
128
+ const OPTIONAL_PARAM_W_CURLY_BRACES_RE = /^(.*?)\{-(\$[a-zA-Z_$][a-zA-Z0-9_$]*)\}(.*)$/;
97
129
  const WILDCARD_RE = /^\$$/;
98
130
  const WILDCARD_W_CURLY_BRACES_RE = /^(.*?)\{\$\}(.*)$/;
99
- function parsePathname(pathname) {
100
- if (!pathname) {
101
- return [];
102
- }
131
+ function baseParsePathname(pathname) {
103
132
  pathname = cleanPath(pathname);
104
133
  const segments = [];
105
134
  if (pathname.slice(0, 1) === "/") {
106
135
  pathname = pathname.substring(1);
107
136
  segments.push({
108
- type: "pathname",
137
+ type: SEGMENT_TYPE_PATHNAME,
109
138
  value: "/"
110
139
  });
111
140
  }
@@ -120,19 +149,34 @@ function parsePathname(pathname) {
120
149
  const prefix = wildcardBracesMatch[1];
121
150
  const suffix = wildcardBracesMatch[2];
122
151
  return {
123
- type: "wildcard",
152
+ type: SEGMENT_TYPE_WILDCARD,
124
153
  value: "$",
125
154
  prefixSegment: prefix || void 0,
126
155
  suffixSegment: suffix || void 0
127
156
  };
128
157
  }
158
+ const optionalParamBracesMatch = part.match(
159
+ OPTIONAL_PARAM_W_CURLY_BRACES_RE
160
+ );
161
+ if (optionalParamBracesMatch) {
162
+ const prefix = optionalParamBracesMatch[1];
163
+ const paramName = optionalParamBracesMatch[2];
164
+ const suffix = optionalParamBracesMatch[3];
165
+ return {
166
+ type: SEGMENT_TYPE_OPTIONAL_PARAM,
167
+ value: paramName,
168
+ // Now just $paramName (no prefix)
169
+ prefixSegment: prefix || void 0,
170
+ suffixSegment: suffix || void 0
171
+ };
172
+ }
129
173
  const paramBracesMatch = part.match(PARAM_W_CURLY_BRACES_RE);
130
174
  if (paramBracesMatch) {
131
175
  const prefix = paramBracesMatch[1];
132
176
  const paramName = paramBracesMatch[2];
133
177
  const suffix = paramBracesMatch[3];
134
178
  return {
135
- type: "param",
179
+ type: SEGMENT_TYPE_PARAM,
136
180
  value: "" + paramName,
137
181
  prefixSegment: prefix || void 0,
138
182
  suffixSegment: suffix || void 0
@@ -141,7 +185,7 @@ function parsePathname(pathname) {
141
185
  if (PARAM_RE.test(part)) {
142
186
  const paramName = part.substring(1);
143
187
  return {
144
- type: "param",
188
+ type: SEGMENT_TYPE_PARAM,
145
189
  value: "$" + paramName,
146
190
  prefixSegment: void 0,
147
191
  suffixSegment: void 0
@@ -149,14 +193,14 @@ function parsePathname(pathname) {
149
193
  }
150
194
  if (WILDCARD_RE.test(part)) {
151
195
  return {
152
- type: "wildcard",
196
+ type: SEGMENT_TYPE_WILDCARD,
153
197
  value: "$",
154
198
  prefixSegment: void 0,
155
199
  suffixSegment: void 0
156
200
  };
157
201
  }
158
202
  return {
159
- type: "pathname",
203
+ type: SEGMENT_TYPE_PATHNAME,
160
204
  value: part.includes("%25") ? part.split("%25").map((segment) => decodeURI(segment)).join("%25") : decodeURI(part)
161
205
  };
162
206
  })
@@ -164,7 +208,7 @@ function parsePathname(pathname) {
164
208
  if (pathname.slice(-1) === "/") {
165
209
  pathname = pathname.substring(1);
166
210
  segments.push({
167
- type: "pathname",
211
+ type: SEGMENT_TYPE_PATHNAME,
168
212
  value: "/"
169
213
  });
170
214
  }
@@ -175,13 +219,14 @@ function interpolatePath({
175
219
  params,
176
220
  leaveWildcards,
177
221
  leaveParams,
178
- decodeCharMap
222
+ decodeCharMap,
223
+ parseCache
179
224
  }) {
180
- const interpolatedPathSegments = parsePathname(path);
225
+ const interpolatedPathSegments = parsePathname(path, parseCache);
181
226
  function encodeParam(key) {
182
227
  const value = params[key];
183
228
  const isValueString = typeof value === "string";
184
- if (["*", "_splat"].includes(key)) {
229
+ if (key === "*" || key === "_splat") {
185
230
  return isValueString ? encodeURI(value) : value;
186
231
  } else {
187
232
  return isValueString ? encodePathParam(value, decodeCharMap) : value;
@@ -191,17 +236,30 @@ function interpolatePath({
191
236
  const usedParams = {};
192
237
  const interpolatedPath = joinPaths(
193
238
  interpolatedPathSegments.map((segment) => {
194
- if (segment.type === "wildcard") {
239
+ if (segment.type === SEGMENT_TYPE_PATHNAME) {
240
+ return segment.value;
241
+ }
242
+ if (segment.type === SEGMENT_TYPE_WILDCARD) {
195
243
  usedParams._splat = params._splat;
196
244
  const segmentPrefix = segment.prefixSegment || "";
197
245
  const segmentSuffix = segment.suffixSegment || "";
246
+ if (!("_splat" in params)) {
247
+ isMissingParams = true;
248
+ if (leaveWildcards) {
249
+ return `${segmentPrefix}${segment.value}${segmentSuffix}`;
250
+ }
251
+ if (segmentPrefix || segmentSuffix) {
252
+ return `${segmentPrefix}${segmentSuffix}`;
253
+ }
254
+ return void 0;
255
+ }
198
256
  const value = encodeParam("_splat");
199
257
  if (leaveWildcards) {
200
258
  return `${segmentPrefix}${segment.value}${value ?? ""}${segmentSuffix}`;
201
259
  }
202
260
  return `${segmentPrefix}${value}${segmentSuffix}`;
203
261
  }
204
- if (segment.type === "param") {
262
+ if (segment.type === SEGMENT_TYPE_PARAM) {
205
263
  const key = segment.value.substring(1);
206
264
  if (!isMissingParams && !(key in params)) {
207
265
  isMissingParams = true;
@@ -215,6 +273,29 @@ function interpolatePath({
215
273
  }
216
274
  return `${segmentPrefix}${encodeParam(key) ?? "undefined"}${segmentSuffix}`;
217
275
  }
276
+ if (segment.type === SEGMENT_TYPE_OPTIONAL_PARAM) {
277
+ const key = segment.value.substring(1);
278
+ const segmentPrefix = segment.prefixSegment || "";
279
+ const segmentSuffix = segment.suffixSegment || "";
280
+ if (!(key in params) || params[key] == null) {
281
+ if (leaveWildcards) {
282
+ return `${segmentPrefix}${key}${segmentSuffix}`;
283
+ }
284
+ if (segmentPrefix || segmentSuffix) {
285
+ return `${segmentPrefix}${segmentSuffix}`;
286
+ }
287
+ return void 0;
288
+ }
289
+ usedParams[key] = params[key];
290
+ if (leaveParams) {
291
+ const value = encodeParam(segment.value);
292
+ return `${segmentPrefix}${segment.value}${value ?? ""}${segmentSuffix}`;
293
+ }
294
+ if (leaveWildcards) {
295
+ return `${segmentPrefix}${key}${encodeParam(key) ?? ""}${segmentSuffix}`;
296
+ }
297
+ return `${segmentPrefix}${encodeParam(key) ?? ""}${segmentSuffix}`;
298
+ }
218
299
  return segment.value;
219
300
  })
220
301
  );
@@ -229,8 +310,13 @@ function encodePathParam(value, decodeCharMap) {
229
310
  }
230
311
  return encoded;
231
312
  }
232
- function matchPathname(basepath, currentPathname, matchLocation) {
233
- const pathParams = matchByPath(basepath, currentPathname, matchLocation);
313
+ function matchPathname(basepath, currentPathname, matchLocation, parseCache) {
314
+ const pathParams = matchByPath(
315
+ basepath,
316
+ currentPathname,
317
+ matchLocation,
318
+ parseCache
319
+ );
234
320
  if (matchLocation.to && !pathParams) {
235
321
  return;
236
322
  }
@@ -265,111 +351,156 @@ function removeBasepath(basepath, pathname, caseSensitive = false) {
265
351
  return pathname;
266
352
  }
267
353
  }
268
- function matchByPath(basepath, from, matchLocation) {
354
+ function matchByPath(basepath, from, {
355
+ to,
356
+ fuzzy,
357
+ caseSensitive
358
+ }, parseCache) {
269
359
  if (basepath !== "/" && !from.startsWith(basepath)) {
270
360
  return void 0;
271
361
  }
272
- from = removeBasepath(basepath, from, matchLocation.caseSensitive);
273
- const to = removeBasepath(
274
- basepath,
275
- `${matchLocation.to ?? "$"}`,
276
- matchLocation.caseSensitive
362
+ from = removeBasepath(basepath, from, caseSensitive);
363
+ to = removeBasepath(basepath, `${to ?? "$"}`, caseSensitive);
364
+ const baseSegments = parsePathname(
365
+ from.startsWith("/") ? from : `/${from}`,
366
+ parseCache
367
+ );
368
+ const routeSegments = parsePathname(
369
+ to.startsWith("/") ? to : `/${to}`,
370
+ parseCache
277
371
  );
278
- const baseSegments = parsePathname(from);
279
- const routeSegments = parsePathname(to);
280
- if (!from.startsWith("/")) {
281
- baseSegments.unshift({
282
- type: "pathname",
283
- value: "/"
284
- });
285
- }
286
- if (!to.startsWith("/")) {
287
- routeSegments.unshift({
288
- type: "pathname",
289
- value: "/"
290
- });
291
- }
292
372
  const params = {};
293
- const isMatch = (() => {
294
- var _a;
295
- for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
296
- const baseSegment = baseSegments[i];
297
- const routeSegment = routeSegments[i];
298
- const isLastBaseSegment = i >= baseSegments.length - 1;
299
- const isLastRouteSegment = i >= routeSegments.length - 1;
300
- if (routeSegment) {
301
- if (routeSegment.type === "wildcard") {
302
- const remainingBaseSegments = baseSegments.slice(i);
303
- let _splat;
304
- if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
305
- if (!baseSegment) return false;
306
- const prefix = routeSegment.prefixSegment || "";
307
- const suffix = routeSegment.suffixSegment || "";
308
- const baseValue = baseSegment.value;
309
- if ("prefixSegment" in routeSegment) {
310
- if (!baseValue.startsWith(prefix)) {
311
- return false;
312
- }
313
- }
314
- if ("suffixSegment" in routeSegment) {
315
- if (!((_a = baseSegments[baseSegments.length - 1]) == null ? void 0 : _a.value.endsWith(suffix))) {
316
- return false;
317
- }
318
- }
319
- let rejoinedSplat = decodeURI(
320
- joinPaths(remainingBaseSegments.map((d) => d.value))
321
- );
322
- if (prefix && rejoinedSplat.startsWith(prefix)) {
323
- rejoinedSplat = rejoinedSplat.slice(prefix.length);
373
+ const result = isMatch(
374
+ baseSegments,
375
+ routeSegments,
376
+ params,
377
+ fuzzy,
378
+ caseSensitive
379
+ );
380
+ return result ? params : void 0;
381
+ }
382
+ function isMatch(baseSegments, routeSegments, params, fuzzy, caseSensitive) {
383
+ let baseIndex = 0;
384
+ let routeIndex = 0;
385
+ while (baseIndex < baseSegments.length || routeIndex < routeSegments.length) {
386
+ const baseSegment = baseSegments[baseIndex];
387
+ const routeSegment = routeSegments[routeIndex];
388
+ if (routeSegment) {
389
+ if (routeSegment.type === SEGMENT_TYPE_WILDCARD) {
390
+ const remainingBaseSegments = baseSegments.slice(baseIndex);
391
+ let _splat;
392
+ if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
393
+ if (!baseSegment) return false;
394
+ const prefix = routeSegment.prefixSegment || "";
395
+ const suffix = routeSegment.suffixSegment || "";
396
+ const baseValue = baseSegment.value;
397
+ if ("prefixSegment" in routeSegment) {
398
+ if (!baseValue.startsWith(prefix)) {
399
+ return false;
324
400
  }
325
- if (suffix && rejoinedSplat.endsWith(suffix)) {
326
- rejoinedSplat = rejoinedSplat.slice(
327
- 0,
328
- rejoinedSplat.length - suffix.length
329
- );
401
+ }
402
+ if ("suffixSegment" in routeSegment) {
403
+ if (!baseSegments[baseSegments.length - 1]?.value.endsWith(suffix)) {
404
+ return false;
330
405
  }
331
- _splat = rejoinedSplat;
332
- } else {
333
- _splat = decodeURI(
334
- joinPaths(remainingBaseSegments.map((d) => d.value))
406
+ }
407
+ let rejoinedSplat = decodeURI(
408
+ joinPaths(remainingBaseSegments.map((d) => d.value))
409
+ );
410
+ if (prefix && rejoinedSplat.startsWith(prefix)) {
411
+ rejoinedSplat = rejoinedSplat.slice(prefix.length);
412
+ }
413
+ if (suffix && rejoinedSplat.endsWith(suffix)) {
414
+ rejoinedSplat = rejoinedSplat.slice(
415
+ 0,
416
+ rejoinedSplat.length - suffix.length
335
417
  );
336
418
  }
337
- params["*"] = _splat;
338
- params["_splat"] = _splat;
339
- return true;
419
+ _splat = rejoinedSplat;
420
+ } else {
421
+ _splat = decodeURI(
422
+ joinPaths(remainingBaseSegments.map((d) => d.value))
423
+ );
340
424
  }
341
- if (routeSegment.type === "pathname") {
342
- if (routeSegment.value === "/" && !(baseSegment == null ? void 0 : baseSegment.value)) {
343
- return true;
344
- }
345
- if (baseSegment) {
346
- if (matchLocation.caseSensitive) {
347
- if (routeSegment.value !== baseSegment.value) {
348
- return false;
349
- }
350
- } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
425
+ params["*"] = _splat;
426
+ params["_splat"] = _splat;
427
+ return true;
428
+ }
429
+ if (routeSegment.type === SEGMENT_TYPE_PATHNAME) {
430
+ if (routeSegment.value === "/" && !baseSegment?.value) {
431
+ routeIndex++;
432
+ continue;
433
+ }
434
+ if (baseSegment) {
435
+ if (caseSensitive) {
436
+ if (routeSegment.value !== baseSegment.value) {
351
437
  return false;
352
438
  }
439
+ } else if (routeSegment.value.toLowerCase() !== baseSegment.value.toLowerCase()) {
440
+ return false;
353
441
  }
442
+ baseIndex++;
443
+ routeIndex++;
444
+ continue;
445
+ } else {
446
+ return false;
354
447
  }
448
+ }
449
+ if (routeSegment.type === SEGMENT_TYPE_PARAM) {
355
450
  if (!baseSegment) {
356
451
  return false;
357
452
  }
358
- if (routeSegment.type === "param") {
359
- if (baseSegment.value === "/") {
453
+ if (baseSegment.value === "/") {
454
+ return false;
455
+ }
456
+ let _paramValue = "";
457
+ let matched = false;
458
+ if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
459
+ const prefix = routeSegment.prefixSegment || "";
460
+ const suffix = routeSegment.suffixSegment || "";
461
+ const baseValue = baseSegment.value;
462
+ if (prefix && !baseValue.startsWith(prefix)) {
360
463
  return false;
361
464
  }
362
- let _paramValue;
363
- if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
364
- const prefix = routeSegment.prefixSegment || "";
365
- const suffix = routeSegment.suffixSegment || "";
366
- const baseValue = baseSegment.value;
367
- if (prefix && !baseValue.startsWith(prefix)) {
368
- return false;
369
- }
370
- if (suffix && !baseValue.endsWith(suffix)) {
371
- return false;
372
- }
465
+ if (suffix && !baseValue.endsWith(suffix)) {
466
+ return false;
467
+ }
468
+ let paramValue = baseValue;
469
+ if (prefix && paramValue.startsWith(prefix)) {
470
+ paramValue = paramValue.slice(prefix.length);
471
+ }
472
+ if (suffix && paramValue.endsWith(suffix)) {
473
+ paramValue = paramValue.slice(0, paramValue.length - suffix.length);
474
+ }
475
+ _paramValue = decodeURIComponent(paramValue);
476
+ matched = true;
477
+ } else {
478
+ _paramValue = decodeURIComponent(baseSegment.value);
479
+ matched = true;
480
+ }
481
+ if (matched) {
482
+ params[routeSegment.value.substring(1)] = _paramValue;
483
+ baseIndex++;
484
+ }
485
+ routeIndex++;
486
+ continue;
487
+ }
488
+ if (routeSegment.type === SEGMENT_TYPE_OPTIONAL_PARAM) {
489
+ if (!baseSegment) {
490
+ routeIndex++;
491
+ continue;
492
+ }
493
+ if (baseSegment.value === "/") {
494
+ routeIndex++;
495
+ continue;
496
+ }
497
+ let _paramValue = "";
498
+ let matched = false;
499
+ if (routeSegment.prefixSegment || routeSegment.suffixSegment) {
500
+ const prefix = routeSegment.prefixSegment || "";
501
+ const suffix = routeSegment.suffixSegment || "";
502
+ const baseValue = baseSegment.value;
503
+ if ((!prefix || baseValue.startsWith(prefix)) && (!suffix || baseValue.endsWith(suffix))) {
373
504
  let paramValue = baseValue;
374
505
  if (prefix && paramValue.startsWith(prefix)) {
375
506
  paramValue = paramValue.slice(prefix.length);
@@ -381,21 +512,58 @@ function matchByPath(basepath, from, matchLocation) {
381
512
  );
382
513
  }
383
514
  _paramValue = decodeURIComponent(paramValue);
384
- } else {
515
+ matched = true;
516
+ }
517
+ } else {
518
+ let shouldMatchOptional = true;
519
+ for (let lookAhead = routeIndex + 1; lookAhead < routeSegments.length; lookAhead++) {
520
+ const futureRouteSegment = routeSegments[lookAhead];
521
+ if (futureRouteSegment?.type === SEGMENT_TYPE_PATHNAME && futureRouteSegment.value === baseSegment.value) {
522
+ shouldMatchOptional = false;
523
+ break;
524
+ }
525
+ if (futureRouteSegment?.type === SEGMENT_TYPE_PARAM || futureRouteSegment?.type === SEGMENT_TYPE_WILDCARD) {
526
+ if (baseSegments.length < routeSegments.length) {
527
+ shouldMatchOptional = false;
528
+ }
529
+ break;
530
+ }
531
+ }
532
+ if (shouldMatchOptional) {
385
533
  _paramValue = decodeURIComponent(baseSegment.value);
534
+ matched = true;
386
535
  }
536
+ }
537
+ if (matched) {
387
538
  params[routeSegment.value.substring(1)] = _paramValue;
539
+ baseIndex++;
388
540
  }
541
+ routeIndex++;
542
+ continue;
389
543
  }
390
- if (!isLastBaseSegment && isLastRouteSegment) {
391
- params["**"] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value));
392
- return !!matchLocation.fuzzy && (routeSegment == null ? void 0 : routeSegment.value) !== "/";
544
+ }
545
+ if (baseIndex < baseSegments.length && routeIndex >= routeSegments.length) {
546
+ params["**"] = joinPaths(
547
+ baseSegments.slice(baseIndex).map((d) => d.value)
548
+ );
549
+ return !!fuzzy && routeSegments[routeSegments.length - 1]?.value !== "/";
550
+ }
551
+ if (routeIndex < routeSegments.length && baseIndex >= baseSegments.length) {
552
+ for (let i = routeIndex; i < routeSegments.length; i++) {
553
+ if (routeSegments[i]?.type !== SEGMENT_TYPE_OPTIONAL_PARAM) {
554
+ return false;
555
+ }
393
556
  }
557
+ break;
394
558
  }
395
- return true;
396
- })();
397
- return isMatch ? params : void 0;
559
+ break;
560
+ }
561
+ return true;
398
562
  }
563
+ exports.SEGMENT_TYPE_OPTIONAL_PARAM = SEGMENT_TYPE_OPTIONAL_PARAM;
564
+ exports.SEGMENT_TYPE_PARAM = SEGMENT_TYPE_PARAM;
565
+ exports.SEGMENT_TYPE_PATHNAME = SEGMENT_TYPE_PATHNAME;
566
+ exports.SEGMENT_TYPE_WILDCARD = SEGMENT_TYPE_WILDCARD;
399
567
  exports.cleanPath = cleanPath;
400
568
  exports.exactPathTest = exactPathTest;
401
569
  exports.interpolatePath = interpolatePath;