@tanstack/react-router 1.92.1 → 1.92.6
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/dist/cjs/router.cjs +3 -3
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/transformer.cjs +88 -25
- package/dist/cjs/transformer.cjs.map +1 -1
- package/dist/cjs/transformer.d.cts +2 -0
- package/dist/esm/router.js +4 -4
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/transformer.d.ts +2 -0
- package/dist/esm/transformer.js +88 -25
- package/dist/esm/transformer.js.map +1 -1
- package/package.json +2 -2
- package/src/router.ts +4 -4
- package/src/transformer.ts +105 -26
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface RouterTransformer {
|
|
2
2
|
stringify: (obj: unknown) => string;
|
|
3
3
|
parse: (str: string) => unknown;
|
|
4
|
+
encode: <T>(value: T) => T;
|
|
5
|
+
decode: <T>(value: T) => T;
|
|
4
6
|
}
|
|
5
7
|
export declare const defaultTransformer: RouterTransformer;
|
|
6
8
|
export type TransformerStringify<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
|
package/dist/esm/transformer.js
CHANGED
|
@@ -1,37 +1,100 @@
|
|
|
1
1
|
import { isPlainObject } from "./utils.js";
|
|
2
2
|
const defaultTransformer = {
|
|
3
|
-
stringify: (value) => JSON.stringify(value, function replacer(key,
|
|
4
|
-
const
|
|
5
|
-
const transformer = transformers.find((t) => t.stringifyCondition(
|
|
3
|
+
stringify: (value) => JSON.stringify(value, function replacer(key, val) {
|
|
4
|
+
const ogVal = this[key];
|
|
5
|
+
const transformer = transformers.find((t) => t.stringifyCondition(ogVal));
|
|
6
6
|
if (transformer) {
|
|
7
|
-
return transformer.stringify(
|
|
7
|
+
return transformer.stringify(ogVal);
|
|
8
8
|
}
|
|
9
|
-
return
|
|
9
|
+
return val;
|
|
10
10
|
}),
|
|
11
|
-
parse: (value) => JSON.parse(value, function parser(key,
|
|
12
|
-
const
|
|
13
|
-
|
|
11
|
+
parse: (value) => JSON.parse(value, function parser(key, val) {
|
|
12
|
+
const ogVal = this[key];
|
|
13
|
+
if (isPlainObject(ogVal)) {
|
|
14
|
+
const transformer = transformers.find((t) => t.parseCondition(ogVal));
|
|
15
|
+
if (transformer) {
|
|
16
|
+
return transformer.parse(ogVal);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return val;
|
|
20
|
+
}),
|
|
21
|
+
encode: (value) => {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return value.map((v) => defaultTransformer.encode(v));
|
|
24
|
+
}
|
|
25
|
+
if (isPlainObject(value)) {
|
|
26
|
+
return Object.fromEntries(
|
|
27
|
+
Object.entries(value).map(([key, v]) => [
|
|
28
|
+
key,
|
|
29
|
+
defaultTransformer.encode(v)
|
|
30
|
+
])
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const transformer = transformers.find((t) => t.stringifyCondition(value));
|
|
14
34
|
if (transformer) {
|
|
15
|
-
return transformer.
|
|
35
|
+
return transformer.stringify(value);
|
|
16
36
|
}
|
|
17
|
-
return
|
|
18
|
-
})
|
|
19
|
-
};
|
|
20
|
-
const transformers = [
|
|
21
|
-
{
|
|
22
|
-
// Dates
|
|
23
|
-
stringifyCondition: (value) => value instanceof Date,
|
|
24
|
-
stringify: (value) => ({ $date: value.toISOString() }),
|
|
25
|
-
parseCondition: (value) => isPlainObject(value) && value.$date,
|
|
26
|
-
parse: (value) => new Date(value.$date)
|
|
37
|
+
return value;
|
|
27
38
|
},
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
decode: (value) => {
|
|
40
|
+
if (isPlainObject(value)) {
|
|
41
|
+
const transformer = transformers.find((t) => t.parseCondition(value));
|
|
42
|
+
if (transformer) {
|
|
43
|
+
return transformer.parse(value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
return value.map((v) => defaultTransformer.decode(v));
|
|
48
|
+
}
|
|
49
|
+
if (isPlainObject(value)) {
|
|
50
|
+
return Object.fromEntries(
|
|
51
|
+
Object.entries(value).map(([key, v]) => [
|
|
52
|
+
key,
|
|
53
|
+
defaultTransformer.decode(v)
|
|
54
|
+
])
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
34
58
|
}
|
|
59
|
+
};
|
|
60
|
+
const createTransformer = (key, check, toValue = (v) => v, fromValue = (v) => v) => ({
|
|
61
|
+
key,
|
|
62
|
+
stringifyCondition: check,
|
|
63
|
+
stringify: (value) => ({ [`$${key}`]: toValue(value) }),
|
|
64
|
+
parseCondition: (value) => Object.hasOwn(value, `$${key}`),
|
|
65
|
+
parse: (value) => fromValue(value[`$${key}`])
|
|
66
|
+
});
|
|
67
|
+
const transformers = [
|
|
68
|
+
createTransformer(
|
|
69
|
+
// Key
|
|
70
|
+
"undefined",
|
|
71
|
+
// Check
|
|
72
|
+
(v) => v === void 0,
|
|
73
|
+
// To
|
|
74
|
+
() => 0,
|
|
75
|
+
// From
|
|
76
|
+
() => void 0
|
|
77
|
+
),
|
|
78
|
+
createTransformer(
|
|
79
|
+
// Key
|
|
80
|
+
"date",
|
|
81
|
+
// Check
|
|
82
|
+
(v) => v instanceof Date,
|
|
83
|
+
// To
|
|
84
|
+
(v) => v.toISOString(),
|
|
85
|
+
// From
|
|
86
|
+
(v) => new Date(v)
|
|
87
|
+
),
|
|
88
|
+
createTransformer(
|
|
89
|
+
// Key
|
|
90
|
+
"error",
|
|
91
|
+
// Check
|
|
92
|
+
(v) => v instanceof Error,
|
|
93
|
+
// To
|
|
94
|
+
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
95
|
+
// From
|
|
96
|
+
(v) => Object.assign(new Error(v.message), v)
|
|
97
|
+
)
|
|
35
98
|
];
|
|
36
99
|
export {
|
|
37
100
|
defaultTransformer
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformer.js","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key,
|
|
1
|
+
{"version":3,"file":"transformer.js","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n encode: <T>(value: T) => T\n decode: <T>(value: T) => T\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key, val) {\n const ogVal = this[key]\n const transformer = transformers.find((t) => t.stringifyCondition(ogVal))\n\n if (transformer) {\n return transformer.stringify(ogVal)\n }\n\n return val\n }),\n parse: (value: string) =>\n JSON.parse(value, function parser(key, val) {\n const ogVal = this[key]\n if (isPlainObject(ogVal)) {\n const transformer = transformers.find((t) => t.parseCondition(ogVal))\n\n if (transformer) {\n return transformer.parse(ogVal)\n }\n }\n\n return val\n }),\n encode: (value: any) => {\n // When encodign, dive first\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.encode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.encode(v),\n ]),\n )\n }\n\n const transformer = transformers.find((t) => t.stringifyCondition(value))\n if (transformer) {\n return transformer.stringify(value)\n }\n\n return value\n },\n decode: (value: any) => {\n // Attempt transform first\n if (isPlainObject(value)) {\n const transformer = transformers.find((t) => t.parseCondition(value))\n if (transformer) {\n return transformer.parse(value)\n }\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.decode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.decode(v),\n ]),\n )\n }\n\n return value\n },\n}\n\nconst createTransformer = <T extends string>(\n key: T,\n check: (value: any) => boolean,\n toValue: (value: any) => any = (v) => v,\n fromValue: (value: any) => any = (v) => v,\n) => ({\n key,\n stringifyCondition: check,\n stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),\n parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),\n parse: (value: any) => fromValue(value[`$${key}`]),\n})\n\n// Keep these ordered by predicted frequency\nconst transformers = [\n createTransformer(\n // Key\n 'undefined',\n // Check\n (v) => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createTransformer(\n // Key\n 'date',\n // Check\n (v) => v instanceof Date,\n // To\n (v) => v.toISOString(),\n // From\n (v) => new Date(v),\n ),\n createTransformer(\n // Key\n 'error',\n // Check\n (v) => v instanceof Error,\n // To\n (v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),\n // From\n (v) => Object.assign(new Error(v.message), v),\n ),\n] as const\n\nexport type TransformerStringify<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : { [K in keyof T]: TransformerStringify<T[K], TSerializable> }\n\nexport type TransformerParse<T, TSerializable> = T extends TSerializable\n ? T\n : T extends React.JSX.Element\n ? ReadableStream\n : { [K in keyof T]: TransformerParse<T[K], TSerializable> }\n\nexport type DefaultTransformerStringify<T> = TransformerStringify<\n T,\n Date | undefined\n>\n\nexport type DefaultTransformerParse<T> = TransformerParse<T, Date | undefined>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
|
-
"version": "1.92.
|
|
3
|
+
"version": "1.92.6",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"node": ">=12"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@tanstack/react-store": "^0.
|
|
52
|
+
"@tanstack/react-store": "^0.7.0",
|
|
53
53
|
"jsesc": "^3.0.2",
|
|
54
54
|
"tiny-invariant": "^1.3.3",
|
|
55
55
|
"tiny-warning": "^1.0.3",
|
package/src/router.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createMemoryHistory,
|
|
4
4
|
parseHref,
|
|
5
5
|
} from '@tanstack/history'
|
|
6
|
-
import { Store } from '@tanstack/react-store'
|
|
6
|
+
import { Store, batch } from '@tanstack/react-store'
|
|
7
7
|
import invariant from 'tiny-invariant'
|
|
8
8
|
import warning from 'tiny-warning'
|
|
9
9
|
import { rootRouteId } from './root'
|
|
@@ -1959,7 +1959,7 @@ export class Router<
|
|
|
1959
1959
|
|
|
1960
1960
|
let pendingMatches!: Array<AnyRouteMatch>
|
|
1961
1961
|
|
|
1962
|
-
|
|
1962
|
+
batch(() => {
|
|
1963
1963
|
// this call breaks a route context of destination route after a redirect
|
|
1964
1964
|
// we should be fine not eagerly calling this since we call it later
|
|
1965
1965
|
// this.clearExpiredCache()
|
|
@@ -2014,7 +2014,7 @@ export class Router<
|
|
|
2014
2014
|
let enteringMatches!: Array<AnyRouteMatch>
|
|
2015
2015
|
let stayingMatches!: Array<AnyRouteMatch>
|
|
2016
2016
|
|
|
2017
|
-
|
|
2017
|
+
batch(() => {
|
|
2018
2018
|
this.__store.setState((s) => {
|
|
2019
2019
|
const previousMatches = s.matches
|
|
2020
2020
|
const newMatches = s.pendingMatches || s.matches
|
|
@@ -2877,7 +2877,7 @@ export class Router<
|
|
|
2877
2877
|
])
|
|
2878
2878
|
|
|
2879
2879
|
// If the matches are already loaded, we need to add them to the cachedMatches
|
|
2880
|
-
|
|
2880
|
+
batch(() => {
|
|
2881
2881
|
matches.forEach((match) => {
|
|
2882
2882
|
if (!loadedMatchIds.has(match.id)) {
|
|
2883
2883
|
this.__store.setState((s) => ({
|
package/src/transformer.ts
CHANGED
|
@@ -3,49 +3,128 @@ import { isPlainObject } from './utils'
|
|
|
3
3
|
export interface RouterTransformer {
|
|
4
4
|
stringify: (obj: unknown) => string
|
|
5
5
|
parse: (str: string) => unknown
|
|
6
|
+
encode: <T>(value: T) => T
|
|
7
|
+
decode: <T>(value: T) => T
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export const defaultTransformer: RouterTransformer = {
|
|
9
11
|
stringify: (value: any) =>
|
|
10
|
-
JSON.stringify(value, function replacer(key,
|
|
11
|
-
const
|
|
12
|
-
const transformer = transformers.find((t) => t.stringifyCondition(
|
|
12
|
+
JSON.stringify(value, function replacer(key, val) {
|
|
13
|
+
const ogVal = this[key]
|
|
14
|
+
const transformer = transformers.find((t) => t.stringifyCondition(ogVal))
|
|
13
15
|
|
|
14
16
|
if (transformer) {
|
|
15
|
-
return transformer.stringify(
|
|
17
|
+
return transformer.stringify(ogVal)
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
return
|
|
20
|
+
return val
|
|
19
21
|
}),
|
|
20
22
|
parse: (value: string) =>
|
|
21
|
-
JSON.parse(value, function parser(key,
|
|
22
|
-
const
|
|
23
|
-
|
|
23
|
+
JSON.parse(value, function parser(key, val) {
|
|
24
|
+
const ogVal = this[key]
|
|
25
|
+
if (isPlainObject(ogVal)) {
|
|
26
|
+
const transformer = transformers.find((t) => t.parseCondition(ogVal))
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if (transformer) {
|
|
29
|
+
return transformer.parse(ogVal)
|
|
30
|
+
}
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
return
|
|
33
|
+
return val
|
|
30
34
|
}),
|
|
31
|
-
|
|
35
|
+
encode: (value: any) => {
|
|
36
|
+
// When encodign, dive first
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.map((v) => defaultTransformer.encode(v))
|
|
39
|
+
}
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
if (isPlainObject(value)) {
|
|
42
|
+
return Object.fromEntries(
|
|
43
|
+
Object.entries(value).map(([key, v]) => [
|
|
44
|
+
key,
|
|
45
|
+
defaultTransformer.encode(v),
|
|
46
|
+
]),
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const transformer = transformers.find((t) => t.stringifyCondition(value))
|
|
51
|
+
if (transformer) {
|
|
52
|
+
return transformer.stringify(value)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return value
|
|
40
56
|
},
|
|
41
|
-
{
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
decode: (value: any) => {
|
|
58
|
+
// Attempt transform first
|
|
59
|
+
if (isPlainObject(value)) {
|
|
60
|
+
const transformer = transformers.find((t) => t.parseCondition(value))
|
|
61
|
+
if (transformer) {
|
|
62
|
+
return transformer.parse(value)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
return value.map((v) => defaultTransformer.decode(v))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isPlainObject(value)) {
|
|
71
|
+
return Object.fromEntries(
|
|
72
|
+
Object.entries(value).map(([key, v]) => [
|
|
73
|
+
key,
|
|
74
|
+
defaultTransformer.decode(v),
|
|
75
|
+
]),
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return value
|
|
48
80
|
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const createTransformer = <T extends string>(
|
|
84
|
+
key: T,
|
|
85
|
+
check: (value: any) => boolean,
|
|
86
|
+
toValue: (value: any) => any = (v) => v,
|
|
87
|
+
fromValue: (value: any) => any = (v) => v,
|
|
88
|
+
) => ({
|
|
89
|
+
key,
|
|
90
|
+
stringifyCondition: check,
|
|
91
|
+
stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),
|
|
92
|
+
parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),
|
|
93
|
+
parse: (value: any) => fromValue(value[`$${key}`]),
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Keep these ordered by predicted frequency
|
|
97
|
+
const transformers = [
|
|
98
|
+
createTransformer(
|
|
99
|
+
// Key
|
|
100
|
+
'undefined',
|
|
101
|
+
// Check
|
|
102
|
+
(v) => v === undefined,
|
|
103
|
+
// To
|
|
104
|
+
() => 0,
|
|
105
|
+
// From
|
|
106
|
+
() => undefined,
|
|
107
|
+
),
|
|
108
|
+
createTransformer(
|
|
109
|
+
// Key
|
|
110
|
+
'date',
|
|
111
|
+
// Check
|
|
112
|
+
(v) => v instanceof Date,
|
|
113
|
+
// To
|
|
114
|
+
(v) => v.toISOString(),
|
|
115
|
+
// From
|
|
116
|
+
(v) => new Date(v),
|
|
117
|
+
),
|
|
118
|
+
createTransformer(
|
|
119
|
+
// Key
|
|
120
|
+
'error',
|
|
121
|
+
// Check
|
|
122
|
+
(v) => v instanceof Error,
|
|
123
|
+
// To
|
|
124
|
+
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
125
|
+
// From
|
|
126
|
+
(v) => Object.assign(new Error(v.message), v),
|
|
127
|
+
),
|
|
49
128
|
] as const
|
|
50
129
|
|
|
51
130
|
export type TransformerStringify<T, TSerializable> = T extends TSerializable
|