@tanstack/router-core 1.126.2 → 1.127.0

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 (74) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +1 -1
  3. package/dist/cjs/index.d.cts +1 -2
  4. package/dist/cjs/router.cjs +8 -25
  5. package/dist/cjs/router.cjs.map +1 -1
  6. package/dist/cjs/router.d.cts +9 -57
  7. package/dist/cjs/ssr/client.cjs +0 -2
  8. package/dist/cjs/ssr/client.cjs.map +1 -1
  9. package/dist/cjs/ssr/client.d.cts +1 -2
  10. package/dist/cjs/ssr/createRequestHandler.cjs +2 -1
  11. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  12. package/dist/cjs/ssr/seroval-plugins.cjs +34 -0
  13. package/dist/cjs/ssr/seroval-plugins.cjs.map +1 -0
  14. package/dist/cjs/ssr/seroval-plugins.d.cts +10 -0
  15. package/dist/cjs/ssr/server.cjs +0 -4
  16. package/dist/cjs/ssr/server.cjs.map +1 -1
  17. package/dist/cjs/ssr/server.d.cts +1 -3
  18. package/dist/cjs/ssr/ssr-client.cjs +18 -56
  19. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  20. package/dist/cjs/ssr/ssr-client.d.cts +17 -57
  21. package/dist/cjs/ssr/ssr-server.cjs +75 -220
  22. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  23. package/dist/cjs/ssr/ssr-server.d.cts +14 -28
  24. package/dist/cjs/ssr/transformStreamWithRouter.cjs +1 -0
  25. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  26. package/dist/cjs/ssr/tsrScript.cjs +1 -1
  27. package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
  28. package/dist/cjs/ssr/tsrScript.d.cts +0 -1
  29. package/dist/esm/Matches.d.ts +1 -1
  30. package/dist/esm/Matches.js.map +1 -1
  31. package/dist/esm/index.d.ts +1 -2
  32. package/dist/esm/router.d.ts +9 -57
  33. package/dist/esm/router.js +8 -25
  34. package/dist/esm/router.js.map +1 -1
  35. package/dist/esm/ssr/client.d.ts +1 -2
  36. package/dist/esm/ssr/client.js +1 -3
  37. package/dist/esm/ssr/client.js.map +1 -1
  38. package/dist/esm/ssr/createRequestHandler.js +3 -2
  39. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  40. package/dist/esm/ssr/seroval-plugins.d.ts +10 -0
  41. package/dist/esm/ssr/seroval-plugins.js +34 -0
  42. package/dist/esm/ssr/seroval-plugins.js.map +1 -0
  43. package/dist/esm/ssr/server.d.ts +1 -3
  44. package/dist/esm/ssr/server.js +1 -5
  45. package/dist/esm/ssr/ssr-client.d.ts +17 -57
  46. package/dist/esm/ssr/ssr-client.js +18 -56
  47. package/dist/esm/ssr/ssr-client.js.map +1 -1
  48. package/dist/esm/ssr/ssr-server.d.ts +14 -28
  49. package/dist/esm/ssr/ssr-server.js +76 -221
  50. package/dist/esm/ssr/ssr-server.js.map +1 -1
  51. package/dist/esm/ssr/transformStreamWithRouter.js +1 -0
  52. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  53. package/dist/esm/ssr/tsrScript.d.ts +0 -1
  54. package/dist/esm/ssr/tsrScript.js +1 -1
  55. package/dist/esm/ssr/tsrScript.js.map +1 -1
  56. package/package.json +3 -1
  57. package/src/Matches.ts +1 -1
  58. package/src/index.ts +0 -18
  59. package/src/router.ts +15 -82
  60. package/src/ssr/client.ts +1 -11
  61. package/src/ssr/createRequestHandler.ts +2 -2
  62. package/src/ssr/seroval-plugins.ts +43 -0
  63. package/src/ssr/server.ts +1 -14
  64. package/src/ssr/ssr-client.ts +35 -128
  65. package/src/ssr/ssr-server.ts +89 -307
  66. package/src/ssr/transformStreamWithRouter.ts +1 -0
  67. package/src/ssr/tsrScript.ts +4 -88
  68. package/dist/cjs/serializer.cjs +0 -146
  69. package/dist/cjs/serializer.cjs.map +0 -1
  70. package/dist/cjs/serializer.d.cts +0 -28
  71. package/dist/esm/serializer.d.ts +0 -28
  72. package/dist/esm/serializer.js +0 -146
  73. package/dist/esm/serializer.js.map +0 -1
  74. package/src/serializer.ts +0 -205
@@ -1 +0,0 @@
1
- {"version":3,"file":"serializer.cjs","sources":["../../src/serializer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface TsrSerializer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n encode: <T>(value: T) => T\n decode: <T>(value: T) => T\n}\n\n/**\n * @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.\n */\nexport interface StartSerializer extends TsrSerializer {}\n\nexport type SerializerStringifyBy<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : { [K in keyof T]: SerializerStringifyBy<T[K], TSerializable> }\n\nexport type SerializerParseBy<T, TSerializable> = T extends TSerializable\n ? T\n : unknown extends SerializerExtensions['ReadableStream']\n ? { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }\n : T extends SerializerExtensions['ReadableStream']\n ? ReadableStream\n : { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }\n\nexport interface DefaultSerializerExtensions {\n ReadableStream: unknown\n}\n\nexport interface SerializerExtensions extends DefaultSerializerExtensions {}\n\nexport type Serializable = Date | undefined | Error | FormData | bigint\n\nexport type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>\n\nexport type SerializerParse<T> = SerializerParseBy<T, Serializable>\nexport const tsrSerializer: TsrSerializer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key, val) {\n const ogVal = this[key]\n const serializer = serializers.find((t) => t.stringifyCondition(ogVal))\n\n if (serializer) {\n return serializer.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 serializer = serializers.find((t) => t.parseCondition(ogVal))\n\n if (serializer) {\n return serializer.parse(ogVal)\n }\n }\n\n return val\n }),\n encode: (value: any) => {\n // When encoding, dive first\n if (Array.isArray(value)) {\n return value.map((v) => tsrSerializer.encode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [key, tsrSerializer.encode(v)]),\n )\n }\n\n const serializer = serializers.find((t) => t.stringifyCondition(value))\n if (serializer) {\n return serializer.stringify(value)\n }\n\n return value\n },\n decode: (value: any) => {\n // Attempt transform first\n if (isPlainObject(value)) {\n const serializer = serializers.find((t) => t.parseCondition(value))\n if (serializer) {\n return serializer.parse(value)\n }\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => tsrSerializer.decode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [key, tsrSerializer.decode(v)]),\n )\n }\n\n return value\n },\n}\nconst createSerializer = <TKey extends string, TInput, TSerialized>(\n key: TKey,\n check: (value: any) => value is TInput,\n toValue: (value: TInput) => TSerialized,\n fromValue: (value: TSerialized) => TInput,\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// Keep these ordered by predicted frequency\n// Make sure to keep DefaultSerializable in sync with these serializers\n// Also, make sure that they are unit tested in serializer.test.tsx\nconst serializers = [\n createSerializer(\n // Key\n 'undefined',\n // Check\n (v): v is undefined => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createSerializer(\n // Key\n 'date',\n // Check\n (v): v is Date => v instanceof Date,\n // To\n (v) => v.toISOString(),\n // From\n (v) => new Date(v),\n ),\n createSerializer(\n // Key\n 'error',\n // Check\n (v): v is Error => v instanceof Error,\n // To\n (v) => ({\n ...v,\n message: v.message,\n stack: process.env.NODE_ENV === 'development' ? v.stack : undefined,\n cause: v.cause,\n }),\n // From\n (v) => Object.assign(new Error(v.message), v),\n ),\n createSerializer(\n // Key\n 'formData',\n // Check\n (v): v is FormData => v instanceof FormData,\n // To\n (v) => {\n const entries: Record<\n string,\n Array<FormDataEntryValue> | FormDataEntryValue\n > = {}\n v.forEach((value, key) => {\n const entry = entries[key]\n if (entry !== undefined) {\n if (Array.isArray(entry)) {\n entry.push(value)\n } else {\n entries[key] = [entry, value]\n }\n } else {\n entries[key] = value\n }\n })\n return entries\n },\n // From\n (v) => {\n const formData = new FormData()\n Object.entries(v).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((val) => formData.append(key, val))\n } else {\n formData.append(key, value)\n }\n })\n return formData\n },\n ),\n createSerializer(\n // Key\n 'bigint',\n // Check\n (v): v is bigint => typeof v === 'bigint',\n // To\n (v) => v.toString(),\n // From\n (v) => BigInt(v),\n ),\n] as const\n"],"names":["isPlainObject"],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- export interface TsrSerializer {
2
- stringify: (obj: unknown) => string;
3
- parse: (str: string) => unknown;
4
- encode: <T>(value: T) => T;
5
- decode: <T>(value: T) => T;
6
- }
7
- /**
8
- * @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.
9
- */
10
- export interface StartSerializer extends TsrSerializer {
11
- }
12
- export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
13
- [K in keyof T]: SerializerStringifyBy<T[K], TSerializable>;
14
- };
15
- export type SerializerParseBy<T, TSerializable> = T extends TSerializable ? T : unknown extends SerializerExtensions['ReadableStream'] ? {
16
- [K in keyof T]: SerializerParseBy<T[K], TSerializable>;
17
- } : T extends SerializerExtensions['ReadableStream'] ? ReadableStream : {
18
- [K in keyof T]: SerializerParseBy<T[K], TSerializable>;
19
- };
20
- export interface DefaultSerializerExtensions {
21
- ReadableStream: unknown;
22
- }
23
- export interface SerializerExtensions extends DefaultSerializerExtensions {
24
- }
25
- export type Serializable = Date | undefined | Error | FormData | bigint;
26
- export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>;
27
- export type SerializerParse<T> = SerializerParseBy<T, Serializable>;
28
- export declare const tsrSerializer: TsrSerializer;
@@ -1,28 +0,0 @@
1
- export interface TsrSerializer {
2
- stringify: (obj: unknown) => string;
3
- parse: (str: string) => unknown;
4
- encode: <T>(value: T) => T;
5
- decode: <T>(value: T) => T;
6
- }
7
- /**
8
- * @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.
9
- */
10
- export interface StartSerializer extends TsrSerializer {
11
- }
12
- export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
13
- [K in keyof T]: SerializerStringifyBy<T[K], TSerializable>;
14
- };
15
- export type SerializerParseBy<T, TSerializable> = T extends TSerializable ? T : unknown extends SerializerExtensions['ReadableStream'] ? {
16
- [K in keyof T]: SerializerParseBy<T[K], TSerializable>;
17
- } : T extends SerializerExtensions['ReadableStream'] ? ReadableStream : {
18
- [K in keyof T]: SerializerParseBy<T[K], TSerializable>;
19
- };
20
- export interface DefaultSerializerExtensions {
21
- ReadableStream: unknown;
22
- }
23
- export interface SerializerExtensions extends DefaultSerializerExtensions {
24
- }
25
- export type Serializable = Date | undefined | Error | FormData | bigint;
26
- export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>;
27
- export type SerializerParse<T> = SerializerParseBy<T, Serializable>;
28
- export declare const tsrSerializer: TsrSerializer;
@@ -1,146 +0,0 @@
1
- import { isPlainObject } from "./utils.js";
2
- const tsrSerializer = {
3
- stringify: (value) => JSON.stringify(value, function replacer(key, val) {
4
- const ogVal = this[key];
5
- const serializer = serializers.find((t) => t.stringifyCondition(ogVal));
6
- if (serializer) {
7
- return serializer.stringify(ogVal);
8
- }
9
- return val;
10
- }),
11
- parse: (value) => JSON.parse(value, function parser(key, val) {
12
- const ogVal = this[key];
13
- if (isPlainObject(ogVal)) {
14
- const serializer = serializers.find((t) => t.parseCondition(ogVal));
15
- if (serializer) {
16
- return serializer.parse(ogVal);
17
- }
18
- }
19
- return val;
20
- }),
21
- encode: (value) => {
22
- if (Array.isArray(value)) {
23
- return value.map((v) => tsrSerializer.encode(v));
24
- }
25
- if (isPlainObject(value)) {
26
- return Object.fromEntries(
27
- Object.entries(value).map(([key, v]) => [key, tsrSerializer.encode(v)])
28
- );
29
- }
30
- const serializer = serializers.find((t) => t.stringifyCondition(value));
31
- if (serializer) {
32
- return serializer.stringify(value);
33
- }
34
- return value;
35
- },
36
- decode: (value) => {
37
- if (isPlainObject(value)) {
38
- const serializer = serializers.find((t) => t.parseCondition(value));
39
- if (serializer) {
40
- return serializer.parse(value);
41
- }
42
- }
43
- if (Array.isArray(value)) {
44
- return value.map((v) => tsrSerializer.decode(v));
45
- }
46
- if (isPlainObject(value)) {
47
- return Object.fromEntries(
48
- Object.entries(value).map(([key, v]) => [key, tsrSerializer.decode(v)])
49
- );
50
- }
51
- return value;
52
- }
53
- };
54
- const createSerializer = (key, check, toValue, fromValue) => ({
55
- key,
56
- stringifyCondition: check,
57
- stringify: (value) => ({ [`$${key}`]: toValue(value) }),
58
- parseCondition: (value) => Object.hasOwn(value, `$${key}`),
59
- parse: (value) => fromValue(value[`$${key}`])
60
- });
61
- const serializers = [
62
- createSerializer(
63
- // Key
64
- "undefined",
65
- // Check
66
- (v) => v === void 0,
67
- // To
68
- () => 0,
69
- // From
70
- () => void 0
71
- ),
72
- createSerializer(
73
- // Key
74
- "date",
75
- // Check
76
- (v) => v instanceof Date,
77
- // To
78
- (v) => v.toISOString(),
79
- // From
80
- (v) => new Date(v)
81
- ),
82
- createSerializer(
83
- // Key
84
- "error",
85
- // Check
86
- (v) => v instanceof Error,
87
- // To
88
- (v) => ({
89
- ...v,
90
- message: v.message,
91
- stack: process.env.NODE_ENV === "development" ? v.stack : void 0,
92
- cause: v.cause
93
- }),
94
- // From
95
- (v) => Object.assign(new Error(v.message), v)
96
- ),
97
- createSerializer(
98
- // Key
99
- "formData",
100
- // Check
101
- (v) => v instanceof FormData,
102
- // To
103
- (v) => {
104
- const entries = {};
105
- v.forEach((value, key) => {
106
- const entry = entries[key];
107
- if (entry !== void 0) {
108
- if (Array.isArray(entry)) {
109
- entry.push(value);
110
- } else {
111
- entries[key] = [entry, value];
112
- }
113
- } else {
114
- entries[key] = value;
115
- }
116
- });
117
- return entries;
118
- },
119
- // From
120
- (v) => {
121
- const formData = new FormData();
122
- Object.entries(v).forEach(([key, value]) => {
123
- if (Array.isArray(value)) {
124
- value.forEach((val) => formData.append(key, val));
125
- } else {
126
- formData.append(key, value);
127
- }
128
- });
129
- return formData;
130
- }
131
- ),
132
- createSerializer(
133
- // Key
134
- "bigint",
135
- // Check
136
- (v) => typeof v === "bigint",
137
- // To
138
- (v) => v.toString(),
139
- // From
140
- (v) => BigInt(v)
141
- )
142
- ];
143
- export {
144
- tsrSerializer
145
- };
146
- //# sourceMappingURL=serializer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serializer.js","sources":["../../src/serializer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface TsrSerializer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n encode: <T>(value: T) => T\n decode: <T>(value: T) => T\n}\n\n/**\n * @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.\n */\nexport interface StartSerializer extends TsrSerializer {}\n\nexport type SerializerStringifyBy<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : { [K in keyof T]: SerializerStringifyBy<T[K], TSerializable> }\n\nexport type SerializerParseBy<T, TSerializable> = T extends TSerializable\n ? T\n : unknown extends SerializerExtensions['ReadableStream']\n ? { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }\n : T extends SerializerExtensions['ReadableStream']\n ? ReadableStream\n : { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }\n\nexport interface DefaultSerializerExtensions {\n ReadableStream: unknown\n}\n\nexport interface SerializerExtensions extends DefaultSerializerExtensions {}\n\nexport type Serializable = Date | undefined | Error | FormData | bigint\n\nexport type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>\n\nexport type SerializerParse<T> = SerializerParseBy<T, Serializable>\nexport const tsrSerializer: TsrSerializer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key, val) {\n const ogVal = this[key]\n const serializer = serializers.find((t) => t.stringifyCondition(ogVal))\n\n if (serializer) {\n return serializer.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 serializer = serializers.find((t) => t.parseCondition(ogVal))\n\n if (serializer) {\n return serializer.parse(ogVal)\n }\n }\n\n return val\n }),\n encode: (value: any) => {\n // When encoding, dive first\n if (Array.isArray(value)) {\n return value.map((v) => tsrSerializer.encode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [key, tsrSerializer.encode(v)]),\n )\n }\n\n const serializer = serializers.find((t) => t.stringifyCondition(value))\n if (serializer) {\n return serializer.stringify(value)\n }\n\n return value\n },\n decode: (value: any) => {\n // Attempt transform first\n if (isPlainObject(value)) {\n const serializer = serializers.find((t) => t.parseCondition(value))\n if (serializer) {\n return serializer.parse(value)\n }\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => tsrSerializer.decode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [key, tsrSerializer.decode(v)]),\n )\n }\n\n return value\n },\n}\nconst createSerializer = <TKey extends string, TInput, TSerialized>(\n key: TKey,\n check: (value: any) => value is TInput,\n toValue: (value: TInput) => TSerialized,\n fromValue: (value: TSerialized) => TInput,\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// Keep these ordered by predicted frequency\n// Make sure to keep DefaultSerializable in sync with these serializers\n// Also, make sure that they are unit tested in serializer.test.tsx\nconst serializers = [\n createSerializer(\n // Key\n 'undefined',\n // Check\n (v): v is undefined => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createSerializer(\n // Key\n 'date',\n // Check\n (v): v is Date => v instanceof Date,\n // To\n (v) => v.toISOString(),\n // From\n (v) => new Date(v),\n ),\n createSerializer(\n // Key\n 'error',\n // Check\n (v): v is Error => v instanceof Error,\n // To\n (v) => ({\n ...v,\n message: v.message,\n stack: process.env.NODE_ENV === 'development' ? v.stack : undefined,\n cause: v.cause,\n }),\n // From\n (v) => Object.assign(new Error(v.message), v),\n ),\n createSerializer(\n // Key\n 'formData',\n // Check\n (v): v is FormData => v instanceof FormData,\n // To\n (v) => {\n const entries: Record<\n string,\n Array<FormDataEntryValue> | FormDataEntryValue\n > = {}\n v.forEach((value, key) => {\n const entry = entries[key]\n if (entry !== undefined) {\n if (Array.isArray(entry)) {\n entry.push(value)\n } else {\n entries[key] = [entry, value]\n }\n } else {\n entries[key] = value\n }\n })\n return entries\n },\n // From\n (v) => {\n const formData = new FormData()\n Object.entries(v).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((val) => formData.append(key, val))\n } else {\n formData.append(key, value)\n }\n })\n return formData\n },\n ),\n createSerializer(\n // Key\n 'bigint',\n // Check\n (v): v is bigint => typeof v === 'bigint',\n // To\n (v) => v.toString(),\n // From\n (v) => BigInt(v),\n ),\n] as const\n"],"names":[],"mappings":"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"}
package/src/serializer.ts DELETED
@@ -1,205 +0,0 @@
1
- import { isPlainObject } from './utils'
2
-
3
- export interface TsrSerializer {
4
- stringify: (obj: unknown) => string
5
- parse: (str: string) => unknown
6
- encode: <T>(value: T) => T
7
- decode: <T>(value: T) => T
8
- }
9
-
10
- /**
11
- * @deprecated This is re-export of TsrSerializer which is the generic Router serializer interface. Going forward StartSerializer will be used specifically as a Tanstack Start serializer interface.
12
- */
13
- export interface StartSerializer extends TsrSerializer {}
14
-
15
- export type SerializerStringifyBy<T, TSerializable> = T extends TSerializable
16
- ? T
17
- : T extends (...args: Array<any>) => any
18
- ? 'Function is not serializable'
19
- : { [K in keyof T]: SerializerStringifyBy<T[K], TSerializable> }
20
-
21
- export type SerializerParseBy<T, TSerializable> = T extends TSerializable
22
- ? T
23
- : unknown extends SerializerExtensions['ReadableStream']
24
- ? { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }
25
- : T extends SerializerExtensions['ReadableStream']
26
- ? ReadableStream
27
- : { [K in keyof T]: SerializerParseBy<T[K], TSerializable> }
28
-
29
- export interface DefaultSerializerExtensions {
30
- ReadableStream: unknown
31
- }
32
-
33
- export interface SerializerExtensions extends DefaultSerializerExtensions {}
34
-
35
- export type Serializable = Date | undefined | Error | FormData | bigint
36
-
37
- export type SerializerStringify<T> = SerializerStringifyBy<T, Serializable>
38
-
39
- export type SerializerParse<T> = SerializerParseBy<T, Serializable>
40
- export const tsrSerializer: TsrSerializer = {
41
- stringify: (value: any) =>
42
- JSON.stringify(value, function replacer(key, val) {
43
- const ogVal = this[key]
44
- const serializer = serializers.find((t) => t.stringifyCondition(ogVal))
45
-
46
- if (serializer) {
47
- return serializer.stringify(ogVal)
48
- }
49
-
50
- return val
51
- }),
52
- parse: (value: string) =>
53
- JSON.parse(value, function parser(key, val) {
54
- const ogVal = this[key]
55
- if (isPlainObject(ogVal)) {
56
- const serializer = serializers.find((t) => t.parseCondition(ogVal))
57
-
58
- if (serializer) {
59
- return serializer.parse(ogVal)
60
- }
61
- }
62
-
63
- return val
64
- }),
65
- encode: (value: any) => {
66
- // When encoding, dive first
67
- if (Array.isArray(value)) {
68
- return value.map((v) => tsrSerializer.encode(v))
69
- }
70
-
71
- if (isPlainObject(value)) {
72
- return Object.fromEntries(
73
- Object.entries(value).map(([key, v]) => [key, tsrSerializer.encode(v)]),
74
- )
75
- }
76
-
77
- const serializer = serializers.find((t) => t.stringifyCondition(value))
78
- if (serializer) {
79
- return serializer.stringify(value)
80
- }
81
-
82
- return value
83
- },
84
- decode: (value: any) => {
85
- // Attempt transform first
86
- if (isPlainObject(value)) {
87
- const serializer = serializers.find((t) => t.parseCondition(value))
88
- if (serializer) {
89
- return serializer.parse(value)
90
- }
91
- }
92
-
93
- if (Array.isArray(value)) {
94
- return value.map((v) => tsrSerializer.decode(v))
95
- }
96
-
97
- if (isPlainObject(value)) {
98
- return Object.fromEntries(
99
- Object.entries(value).map(([key, v]) => [key, tsrSerializer.decode(v)]),
100
- )
101
- }
102
-
103
- return value
104
- },
105
- }
106
- const createSerializer = <TKey extends string, TInput, TSerialized>(
107
- key: TKey,
108
- check: (value: any) => value is TInput,
109
- toValue: (value: TInput) => TSerialized,
110
- fromValue: (value: TSerialized) => TInput,
111
- ) => ({
112
- key,
113
- stringifyCondition: check,
114
- stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),
115
- parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),
116
- parse: (value: any) => fromValue(value[`$${key}`]),
117
- })
118
- // Keep these ordered by predicted frequency
119
- // Make sure to keep DefaultSerializable in sync with these serializers
120
- // Also, make sure that they are unit tested in serializer.test.tsx
121
- const serializers = [
122
- createSerializer(
123
- // Key
124
- 'undefined',
125
- // Check
126
- (v): v is undefined => v === undefined,
127
- // To
128
- () => 0,
129
- // From
130
- () => undefined,
131
- ),
132
- createSerializer(
133
- // Key
134
- 'date',
135
- // Check
136
- (v): v is Date => v instanceof Date,
137
- // To
138
- (v) => v.toISOString(),
139
- // From
140
- (v) => new Date(v),
141
- ),
142
- createSerializer(
143
- // Key
144
- 'error',
145
- // Check
146
- (v): v is Error => v instanceof Error,
147
- // To
148
- (v) => ({
149
- ...v,
150
- message: v.message,
151
- stack: process.env.NODE_ENV === 'development' ? v.stack : undefined,
152
- cause: v.cause,
153
- }),
154
- // From
155
- (v) => Object.assign(new Error(v.message), v),
156
- ),
157
- createSerializer(
158
- // Key
159
- 'formData',
160
- // Check
161
- (v): v is FormData => v instanceof FormData,
162
- // To
163
- (v) => {
164
- const entries: Record<
165
- string,
166
- Array<FormDataEntryValue> | FormDataEntryValue
167
- > = {}
168
- v.forEach((value, key) => {
169
- const entry = entries[key]
170
- if (entry !== undefined) {
171
- if (Array.isArray(entry)) {
172
- entry.push(value)
173
- } else {
174
- entries[key] = [entry, value]
175
- }
176
- } else {
177
- entries[key] = value
178
- }
179
- })
180
- return entries
181
- },
182
- // From
183
- (v) => {
184
- const formData = new FormData()
185
- Object.entries(v).forEach(([key, value]) => {
186
- if (Array.isArray(value)) {
187
- value.forEach((val) => formData.append(key, val))
188
- } else {
189
- formData.append(key, value)
190
- }
191
- })
192
- return formData
193
- },
194
- ),
195
- createSerializer(
196
- // Key
197
- 'bigint',
198
- // Check
199
- (v): v is bigint => typeof v === 'bigint',
200
- // To
201
- (v) => v.toString(),
202
- // From
203
- (v) => BigInt(v),
204
- ),
205
- ] as const