@tanstack/router-core 1.133.13 → 1.133.18

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.
@@ -1 +1 @@
1
- {"version":3,"file":"searchMiddleware.js","sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import { deepEqual } from './utils'\nimport type { NoInfer, PickOptional } from './utils'\nimport type { SearchMiddleware } from './route'\nimport type { IsRequiredParams } from './link'\n\nexport function retainSearchParams<TSearchSchema extends object>(\n keys: Array<keyof TSearchSchema> | true,\n): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n const result = next(search)\n if (keys === true) {\n return { ...search, ...result }\n }\n // add missing keys from search to result\n keys.forEach((key) => {\n if (!(key in result)) {\n result[key] = search[key]\n }\n })\n return result\n }\n}\n\nexport function stripSearchParams<\n TSearchSchema,\n TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,\n const TValues =\n | Partial<NoInfer<TOptionalProps>>\n | Array<keyof TOptionalProps>,\n const TInput = IsRequiredParams<TSearchSchema> extends never\n ? TValues | true\n : TValues,\n>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n if (input === true) {\n return {}\n }\n const result = next(search) as Record<string, unknown>\n if (Array.isArray(input)) {\n input.forEach((key) => {\n delete result[key]\n })\n } else {\n Object.entries(input as Record<string, unknown>).forEach(\n ([key, value]) => {\n if (deepEqual(result[key], value)) {\n delete result[key]\n }\n },\n )\n }\n return result as any\n }\n}\n"],"names":[],"mappings":";AAKO,SAAS,mBACd,MACiC;AACjC,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,SAAS,MAAM;AACjB,aAAO,EAAE,GAAG,QAAQ,GAAG,OAAA;AAAA,IACzB;AAEA,SAAK,QAAQ,CAAC,QAAQ;AACpB,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI,OAAO,GAAG;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,kBASd,OAAyD;AACzD,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,QAAI,UAAU,MAAM;AAClB,aAAO,CAAA;AAAA,IACT;AACA,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,QAAQ,CAAC,QAAQ;AACrB,eAAO,OAAO,GAAG;AAAA,MACnB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,QAAQ,KAAgC,EAAE;AAAA,QAC/C,CAAC,CAAC,KAAK,KAAK,MAAM;AAChB,cAAI,UAAU,OAAO,GAAG,GAAG,KAAK,GAAG;AACjC,mBAAO,OAAO,GAAG;AAAA,UACnB;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AACF;"}
1
+ {"version":3,"file":"searchMiddleware.js","sources":["../../src/searchMiddleware.ts"],"sourcesContent":["import { deepEqual } from './utils'\nimport type { NoInfer, PickOptional } from './utils'\nimport type { SearchMiddleware } from './route'\nimport type { IsRequiredParams } from './link'\n\n/**\n * Retain specified search params across navigations.\n *\n * If `keys` is `true`, retain all current params. Otherwise, copy only the\n * listed keys from the current search into the next search.\n *\n * @param keys `true` to retain all, or a list of keys to retain.\n * @returns A search middleware suitable for route `search.middlewares`.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/retainSearchParamsFunction\n */\nexport function retainSearchParams<TSearchSchema extends object>(\n keys: Array<keyof TSearchSchema> | true,\n): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n const result = next(search)\n if (keys === true) {\n return { ...search, ...result }\n }\n // add missing keys from search to result\n keys.forEach((key) => {\n if (!(key in result)) {\n result[key] = search[key]\n }\n })\n return result\n }\n}\n\n/**\n * Remove optional or default-valued search params from navigations.\n *\n * - Pass `true` (only if there are no required search params) to strip all.\n * - Pass an array to always remove those optional keys.\n * - Pass an object of default values; keys equal (deeply) to the defaults are removed.\n *\n * @returns A search middleware suitable for route `search.middlewares`.\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/stripSearchParamsFunction\n */\nexport function stripSearchParams<\n TSearchSchema,\n TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,\n const TValues =\n | Partial<NoInfer<TOptionalProps>>\n | Array<keyof TOptionalProps>,\n const TInput = IsRequiredParams<TSearchSchema> extends never\n ? TValues | true\n : TValues,\n>(input: NoInfer<TInput>): SearchMiddleware<TSearchSchema> {\n return ({ search, next }) => {\n if (input === true) {\n return {}\n }\n const result = next(search) as Record<string, unknown>\n if (Array.isArray(input)) {\n input.forEach((key) => {\n delete result[key]\n })\n } else {\n Object.entries(input as Record<string, unknown>).forEach(\n ([key, value]) => {\n if (deepEqual(result[key], value)) {\n delete result[key]\n }\n },\n )\n }\n return result as any\n }\n}\n"],"names":[],"mappings":";AAeO,SAAS,mBACd,MACiC;AACjC,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,SAAS,MAAM;AACjB,aAAO,EAAE,GAAG,QAAQ,GAAG,OAAA;AAAA,IACzB;AAEA,SAAK,QAAQ,CAAC,QAAQ;AACpB,UAAI,EAAE,OAAO,SAAS;AACpB,eAAO,GAAG,IAAI,OAAO,GAAG;AAAA,MAC1B;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AACF;AAYO,SAAS,kBASd,OAAyD;AACzD,SAAO,CAAC,EAAE,QAAQ,WAAW;AAC3B,QAAI,UAAU,MAAM;AAClB,aAAO,CAAA;AAAA,IACT;AACA,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,QAAQ,CAAC,QAAQ;AACrB,eAAO,OAAO,GAAG;AAAA,MACnB,CAAC;AAAA,IACH,OAAO;AACL,aAAO,QAAQ,KAAgC,EAAE;AAAA,QAC/C,CAAC,CAAC,KAAK,KAAK,MAAM;AAChB,cAAI,UAAU,OAAO,GAAG,GAAG,KAAK,GAAG;AACjC,mBAAO,OAAO,GAAG;AAAA,UACnB;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AACF;"}
@@ -1,7 +1,29 @@
1
1
  import { AnySchema } from './validators.js';
2
2
  export declare const defaultParseSearch: (searchStr: string) => AnySchema;
3
3
  export declare const defaultStringifySearch: (search: Record<string, any>) => string;
4
+ /**
5
+ * Build a `parseSearch` function using a provided JSON-like parser.
6
+ *
7
+ * The returned function strips a leading `?`, decodes values, and attempts to
8
+ * JSON-parse string values using the given `parser`.
9
+ *
10
+ * @param parser Function to parse a string value (e.g. `JSON.parse`).
11
+ * @returns A `parseSearch` function compatible with `Router` options.
12
+ * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization
13
+ */
4
14
  export declare function parseSearchWith(parser: (str: string) => any): (searchStr: string) => AnySchema;
15
+ /**
16
+ * Build a `stringifySearch` function using a provided serializer.
17
+ *
18
+ * Non-primitive values are serialized with `stringify`. If a `parser` is
19
+ * supplied, string values that are parseable are re-serialized to ensure
20
+ * symmetry with `parseSearch`.
21
+ *
22
+ * @param stringify Function to serialize a value (e.g. `JSON.stringify`).
23
+ * @param parser Optional parser to detect parseable strings.
24
+ * @returns A `stringifySearch` function compatible with `Router` options.
25
+ * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization
26
+ */
5
27
  export declare function stringifySearchWith(stringify: (search: any) => string, parser?: (str: string) => any): (search: Record<string, any>) => string;
6
28
  export type SearchSerializer = (searchObj: Record<string, any>) => string;
7
29
  export type SearchParser = (searchStr: string) => Record<string, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"searchParams.js","sources":["../../src/searchParams.ts"],"sourcesContent":["import { decode, encode } from './qss'\nimport type { AnySchema } from './validators'\n\nexport const defaultParseSearch = parseSearchWith(JSON.parse)\nexport const defaultStringifySearch = stringifySearchWith(\n JSON.stringify,\n JSON.parse,\n)\n\nexport function parseSearchWith(parser: (str: string) => any) {\n return (searchStr: string): AnySchema => {\n if (searchStr[0] === '?') {\n searchStr = searchStr.substring(1)\n }\n\n const query: Record<string, unknown> = decode(searchStr)\n\n // Try to parse any query params that might be json\n for (const key in query) {\n const value = query[key]\n if (typeof value === 'string') {\n try {\n query[key] = parser(value)\n } catch (_err) {\n // silent\n }\n }\n }\n\n return query\n }\n}\n\nexport function stringifySearchWith(\n stringify: (search: any) => string,\n parser?: (str: string) => any,\n) {\n const hasParser = typeof parser === 'function'\n function stringifyValue(val: any) {\n if (typeof val === 'object' && val !== null) {\n try {\n return stringify(val)\n } catch (_err) {\n // silent\n }\n } else if (hasParser && typeof val === 'string') {\n try {\n // Check if it's a valid parseable string.\n // If it is, then stringify it again.\n parser(val)\n return stringify(val)\n } catch (_err) {\n // silent\n }\n }\n return val\n }\n\n return (search: Record<string, any>) => {\n const searchStr = encode(search, stringifyValue)\n return searchStr ? `?${searchStr}` : ''\n }\n}\n\nexport type SearchSerializer = (searchObj: Record<string, any>) => string\nexport type SearchParser = (searchStr: string) => Record<string, any>\n"],"names":[],"mappings":";AAGO,MAAM,qBAAqB,gBAAgB,KAAK,KAAK;AACrD,MAAM,yBAAyB;AAAA,EACpC,KAAK;AAAA,EACL,KAAK;AACP;AAEO,SAAS,gBAAgB,QAA8B;AAC5D,SAAO,CAAC,cAAiC;AACvC,QAAI,UAAU,CAAC,MAAM,KAAK;AACxB,kBAAY,UAAU,UAAU,CAAC;AAAA,IACnC;AAEA,UAAM,QAAiC,OAAO,SAAS;AAGvD,eAAW,OAAO,OAAO;AACvB,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,OAAO,UAAU,UAAU;AAC7B,YAAI;AACF,gBAAM,GAAG,IAAI,OAAO,KAAK;AAAA,QAC3B,SAAS,MAAM;AAAA,QAEf;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,oBACd,WACA,QACA;AACA,QAAM,YAAY,OAAO,WAAW;AACpC,WAAS,eAAe,KAAU;AAChC,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAI;AACF,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,MAAM;AAAA,MAEf;AAAA,IACF,WAAW,aAAa,OAAO,QAAQ,UAAU;AAC/C,UAAI;AAGF,eAAO,GAAG;AACV,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,MAAM;AAAA,MAEf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,WAAgC;AACtC,UAAM,YAAY,OAAO,QAAQ,cAAc;AAC/C,WAAO,YAAY,IAAI,SAAS,KAAK;AAAA,EACvC;AACF;"}
1
+ {"version":3,"file":"searchParams.js","sources":["../../src/searchParams.ts"],"sourcesContent":["import { decode, encode } from './qss'\nimport type { AnySchema } from './validators'\n\nexport const defaultParseSearch = parseSearchWith(JSON.parse)\nexport const defaultStringifySearch = stringifySearchWith(\n JSON.stringify,\n JSON.parse,\n)\n\n/**\n * Build a `parseSearch` function using a provided JSON-like parser.\n *\n * The returned function strips a leading `?`, decodes values, and attempts to\n * JSON-parse string values using the given `parser`.\n *\n * @param parser Function to parse a string value (e.g. `JSON.parse`).\n * @returns A `parseSearch` function compatible with `Router` options.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization\n */\nexport function parseSearchWith(parser: (str: string) => any) {\n return (searchStr: string): AnySchema => {\n if (searchStr[0] === '?') {\n searchStr = searchStr.substring(1)\n }\n\n const query: Record<string, unknown> = decode(searchStr)\n\n // Try to parse any query params that might be json\n for (const key in query) {\n const value = query[key]\n if (typeof value === 'string') {\n try {\n query[key] = parser(value)\n } catch (_err) {\n // silent\n }\n }\n }\n\n return query\n }\n}\n\n/**\n * Build a `stringifySearch` function using a provided serializer.\n *\n * Non-primitive values are serialized with `stringify`. If a `parser` is\n * supplied, string values that are parseable are re-serialized to ensure\n * symmetry with `parseSearch`.\n *\n * @param stringify Function to serialize a value (e.g. `JSON.stringify`).\n * @param parser Optional parser to detect parseable strings.\n * @returns A `stringifySearch` function compatible with `Router` options.\n * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization\n */\nexport function stringifySearchWith(\n stringify: (search: any) => string,\n parser?: (str: string) => any,\n) {\n const hasParser = typeof parser === 'function'\n function stringifyValue(val: any) {\n if (typeof val === 'object' && val !== null) {\n try {\n return stringify(val)\n } catch (_err) {\n // silent\n }\n } else if (hasParser && typeof val === 'string') {\n try {\n // Check if it's a valid parseable string.\n // If it is, then stringify it again.\n parser(val)\n return stringify(val)\n } catch (_err) {\n // silent\n }\n }\n return val\n }\n\n return (search: Record<string, any>) => {\n const searchStr = encode(search, stringifyValue)\n return searchStr ? `?${searchStr}` : ''\n }\n}\n\nexport type SearchSerializer = (searchObj: Record<string, any>) => string\nexport type SearchParser = (searchStr: string) => Record<string, any>\n"],"names":[],"mappings":";AAGO,MAAM,qBAAqB,gBAAgB,KAAK,KAAK;AACrD,MAAM,yBAAyB;AAAA,EACpC,KAAK;AAAA,EACL,KAAK;AACP;AAYO,SAAS,gBAAgB,QAA8B;AAC5D,SAAO,CAAC,cAAiC;AACvC,QAAI,UAAU,CAAC,MAAM,KAAK;AACxB,kBAAY,UAAU,UAAU,CAAC;AAAA,IACnC;AAEA,UAAM,QAAiC,OAAO,SAAS;AAGvD,eAAW,OAAO,OAAO;AACvB,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,OAAO,UAAU,UAAU;AAC7B,YAAI;AACF,gBAAM,GAAG,IAAI,OAAO,KAAK;AAAA,QAC3B,SAAS,MAAM;AAAA,QAEf;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAcO,SAAS,oBACd,WACA,QACA;AACA,QAAM,YAAY,OAAO,WAAW;AACpC,WAAS,eAAe,KAAU;AAChC,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,UAAI;AACF,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,MAAM;AAAA,MAEf;AAAA,IACF,WAAW,aAAa,OAAO,QAAQ,UAAU;AAC/C,UAAI;AAGF,eAAO,GAAG;AACV,eAAO,UAAU,GAAG;AAAA,MACtB,SAAS,MAAM;AAAA,MAEf;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,WAAgC;AACtC,UAAM,YAAY,OAAO,QAAQ,cAAc;AAC/C,WAAO,YAAY,IAAI,SAAS,KAAK;AAAA,EACvC;AACF;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
- "version": "1.133.13",
3
+ "version": "1.133.18",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
package/src/defer.ts CHANGED
@@ -22,6 +22,18 @@ export type DeferredPromise<T> = Promise<T> & {
22
22
  [TSR_DEFERRED_PROMISE]: DeferredPromiseState<T>
23
23
  }
24
24
 
25
+ /**
26
+ * Wrap a promise with a deferred state for use with `<Await>` and `useAwaited`.
27
+ *
28
+ * The returned promise is augmented with internal state (status/data/error)
29
+ * so UI can read progress or suspend until it settles.
30
+ *
31
+ * @param _promise The promise to wrap.
32
+ * @param options Optional config. Provide `serializeError` to customize how
33
+ * errors are serialized for transfer.
34
+ * @returns The same promise with attached deferred metadata.
35
+ * @link https://tanstack.com/router/latest/docs/framework/react/api/router/deferFunction
36
+ */
25
37
  export function defer<T>(
26
38
  _promise: Promise<T>,
27
39
  options?: {
@@ -673,6 +673,10 @@ const runLoader = async (
673
673
  const pendingPromise = match._nonReactive.minPendingPromise
674
674
  if (pendingPromise) await pendingPromise
675
675
 
676
+ if (isNotFound(e)) {
677
+ await (route.options.notFoundComponent as any)?.preload?.()
678
+ }
679
+
676
680
  handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e)
677
681
 
678
682
  try {
package/src/not-found.ts CHANGED
@@ -18,12 +18,24 @@ export type NotFoundError = {
18
18
  headers?: HeadersInit
19
19
  }
20
20
 
21
+ /**
22
+ * Create a not-found error object recognized by TanStack Router.
23
+ *
24
+ * Throw this from loaders/actions to trigger the nearest `notFoundComponent`.
25
+ * Use `routeId` to target a specific route's not-found boundary. If `throw`
26
+ * is true, the error is thrown instead of returned.
27
+ *
28
+ * @param options Optional settings including `routeId`, `headers`, and `throw`.
29
+ * @returns A not-found error object that can be thrown or returned.
30
+ * @link https://tanstack.com/router/latest/docs/router/framework/react/api/router/notFoundFunction
31
+ */
21
32
  export function notFound(options: NotFoundError = {}) {
22
33
  ;(options as any).isNotFound = true
23
34
  if (options.throw) throw options
24
35
  return options
25
36
  }
26
37
 
38
+ /** Determine if a value is a TanStack Router not-found error. */
27
39
  export function isNotFound(obj: any): obj is NotFoundError {
28
40
  return !!obj?.isNotFound
29
41
  }
package/src/redirect.ts CHANGED
@@ -54,6 +54,23 @@ export type ResolvedRedirect<
54
54
  TMaskTo extends string = '',
55
55
  > = Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
56
56
 
57
+ /**
58
+ * Create a redirect Response understood by TanStack Router.
59
+ *
60
+ * Use from route `loader`/`beforeLoad` or server functions to trigger a
61
+ * navigation. If `throw: true` is set, the redirect is thrown instead of
62
+ * returned. When an absolute `href` is supplied and `reloadDocument` is not
63
+ * set, a full-document navigation is inferred.
64
+ *
65
+ * @param opts Options for the redirect. Common fields:
66
+ * - `href`: absolute URL for external redirects; infers `reloadDocument`.
67
+ * - `statusCode`: HTTP status code to use (defaults to 307).
68
+ * - `headers`: additional headers to include on the Response.
69
+ * - Standard navigation options like `to`, `params`, `search`, `replace`,
70
+ * and `reloadDocument` for internal redirects.
71
+ * @returns A Response augmented with router navigation options.
72
+ * @link https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction
73
+ */
57
74
  export function redirect<
58
75
  TRouter extends AnyRouter = RegisteredRouter,
59
76
  const TTo extends string | undefined = '.',
@@ -92,6 +109,7 @@ export function redirect<
92
109
  return response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
93
110
  }
94
111
 
112
+ /** Check whether a value is a TanStack Router redirect Response. */
95
113
  export function isRedirect(obj: any): obj is AnyRedirect {
96
114
  return obj instanceof Response && !!(obj as any).options
97
115
  }
package/src/router.ts CHANGED
@@ -2135,10 +2135,16 @@ export class RouterCore<
2135
2135
  await this.latestLoadPromise
2136
2136
  }
2137
2137
 
2138
+ let newStatusCode: number | undefined = undefined
2138
2139
  if (this.hasNotFoundMatch()) {
2140
+ newStatusCode = 404
2141
+ } else if (this.__store.state.matches.some((d) => d.status === 'error')) {
2142
+ newStatusCode = 500
2143
+ }
2144
+ if (newStatusCode !== undefined) {
2139
2145
  this.__store.setState((s) => ({
2140
2146
  ...s,
2141
- statusCode: 404,
2147
+ statusCode: newStatusCode,
2142
2148
  }))
2143
2149
  }
2144
2150
  }
@@ -3,6 +3,16 @@ import type { NoInfer, PickOptional } from './utils'
3
3
  import type { SearchMiddleware } from './route'
4
4
  import type { IsRequiredParams } from './link'
5
5
 
6
+ /**
7
+ * Retain specified search params across navigations.
8
+ *
9
+ * If `keys` is `true`, retain all current params. Otherwise, copy only the
10
+ * listed keys from the current search into the next search.
11
+ *
12
+ * @param keys `true` to retain all, or a list of keys to retain.
13
+ * @returns A search middleware suitable for route `search.middlewares`.
14
+ * @link https://tanstack.com/router/latest/docs/framework/react/api/router/retainSearchParamsFunction
15
+ */
6
16
  export function retainSearchParams<TSearchSchema extends object>(
7
17
  keys: Array<keyof TSearchSchema> | true,
8
18
  ): SearchMiddleware<TSearchSchema> {
@@ -21,6 +31,16 @@ export function retainSearchParams<TSearchSchema extends object>(
21
31
  }
22
32
  }
23
33
 
34
+ /**
35
+ * Remove optional or default-valued search params from navigations.
36
+ *
37
+ * - Pass `true` (only if there are no required search params) to strip all.
38
+ * - Pass an array to always remove those optional keys.
39
+ * - Pass an object of default values; keys equal (deeply) to the defaults are removed.
40
+ *
41
+ * @returns A search middleware suitable for route `search.middlewares`.
42
+ * @link https://tanstack.com/router/latest/docs/framework/react/api/router/stripSearchParamsFunction
43
+ */
24
44
  export function stripSearchParams<
25
45
  TSearchSchema,
26
46
  TOptionalProps = PickOptional<NoInfer<TSearchSchema>>,
@@ -7,6 +7,16 @@ export const defaultStringifySearch = stringifySearchWith(
7
7
  JSON.parse,
8
8
  )
9
9
 
10
+ /**
11
+ * Build a `parseSearch` function using a provided JSON-like parser.
12
+ *
13
+ * The returned function strips a leading `?`, decodes values, and attempts to
14
+ * JSON-parse string values using the given `parser`.
15
+ *
16
+ * @param parser Function to parse a string value (e.g. `JSON.parse`).
17
+ * @returns A `parseSearch` function compatible with `Router` options.
18
+ * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization
19
+ */
10
20
  export function parseSearchWith(parser: (str: string) => any) {
11
21
  return (searchStr: string): AnySchema => {
12
22
  if (searchStr[0] === '?') {
@@ -31,6 +41,18 @@ export function parseSearchWith(parser: (str: string) => any) {
31
41
  }
32
42
  }
33
43
 
44
+ /**
45
+ * Build a `stringifySearch` function using a provided serializer.
46
+ *
47
+ * Non-primitive values are serialized with `stringify`. If a `parser` is
48
+ * supplied, string values that are parseable are re-serialized to ensure
49
+ * symmetry with `parseSearch`.
50
+ *
51
+ * @param stringify Function to serialize a value (e.g. `JSON.stringify`).
52
+ * @param parser Optional parser to detect parseable strings.
53
+ * @returns A `stringifySearch` function compatible with `Router` options.
54
+ * @link https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization
55
+ */
34
56
  export function stringifySearchWith(
35
57
  stringify: (search: any) => string,
36
58
  parser?: (str: string) => any,