@tanstack/router-core 1.132.0-alpha.1 → 1.132.0-alpha.12
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/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +9 -11
- package/dist/cjs/config.cjs +10 -0
- package/dist/cjs/config.cjs.map +1 -0
- package/dist/cjs/config.d.cts +17 -0
- package/dist/cjs/fileRoute.d.cts +3 -2
- package/dist/cjs/index.cjs +10 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +8 -3
- package/dist/cjs/load-matches.cjs +636 -0
- package/dist/cjs/load-matches.cjs.map +1 -0
- package/dist/cjs/load-matches.d.cts +16 -0
- package/dist/cjs/qss.cjs +19 -19
- package/dist/cjs/qss.cjs.map +1 -1
- package/dist/cjs/qss.d.cts +6 -4
- package/dist/cjs/redirect.cjs +3 -3
- package/dist/cjs/redirect.cjs.map +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +42 -41
- package/dist/cjs/router.cjs +85 -654
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +19 -23
- package/dist/cjs/scroll-restoration.cjs +32 -29
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/scroll-restoration.d.cts +1 -10
- package/dist/cjs/searchParams.cjs +7 -15
- package/dist/cjs/searchParams.cjs.map +1 -1
- package/dist/cjs/ssr/constants.cjs +5 -0
- package/dist/cjs/ssr/constants.cjs.map +1 -0
- package/dist/cjs/ssr/constants.d.cts +1 -0
- package/dist/cjs/ssr/{seroval-plugins.cjs → serializer/ShallowErrorPlugin.cjs} +2 -2
- package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -0
- package/dist/cjs/ssr/{seroval-plugins.d.cts → serializer/ShallowErrorPlugin.d.cts} +1 -2
- package/dist/cjs/ssr/serializer/seroval-plugins.cjs +11 -0
- package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -0
- package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -0
- package/dist/cjs/ssr/serializer/transformer.cjs +52 -0
- package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -0
- package/dist/cjs/ssr/serializer/transformer.d.cts +56 -0
- package/dist/cjs/ssr/server.d.cts +5 -0
- package/dist/cjs/ssr/ssr-client.cjs +53 -40
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.d.cts +5 -1
- package/dist/cjs/ssr/ssr-server.cjs +12 -10
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.d.cts +0 -1
- package/dist/cjs/ssr/tsrScript.cjs +1 -1
- package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
- package/dist/cjs/typePrimitives.d.cts +6 -6
- package/dist/cjs/utils.cjs +14 -7
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +2 -1
- package/dist/esm/Matches.d.ts +9 -11
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/config.d.ts +17 -0
- package/dist/esm/config.js +10 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/fileRoute.d.ts +3 -2
- package/dist/esm/index.d.ts +8 -3
- package/dist/esm/index.js +11 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/load-matches.d.ts +16 -0
- package/dist/esm/load-matches.js +636 -0
- package/dist/esm/load-matches.js.map +1 -0
- package/dist/esm/qss.d.ts +6 -4
- package/dist/esm/qss.js +19 -19
- package/dist/esm/qss.js.map +1 -1
- package/dist/esm/redirect.js +3 -3
- package/dist/esm/redirect.js.map +1 -1
- package/dist/esm/route.d.ts +42 -41
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.d.ts +19 -23
- package/dist/esm/router.js +85 -654
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.d.ts +1 -10
- package/dist/esm/scroll-restoration.js +32 -29
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/searchParams.js +7 -15
- package/dist/esm/searchParams.js.map +1 -1
- package/dist/esm/ssr/constants.d.ts +1 -0
- package/dist/esm/ssr/constants.js +5 -0
- package/dist/esm/ssr/constants.js.map +1 -0
- package/dist/esm/ssr/{seroval-plugins.d.ts → serializer/ShallowErrorPlugin.d.ts} +1 -2
- package/dist/esm/ssr/{seroval-plugins.js → serializer/ShallowErrorPlugin.js} +2 -2
- package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -0
- package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -0
- package/dist/esm/ssr/serializer/seroval-plugins.js +11 -0
- package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -0
- package/dist/esm/ssr/serializer/transformer.d.ts +56 -0
- package/dist/esm/ssr/serializer/transformer.js +52 -0
- package/dist/esm/ssr/serializer/transformer.js.map +1 -0
- package/dist/esm/ssr/server.d.ts +5 -0
- package/dist/esm/ssr/ssr-client.d.ts +5 -1
- package/dist/esm/ssr/ssr-client.js +53 -40
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.d.ts +0 -1
- package/dist/esm/ssr/ssr-server.js +12 -10
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/tsrScript.js +1 -1
- package/dist/esm/ssr/tsrScript.js.map +1 -1
- package/dist/esm/typePrimitives.d.ts +6 -6
- package/dist/esm/utils.d.ts +2 -1
- package/dist/esm/utils.js +14 -7
- package/dist/esm/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.ts +18 -10
- package/src/config.ts +42 -0
- package/src/fileRoute.ts +15 -3
- package/src/index.ts +24 -2
- package/src/load-matches.ts +955 -0
- package/src/qss.ts +27 -24
- package/src/redirect.ts +3 -3
- package/src/route.ts +146 -35
- package/src/router.ts +135 -925
- package/src/scroll-restoration.ts +42 -37
- package/src/searchParams.ts +8 -19
- package/src/ssr/constants.ts +1 -0
- package/src/ssr/{seroval-plugins.ts → serializer/ShallowErrorPlugin.ts} +2 -2
- package/src/ssr/serializer/seroval-plugins.ts +9 -0
- package/src/ssr/serializer/transformer.ts +215 -0
- package/src/ssr/server.ts +6 -0
- package/src/ssr/ssr-client.ts +72 -44
- package/src/ssr/ssr-server.ts +18 -10
- package/src/ssr/tsrScript.ts +5 -1
- package/src/typePrimitives.ts +6 -6
- package/src/utils.ts +21 -10
- package/dist/cjs/ssr/seroval-plugins.cjs.map +0 -1
- package/dist/esm/ssr/seroval-plugins.js.map +0 -1
|
@@ -28,7 +28,7 @@ function getSafeSessionStorage() {
|
|
|
28
28
|
return window.sessionStorage
|
|
29
29
|
}
|
|
30
30
|
} catch {
|
|
31
|
-
|
|
31
|
+
// silent
|
|
32
32
|
}
|
|
33
33
|
return undefined
|
|
34
34
|
}
|
|
@@ -47,10 +47,10 @@ const throttle = (fn: (...args: Array<any>) => void, wait: number) => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
function createScrollRestorationCache(): ScrollRestorationCache |
|
|
50
|
+
function createScrollRestorationCache(): ScrollRestorationCache | null {
|
|
51
51
|
const safeSessionStorage = getSafeSessionStorage()
|
|
52
52
|
if (!safeSessionStorage) {
|
|
53
|
-
return
|
|
53
|
+
return null
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const persistedState = safeSessionStorage.getItem(storageKey)
|
|
@@ -85,14 +85,14 @@ export const defaultGetScrollRestorationKey = (location: ParsedLocation) => {
|
|
|
85
85
|
|
|
86
86
|
export function getCssSelector(el: any): string {
|
|
87
87
|
const path = []
|
|
88
|
-
let parent
|
|
88
|
+
let parent: HTMLElement
|
|
89
89
|
while ((parent = el.parentNode)) {
|
|
90
|
-
path.
|
|
91
|
-
`${el.tagName}:nth-child(${
|
|
90
|
+
path.push(
|
|
91
|
+
`${el.tagName}:nth-child(${Array.prototype.indexOf.call(parent.children, el) + 1})`,
|
|
92
92
|
)
|
|
93
93
|
el = parent
|
|
94
94
|
}
|
|
95
|
-
return `${path.join(' > ')}`.toLowerCase()
|
|
95
|
+
return `${path.reverse().join(' > ')}`.toLowerCase()
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
let ignoreScroll = false
|
|
@@ -120,19 +120,19 @@ export function restoreScroll({
|
|
|
120
120
|
|
|
121
121
|
try {
|
|
122
122
|
byKey = JSON.parse(sessionStorage.getItem(storageKey) || '{}')
|
|
123
|
-
} catch (error
|
|
123
|
+
} catch (error) {
|
|
124
124
|
console.error(error)
|
|
125
125
|
return
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
const resolvedKey = key || window.history.state?.
|
|
128
|
+
const resolvedKey = key || window.history.state?.__TSR_key
|
|
129
129
|
const elementEntries = byKey[resolvedKey]
|
|
130
130
|
|
|
131
131
|
//
|
|
132
132
|
ignoreScroll = true
|
|
133
133
|
|
|
134
134
|
//
|
|
135
|
-
|
|
135
|
+
scroll: {
|
|
136
136
|
// If we have a cached entry for this location state,
|
|
137
137
|
// we always need to prefer that over the hash scroll.
|
|
138
138
|
if (
|
|
@@ -157,18 +157,18 @@ export function restoreScroll({
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
break scroll
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// If we don't have a cached entry for the hash,
|
|
164
164
|
// Which means we've never seen this location before,
|
|
165
165
|
// we need to check if there is a hash in the URL.
|
|
166
166
|
// If there is, we need to scroll it's ID into view.
|
|
167
|
-
const hash = (location ?? window.location).hash.split('#')[1]
|
|
167
|
+
const hash = (location ?? window.location).hash.split('#', 2)[1]
|
|
168
168
|
|
|
169
169
|
if (hash) {
|
|
170
170
|
const hashScrollIntoViewOptions =
|
|
171
|
-
|
|
171
|
+
window.history.state?.__hashScrollIntoViewOptions ?? true
|
|
172
172
|
|
|
173
173
|
if (hashScrollIntoViewOptions) {
|
|
174
174
|
const el = document.getElementById(hash)
|
|
@@ -177,37 +177,31 @@ export function restoreScroll({
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
break scroll
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
// If there is no cached entry for the hash and there is no hash in the URL,
|
|
184
184
|
// we need to scroll to the top of the page for every scrollToTop element
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
: typeof selector === 'function'
|
|
185
|
+
const scrollOptions = { top: 0, left: 0, behavior }
|
|
186
|
+
window.scrollTo(scrollOptions)
|
|
187
|
+
if (scrollToTopSelectors) {
|
|
188
|
+
for (const selector of scrollToTopSelectors) {
|
|
189
|
+
if (selector === 'window') continue
|
|
190
|
+
const element =
|
|
191
|
+
typeof selector === 'function'
|
|
193
192
|
? selector()
|
|
194
193
|
: document.querySelector(selector)
|
|
195
|
-
|
|
196
|
-
element.scrollTo({
|
|
197
|
-
top: 0,
|
|
198
|
-
left: 0,
|
|
199
|
-
behavior,
|
|
200
|
-
})
|
|
194
|
+
if (element) element.scrollTo(scrollOptions)
|
|
201
195
|
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
204
198
|
|
|
205
199
|
//
|
|
206
200
|
ignoreScroll = false
|
|
207
201
|
}
|
|
208
202
|
|
|
209
203
|
export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
|
|
210
|
-
if (scrollRestorationCache
|
|
204
|
+
if (!scrollRestorationCache && !router.isServer) {
|
|
211
205
|
return
|
|
212
206
|
}
|
|
213
207
|
const shouldScrollRestoration =
|
|
@@ -217,7 +211,11 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
|
|
|
217
211
|
router.isScrollRestoring = true
|
|
218
212
|
}
|
|
219
213
|
|
|
220
|
-
if (
|
|
214
|
+
if (
|
|
215
|
+
router.isServer ||
|
|
216
|
+
router.isScrollRestorationSetup ||
|
|
217
|
+
!scrollRestorationCache
|
|
218
|
+
) {
|
|
221
219
|
return
|
|
222
220
|
}
|
|
223
221
|
|
|
@@ -294,11 +292,10 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
|
|
|
294
292
|
const restoreKey = getKey(router.state.location)
|
|
295
293
|
|
|
296
294
|
scrollRestorationCache.set((state) => {
|
|
297
|
-
const keyEntry = (state[restoreKey]
|
|
298
|
-
state[restoreKey] || ({} as ScrollRestorationByElement))
|
|
295
|
+
const keyEntry = (state[restoreKey] ||= {} as ScrollRestorationByElement)
|
|
299
296
|
|
|
300
|
-
const elementEntry = (keyEntry[elementSelector]
|
|
301
|
-
|
|
297
|
+
const elementEntry = (keyEntry[elementSelector] ||=
|
|
298
|
+
{} as ScrollRestorationEntry)
|
|
302
299
|
|
|
303
300
|
if (elementSelector === 'window') {
|
|
304
301
|
elementEntry.scrollX = window.scrollX || 0
|
|
@@ -331,6 +328,14 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
|
|
|
331
328
|
router.resetNextScroll = true
|
|
332
329
|
return
|
|
333
330
|
}
|
|
331
|
+
if (typeof router.options.scrollRestoration === 'function') {
|
|
332
|
+
const shouldRestore = router.options.scrollRestoration({
|
|
333
|
+
location: router.latestLocation,
|
|
334
|
+
})
|
|
335
|
+
if (!shouldRestore) {
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
}
|
|
334
339
|
|
|
335
340
|
restoreScroll({
|
|
336
341
|
storageKey,
|
|
@@ -344,7 +349,7 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
|
|
|
344
349
|
if (router.isScrollRestoring) {
|
|
345
350
|
// Mark the location as having been seen
|
|
346
351
|
scrollRestorationCache.set((state) => {
|
|
347
|
-
state[cacheKey]
|
|
352
|
+
state[cacheKey] ||= {} as ScrollRestorationByElement
|
|
348
353
|
|
|
349
354
|
return state
|
|
350
355
|
})
|
package/src/searchParams.ts
CHANGED
|
@@ -9,7 +9,7 @@ export const defaultStringifySearch = stringifySearchWith(
|
|
|
9
9
|
|
|
10
10
|
export function parseSearchWith(parser: (str: string) => any) {
|
|
11
11
|
return (searchStr: string): AnySchema => {
|
|
12
|
-
if (searchStr
|
|
12
|
+
if (searchStr[0] === '?') {
|
|
13
13
|
searchStr = searchStr.substring(1)
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -21,8 +21,8 @@ export function parseSearchWith(parser: (str: string) => any) {
|
|
|
21
21
|
if (typeof value === 'string') {
|
|
22
22
|
try {
|
|
23
23
|
query[key] = parser(value)
|
|
24
|
-
} catch (
|
|
25
|
-
//
|
|
24
|
+
} catch (_err) {
|
|
25
|
+
// silent
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -35,20 +35,21 @@ export function stringifySearchWith(
|
|
|
35
35
|
stringify: (search: any) => string,
|
|
36
36
|
parser?: (str: string) => any,
|
|
37
37
|
) {
|
|
38
|
+
const hasParser = typeof parser === 'function'
|
|
38
39
|
function stringifyValue(val: any) {
|
|
39
40
|
if (typeof val === 'object' && val !== null) {
|
|
40
41
|
try {
|
|
41
42
|
return stringify(val)
|
|
42
|
-
} catch (
|
|
43
|
+
} catch (_err) {
|
|
43
44
|
// silent
|
|
44
45
|
}
|
|
45
|
-
} else if (
|
|
46
|
+
} else if (hasParser && typeof val === 'string') {
|
|
46
47
|
try {
|
|
47
48
|
// Check if it's a valid parseable string.
|
|
48
49
|
// If it is, then stringify it again.
|
|
49
50
|
parser(val)
|
|
50
51
|
return stringify(val)
|
|
51
|
-
} catch (
|
|
52
|
+
} catch (_err) {
|
|
52
53
|
// silent
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -56,19 +57,7 @@ export function stringifySearchWith(
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
return (search: Record<string, any>) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Object.keys(search).forEach((key) => {
|
|
62
|
-
const val = search[key]
|
|
63
|
-
if (typeof val === 'undefined' || val === undefined) {
|
|
64
|
-
delete search[key]
|
|
65
|
-
} else {
|
|
66
|
-
search[key] = stringifyValue(val)
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
const searchStr = encode(search as Record<string, string>).toString()
|
|
71
|
-
|
|
60
|
+
const searchStr = encode(search, stringifyValue)
|
|
72
61
|
return searchStr ? `?${searchStr}` : ''
|
|
73
62
|
}
|
|
74
63
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const GLOBAL_TSR = '$_TSR'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createPlugin } from 'seroval'
|
|
2
2
|
import type { SerovalNode } from 'seroval'
|
|
3
3
|
|
|
4
|
-
interface ErrorNode {
|
|
4
|
+
export interface ErrorNode {
|
|
5
5
|
message: SerovalNode
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ export const ShallowErrorPlugin = /* @__PURE__ */ createPlugin<
|
|
|
13
13
|
Error,
|
|
14
14
|
ErrorNode
|
|
15
15
|
>({
|
|
16
|
-
tag: '
|
|
16
|
+
tag: '$TSR/Error',
|
|
17
17
|
test(value) {
|
|
18
18
|
return value instanceof Error
|
|
19
19
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ReadableStreamPlugin } from 'seroval-plugins/web'
|
|
2
|
+
import { ShallowErrorPlugin } from './ShallowErrorPlugin'
|
|
3
|
+
import type { Plugin } from 'seroval'
|
|
4
|
+
|
|
5
|
+
export const defaultSerovalPlugins = [
|
|
6
|
+
ShallowErrorPlugin as Plugin<Error, any>,
|
|
7
|
+
// ReadableStreamNode is not exported by seroval
|
|
8
|
+
ReadableStreamPlugin as Plugin<ReadableStream, any>,
|
|
9
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { createPlugin } from 'seroval'
|
|
2
|
+
import { GLOBAL_TSR } from '../constants'
|
|
3
|
+
import type { Plugin, SerovalNode } from 'seroval'
|
|
4
|
+
import type { Register, SSROption } from '../../router'
|
|
5
|
+
import type { LooseReturnType } from '../../utils'
|
|
6
|
+
import type { AnyRoute, ResolveAllSSR } from '../../route'
|
|
7
|
+
|
|
8
|
+
export type Serializable =
|
|
9
|
+
| number
|
|
10
|
+
| string
|
|
11
|
+
| boolean
|
|
12
|
+
| null
|
|
13
|
+
| undefined
|
|
14
|
+
| bigint
|
|
15
|
+
| Date
|
|
16
|
+
|
|
17
|
+
export function createSerializationAdapter<
|
|
18
|
+
TInput = unknown,
|
|
19
|
+
TOutput = unknown /* we need to check that this type is actually serializable taking into account all seroval native types and any custom plugin WE=router/start add!!! */,
|
|
20
|
+
>(
|
|
21
|
+
opts: CreateSerializationAdapterOptions<TInput, TOutput>,
|
|
22
|
+
): SerializationAdapter<TInput, TOutput> {
|
|
23
|
+
return opts as unknown as SerializationAdapter<TInput, TOutput>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CreateSerializationAdapterOptions<TInput, TOutput> {
|
|
27
|
+
key: string
|
|
28
|
+
test: (value: unknown) => value is TInput
|
|
29
|
+
toSerializable: (value: TInput) => ValidateSerializable<TOutput, Serializable>
|
|
30
|
+
fromSerializable: (value: TOutput) => TInput
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type ValidateSerializable<T, TSerializable> = T extends TSerializable
|
|
34
|
+
? T
|
|
35
|
+
: T extends (...args: Array<any>) => any
|
|
36
|
+
? 'Function is not serializable'
|
|
37
|
+
: T extends Promise<any>
|
|
38
|
+
? ValidateSerializablePromise<T, TSerializable>
|
|
39
|
+
: T extends ReadableStream<any>
|
|
40
|
+
? ValidateReadableStream<T, TSerializable>
|
|
41
|
+
: T extends Set<any>
|
|
42
|
+
? ValidateSerializableSet<T, TSerializable>
|
|
43
|
+
: T extends Map<any, any>
|
|
44
|
+
? ValidateSerializableMap<T, TSerializable>
|
|
45
|
+
: {
|
|
46
|
+
[K in keyof T]: ValidateSerializable<T[K], TSerializable>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type ValidateSerializablePromise<T, TSerializable> =
|
|
50
|
+
T extends Promise<infer TAwaited>
|
|
51
|
+
? Promise<ValidateSerializable<TAwaited, TSerializable>>
|
|
52
|
+
: never
|
|
53
|
+
|
|
54
|
+
export type ValidateReadableStream<T, TSerializable> =
|
|
55
|
+
T extends ReadableStream<infer TStreamed>
|
|
56
|
+
? ReadableStream<ValidateSerializable<TStreamed, TSerializable>>
|
|
57
|
+
: never
|
|
58
|
+
|
|
59
|
+
export type ValidateSerializableSet<T, TSerializable> =
|
|
60
|
+
T extends Set<infer TItem>
|
|
61
|
+
? Set<ValidateSerializable<TItem, TSerializable>>
|
|
62
|
+
: never
|
|
63
|
+
|
|
64
|
+
export type ValidateSerializableMap<T, TSerializable> =
|
|
65
|
+
T extends Map<infer TKey, infer TValue>
|
|
66
|
+
? Map<
|
|
67
|
+
ValidateSerializable<TKey, TSerializable>,
|
|
68
|
+
ValidateSerializable<TValue, TSerializable>
|
|
69
|
+
>
|
|
70
|
+
: never
|
|
71
|
+
|
|
72
|
+
export type RegisteredReadableStream =
|
|
73
|
+
unknown extends SerializerExtensions['ReadableStream']
|
|
74
|
+
? never
|
|
75
|
+
: SerializerExtensions['ReadableStream']
|
|
76
|
+
|
|
77
|
+
export interface DefaultSerializerExtensions {
|
|
78
|
+
ReadableStream: unknown
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface SerializerExtensions extends DefaultSerializerExtensions {}
|
|
82
|
+
|
|
83
|
+
export interface SerializationAdapter<TInput, TOutput> {
|
|
84
|
+
'~types': SerializationAdapterTypes<TInput, TOutput>
|
|
85
|
+
key: string
|
|
86
|
+
test: (value: unknown) => value is TInput
|
|
87
|
+
toSerializable: (value: TInput) => TOutput
|
|
88
|
+
fromSerializable: (value: TOutput) => TInput
|
|
89
|
+
makePlugin: (options: { didRun: boolean }) => Plugin<TInput, SerovalNode>
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SerializationAdapterTypes<TInput, TOutput> {
|
|
93
|
+
input: TInput
|
|
94
|
+
output: TOutput
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type AnySerializationAdapter = SerializationAdapter<any, any>
|
|
98
|
+
|
|
99
|
+
export function makeSsrSerovalPlugin<TInput, TOutput>(
|
|
100
|
+
serializationAdapter: SerializationAdapter<TInput, TOutput>,
|
|
101
|
+
options: { didRun: boolean },
|
|
102
|
+
) {
|
|
103
|
+
return createPlugin<TInput, SerovalNode>({
|
|
104
|
+
tag: '$TSR/t/' + serializationAdapter.key,
|
|
105
|
+
test: serializationAdapter.test,
|
|
106
|
+
parse: {
|
|
107
|
+
stream(value, ctx) {
|
|
108
|
+
return ctx.parse(serializationAdapter.toSerializable(value))
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
serialize(node, ctx) {
|
|
112
|
+
options.didRun = true
|
|
113
|
+
return (
|
|
114
|
+
GLOBAL_TSR +
|
|
115
|
+
'.t.get("' +
|
|
116
|
+
serializationAdapter.key +
|
|
117
|
+
'")(' +
|
|
118
|
+
ctx.serialize(node) +
|
|
119
|
+
')'
|
|
120
|
+
)
|
|
121
|
+
},
|
|
122
|
+
// we never deserialize on the server during SSR
|
|
123
|
+
deserialize: undefined as never,
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function makeSerovalPlugin<TInput, TOutput>(
|
|
128
|
+
serializationAdapter: SerializationAdapter<TInput, TOutput>,
|
|
129
|
+
) {
|
|
130
|
+
return createPlugin<TInput, SerovalNode>({
|
|
131
|
+
tag: '$TSR/t/' + serializationAdapter.key,
|
|
132
|
+
test: serializationAdapter.test,
|
|
133
|
+
parse: {
|
|
134
|
+
sync(value, ctx) {
|
|
135
|
+
return ctx.parse(serializationAdapter.toSerializable(value))
|
|
136
|
+
},
|
|
137
|
+
async async(value, ctx) {
|
|
138
|
+
return await ctx.parse(serializationAdapter.toSerializable(value))
|
|
139
|
+
},
|
|
140
|
+
stream(value, ctx) {
|
|
141
|
+
return ctx.parse(serializationAdapter.toSerializable(value))
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
// we don't generate JS code outside of SSR (for now)
|
|
145
|
+
serialize: undefined as never,
|
|
146
|
+
deserialize(node, ctx) {
|
|
147
|
+
return serializationAdapter.fromSerializable(
|
|
148
|
+
ctx.deserialize(node) as TOutput,
|
|
149
|
+
)
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export type ValidateSerializableInput<
|
|
155
|
+
TRegister extends Register,
|
|
156
|
+
T,
|
|
157
|
+
> = ValidateSerializable<T, RegisteredSerializableInput<TRegister>>
|
|
158
|
+
|
|
159
|
+
export type RegisteredSerializableInput<TRegister extends Register> =
|
|
160
|
+
| (unknown extends RegisteredSerializationAdapters<TRegister>
|
|
161
|
+
? never
|
|
162
|
+
: RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter>
|
|
163
|
+
? RegisteredSerializationAdapters<TRegister>[number]['~types']['input']
|
|
164
|
+
: never)
|
|
165
|
+
| Serializable
|
|
166
|
+
|
|
167
|
+
export type RegisteredSerializationAdapters<TRegister extends Register> =
|
|
168
|
+
TRegister['config']['~types']['serializationAdapters']
|
|
169
|
+
|
|
170
|
+
export type ValidateSerializableInputResult<
|
|
171
|
+
TRegister extends Register,
|
|
172
|
+
T,
|
|
173
|
+
> = ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>
|
|
174
|
+
|
|
175
|
+
export type ValidateSerializableResult<T, TSerializable> =
|
|
176
|
+
T extends TSerializable
|
|
177
|
+
? T
|
|
178
|
+
: unknown extends SerializerExtensions['ReadableStream']
|
|
179
|
+
? { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
|
|
180
|
+
: T extends SerializerExtensions['ReadableStream']
|
|
181
|
+
? ReadableStream
|
|
182
|
+
: { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
|
|
183
|
+
|
|
184
|
+
export type RegisteredSSROption<TRegister extends Register> =
|
|
185
|
+
unknown extends TRegister['config']['~types']['defaultSsr']
|
|
186
|
+
? SSROption
|
|
187
|
+
: TRegister['config']['~types']['defaultSsr']
|
|
188
|
+
|
|
189
|
+
export type ValidateSerializableLifecycleResult<
|
|
190
|
+
TRegister extends Register,
|
|
191
|
+
TParentRoute extends AnyRoute,
|
|
192
|
+
TSSR,
|
|
193
|
+
TFn,
|
|
194
|
+
> = false extends TRegister['ssr']
|
|
195
|
+
? any
|
|
196
|
+
: ValidateSerializableLifecycleResultSSR<
|
|
197
|
+
TRegister,
|
|
198
|
+
TParentRoute,
|
|
199
|
+
TSSR,
|
|
200
|
+
TFn
|
|
201
|
+
> extends infer TInput
|
|
202
|
+
? TInput
|
|
203
|
+
: never
|
|
204
|
+
|
|
205
|
+
export type ValidateSerializableLifecycleResultSSR<
|
|
206
|
+
TRegister extends Register,
|
|
207
|
+
TParentRoute extends AnyRoute,
|
|
208
|
+
TSSR,
|
|
209
|
+
TFn,
|
|
210
|
+
> =
|
|
211
|
+
ResolveAllSSR<TParentRoute, TSSR> extends false
|
|
212
|
+
? any
|
|
213
|
+
: RegisteredSSROption<TRegister> extends false
|
|
214
|
+
? any
|
|
215
|
+
: ValidateSerializableInput<TRegister, LooseReturnType<TFn>>
|
package/src/ssr/server.ts
CHANGED