@tanstack/router-core 1.157.7 → 1.157.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
- "version": "1.157.7",
3
+ "version": "1.157.8",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/path.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { isServer } from '@tanstack/router-core/isServer'
1
2
  import { last } from './utils'
2
3
  import {
3
4
  SEGMENT_TYPE_OPTIONAL_PARAM,
@@ -224,6 +225,11 @@ interface InterpolatePathOptions {
224
225
  * Obtained from `compileDecodeCharMap(pathParamsAllowedCharacters)`.
225
226
  */
226
227
  decoder?: (encoded: string) => string
228
+ /**
229
+ * @internal
230
+ * For testing only, in development mode we use the router.isServer value
231
+ */
232
+ server?: boolean
227
233
  }
228
234
 
229
235
  type InterPolatePathResult = {
@@ -258,6 +264,7 @@ export function interpolatePath({
258
264
  path,
259
265
  params,
260
266
  decoder,
267
+ server,
261
268
  }: InterpolatePathOptions): InterPolatePathResult {
262
269
  // Tracking if any params are missing in the `params` object
263
270
  // when interpolating the path
@@ -269,6 +276,65 @@ export function interpolatePath({
269
276
  if (!path.includes('$'))
270
277
  return { interpolatedPath: path, usedParams, isMissingParams }
271
278
 
279
+ if (isServer ?? server) {
280
+ // Fast path for common templates like `/posts/$id` or `/files/$`.
281
+ // Braced segments (`{...}`) are more complex (prefix/suffix/optional) and are
282
+ // handled by the general parser below.
283
+ if (path.indexOf('{') === -1) {
284
+ const length = path.length
285
+ let cursor = 0
286
+ let joined = ''
287
+
288
+ while (cursor < length) {
289
+ // Skip slashes between segments. '/' code is 47
290
+ while (cursor < length && path.charCodeAt(cursor) === 47) cursor++
291
+ if (cursor >= length) break
292
+
293
+ const start = cursor
294
+ let end = path.indexOf('/', cursor)
295
+ if (end === -1) end = length
296
+ cursor = end
297
+
298
+ const part = path.substring(start, end)
299
+ if (!part) continue
300
+
301
+ // `$id` or `$` (splat). '$' code is 36
302
+ if (part.charCodeAt(0) === 36) {
303
+ if (part.length === 1) {
304
+ const splat = params._splat
305
+ usedParams._splat = splat
306
+ // TODO: Deprecate *
307
+ usedParams['*'] = splat
308
+
309
+ if (!splat) {
310
+ isMissingParams = true
311
+ continue
312
+ }
313
+
314
+ const value = encodeParam('_splat', params, decoder)
315
+ joined += '/' + value
316
+ } else {
317
+ const key = part.substring(1)
318
+ if (!isMissingParams && !(key in params)) {
319
+ isMissingParams = true
320
+ }
321
+ usedParams[key] = params[key]
322
+
323
+ const value = encodeParam(key, params, decoder) ?? 'undefined'
324
+ joined += '/' + value
325
+ }
326
+ } else {
327
+ joined += '/' + part
328
+ }
329
+ }
330
+
331
+ if (path.endsWith('/')) joined += '/'
332
+
333
+ const interpolatedPath = joined || '/'
334
+ return { usedParams, interpolatedPath, isMissingParams }
335
+ }
336
+ }
337
+
272
338
  const length = path.length
273
339
  let cursor = 0
274
340
  let segment
package/src/router.ts CHANGED
@@ -1440,6 +1440,7 @@ export class RouterCore<
1440
1440
  path: route.fullPath,
1441
1441
  params: routeParams,
1442
1442
  decoder: this.pathParamsDecoder,
1443
+ server: this.isServer,
1443
1444
  })
1444
1445
 
1445
1446
  // Waste not, want not. If we already have a match for this route,
@@ -1804,6 +1805,7 @@ export class RouterCore<
1804
1805
  const interpolatedNextTo = interpolatePath({
1805
1806
  path: nextTo,
1806
1807
  params: nextParams,
1808
+ server: this.isServer,
1807
1809
  }).interpolatedPath
1808
1810
 
1809
1811
  // Use lightweight getMatchedRoutes instead of matchRoutesInternal
@@ -1850,6 +1852,7 @@ export class RouterCore<
1850
1852
  path: nextTo,
1851
1853
  params: nextParams,
1852
1854
  decoder: this.pathParamsDecoder,
1855
+ server: this.isServer,
1853
1856
  }).interpolatedPath,
1854
1857
  )
1855
1858