@tanstack/start-client-core 1.120.4-alpha.19 → 1.120.4
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/README.md +27 -6
- package/dist/cjs/createMiddleware.cjs +5 -8
- package/dist/cjs/createMiddleware.cjs.map +1 -1
- package/dist/cjs/createMiddleware.d.cts +81 -125
- package/dist/cjs/createServerFn.cjs +0 -1
- package/dist/cjs/createServerFn.cjs.map +1 -1
- package/dist/cjs/createServerFn.d.cts +5 -6
- package/dist/cjs/index.cjs +0 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +2 -2
- package/dist/cjs/registerGlobalMiddleware.cjs.map +1 -1
- package/dist/cjs/registerGlobalMiddleware.d.cts +3 -3
- package/dist/cjs/ssr-client.cjs +25 -24
- package/dist/cjs/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr-client.d.cts +1 -2
- package/dist/esm/createMiddleware.d.ts +81 -125
- package/dist/esm/createMiddleware.js +5 -8
- package/dist/esm/createMiddleware.js.map +1 -1
- package/dist/esm/createServerFn.d.ts +5 -6
- package/dist/esm/createServerFn.js +0 -1
- package/dist/esm/createServerFn.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -2
- package/dist/esm/registerGlobalMiddleware.d.ts +3 -3
- package/dist/esm/registerGlobalMiddleware.js.map +1 -1
- package/dist/esm/ssr-client.d.ts +1 -2
- package/dist/esm/ssr-client.js +25 -24
- package/dist/esm/ssr-client.js.map +1 -1
- package/package.json +2 -2
- package/src/createMiddleware.ts +368 -479
- package/src/createServerFn.ts +16 -31
- package/src/index.tsx +21 -22
- package/src/registerGlobalMiddleware.ts +3 -3
- package/src/ssr-client.tsx +29 -33
- package/src/tests/createServerFn.test-d.ts +13 -20
- package/src/tests/createServerMiddleware.test-d.ts +73 -186
package/src/createServerFn.ts
CHANGED
|
@@ -16,17 +16,15 @@ import type {
|
|
|
16
16
|
} from '@tanstack/router-core'
|
|
17
17
|
import type { Readable } from 'node:stream'
|
|
18
18
|
import type {
|
|
19
|
-
|
|
19
|
+
AnyMiddleware,
|
|
20
20
|
AssignAllClientSendContext,
|
|
21
21
|
AssignAllServerContext,
|
|
22
|
-
FunctionMiddlewareClientFnResult,
|
|
23
|
-
FunctionMiddlewareServerFnResult,
|
|
24
22
|
IntersectAllValidatorInputs,
|
|
25
23
|
IntersectAllValidatorOutputs,
|
|
24
|
+
MiddlewareClientFnResult,
|
|
25
|
+
MiddlewareServerFnResult,
|
|
26
26
|
} from './createMiddleware'
|
|
27
27
|
|
|
28
|
-
type TODO = any
|
|
29
|
-
|
|
30
28
|
export function createServerFn<
|
|
31
29
|
TMethod extends Method,
|
|
32
30
|
TServerFnResponseType extends ServerFnResponseType = 'data',
|
|
@@ -217,8 +215,8 @@ export function createServerFn<
|
|
|
217
215
|
}
|
|
218
216
|
}
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
middlewares: Array<
|
|
218
|
+
async function executeMiddleware(
|
|
219
|
+
middlewares: Array<AnyMiddleware>,
|
|
222
220
|
env: 'client' | 'server',
|
|
223
221
|
opts: ServerFnMiddlewareOptions,
|
|
224
222
|
): Promise<ServerFnMiddlewareResult> {
|
|
@@ -400,7 +398,6 @@ export type ServerFnReturnType<
|
|
|
400
398
|
> = TServerFnResponseType extends 'raw'
|
|
401
399
|
? RawResponse | Promise<RawResponse>
|
|
402
400
|
: Promise<SerializerStringify<TResponse>> | SerializerStringify<TResponse>
|
|
403
|
-
|
|
404
401
|
export type ServerFn<
|
|
405
402
|
TMethod,
|
|
406
403
|
TServerFnResponseType extends ServerFnResponseType,
|
|
@@ -445,7 +442,7 @@ export type ServerFnBaseOptions<
|
|
|
445
442
|
method: TMethod
|
|
446
443
|
response?: TServerFnResponseType
|
|
447
444
|
validateClient?: boolean
|
|
448
|
-
middleware?: Constrain<TMiddlewares, ReadonlyArray<
|
|
445
|
+
middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyMiddleware>>
|
|
449
446
|
validator?: ConstrainValidator<TInput>
|
|
450
447
|
extractedFn?: CompiledFetcherFn<TResponse, TServerFnResponseType>
|
|
451
448
|
serverFn?: ServerFn<
|
|
@@ -488,10 +485,7 @@ export interface ServerFnMiddleware<
|
|
|
488
485
|
TValidator,
|
|
489
486
|
> {
|
|
490
487
|
middleware: <const TNewMiddlewares = undefined>(
|
|
491
|
-
middlewares: Constrain<
|
|
492
|
-
TNewMiddlewares,
|
|
493
|
-
ReadonlyArray<AnyFunctionMiddleware>
|
|
494
|
-
>,
|
|
488
|
+
middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyMiddleware>>,
|
|
495
489
|
) => ServerFnAfterMiddleware<
|
|
496
490
|
TMethod,
|
|
497
491
|
TServerFnResponseType,
|
|
@@ -818,12 +812,12 @@ export function extractFormDataContext(formData: FormData) {
|
|
|
818
812
|
}
|
|
819
813
|
|
|
820
814
|
export function flattenMiddlewares(
|
|
821
|
-
middlewares: Array<
|
|
822
|
-
): Array<
|
|
823
|
-
const seen = new Set<
|
|
824
|
-
const flattened: Array<
|
|
815
|
+
middlewares: Array<AnyMiddleware>,
|
|
816
|
+
): Array<AnyMiddleware> {
|
|
817
|
+
const seen = new Set<AnyMiddleware>()
|
|
818
|
+
const flattened: Array<AnyMiddleware> = []
|
|
825
819
|
|
|
826
|
-
const recurse = (middleware: Array<
|
|
820
|
+
const recurse = (middleware: Array<AnyMiddleware>) => {
|
|
827
821
|
middleware.forEach((m) => {
|
|
828
822
|
if (m.options.middleware) {
|
|
829
823
|
recurse(m.options.middleware)
|
|
@@ -935,7 +929,7 @@ export function execValidator(
|
|
|
935
929
|
|
|
936
930
|
export function serverFnBaseToMiddleware(
|
|
937
931
|
options: ServerFnBaseOptions<any, any, any, any, any>,
|
|
938
|
-
):
|
|
932
|
+
): AnyMiddleware {
|
|
939
933
|
return {
|
|
940
934
|
_types: undefined!,
|
|
941
935
|
options: {
|
|
@@ -979,25 +973,16 @@ export function serverFnBaseToMiddleware(
|
|
|
979
973
|
// but not before serializing the context
|
|
980
974
|
const res = await options.extractedFn?.(payload)
|
|
981
975
|
|
|
982
|
-
return next(res) as unknown as
|
|
983
|
-
any,
|
|
984
|
-
any,
|
|
985
|
-
any
|
|
986
|
-
>
|
|
976
|
+
return next(res) as unknown as MiddlewareClientFnResult<any, any, any>
|
|
987
977
|
},
|
|
988
978
|
server: async ({ next, ...ctx }) => {
|
|
989
979
|
// Execute the server function
|
|
990
|
-
const result = await options.serverFn?.(ctx
|
|
980
|
+
const result = await options.serverFn?.(ctx)
|
|
991
981
|
|
|
992
982
|
return next({
|
|
993
983
|
...ctx,
|
|
994
984
|
result,
|
|
995
|
-
} as any) as unknown as
|
|
996
|
-
any,
|
|
997
|
-
any,
|
|
998
|
-
any,
|
|
999
|
-
any
|
|
1000
|
-
>
|
|
985
|
+
} as any) as unknown as MiddlewareServerFnResult<any, any, any, any>
|
|
1001
986
|
},
|
|
1002
987
|
},
|
|
1003
988
|
}
|
package/src/index.tsx
CHANGED
|
@@ -25,30 +25,30 @@ export {
|
|
|
25
25
|
createMiddleware,
|
|
26
26
|
type IntersectAllValidatorInputs,
|
|
27
27
|
type IntersectAllValidatorOutputs,
|
|
28
|
-
type
|
|
29
|
-
type
|
|
30
|
-
type
|
|
31
|
-
type
|
|
32
|
-
type
|
|
33
|
-
type
|
|
34
|
-
type
|
|
35
|
-
type
|
|
36
|
-
type
|
|
37
|
-
type
|
|
38
|
-
type
|
|
39
|
-
type
|
|
40
|
-
type
|
|
28
|
+
type MiddlewareServerFn,
|
|
29
|
+
type AnyMiddleware,
|
|
30
|
+
type MiddlewareOptions,
|
|
31
|
+
type MiddlewareWithTypes,
|
|
32
|
+
type MiddlewareValidator,
|
|
33
|
+
type MiddlewareServer,
|
|
34
|
+
type MiddlewareAfterClient,
|
|
35
|
+
type MiddlewareAfterMiddleware,
|
|
36
|
+
type MiddlewareAfterServer,
|
|
37
|
+
type Middleware,
|
|
38
|
+
type MiddlewareClientFnOptions,
|
|
39
|
+
type MiddlewareClientFnResult,
|
|
40
|
+
type MiddlewareClientNextFn,
|
|
41
|
+
type ClientResultWithContext,
|
|
41
42
|
type AssignAllClientContextBeforeNext,
|
|
42
43
|
type AssignAllMiddleware,
|
|
43
44
|
type AssignAllServerContext,
|
|
44
|
-
type
|
|
45
|
-
type
|
|
46
|
-
type
|
|
47
|
-
type
|
|
48
|
-
type
|
|
49
|
-
type
|
|
50
|
-
type
|
|
51
|
-
type AnyRequestMiddleware,
|
|
45
|
+
type MiddlewareAfterValidator,
|
|
46
|
+
type MiddlewareClientFn,
|
|
47
|
+
type MiddlewareServerFnResult,
|
|
48
|
+
type MiddlewareClient,
|
|
49
|
+
type MiddlewareServerFnOptions,
|
|
50
|
+
type MiddlewareServerNextFn,
|
|
51
|
+
type ServerResultWithContext,
|
|
52
52
|
} from './createMiddleware'
|
|
53
53
|
export {
|
|
54
54
|
registerGlobalMiddleware,
|
|
@@ -84,5 +84,4 @@ export {
|
|
|
84
84
|
extractFormDataContext,
|
|
85
85
|
flattenMiddlewares,
|
|
86
86
|
serverFnStaticCache,
|
|
87
|
-
executeMiddleware,
|
|
88
87
|
} from './createServerFn'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AnyMiddleware } from './createMiddleware'
|
|
2
2
|
|
|
3
|
-
export const globalMiddleware: Array<
|
|
3
|
+
export const globalMiddleware: Array<AnyMiddleware> = []
|
|
4
4
|
|
|
5
5
|
export function registerGlobalMiddleware(options: {
|
|
6
|
-
middleware: Array<
|
|
6
|
+
middleware: Array<AnyMiddleware>
|
|
7
7
|
}) {
|
|
8
8
|
globalMiddleware.push(...options.middleware)
|
|
9
9
|
}
|
package/src/ssr-client.tsx
CHANGED
|
@@ -77,16 +77,15 @@ export interface ResolvePromiseState {
|
|
|
77
77
|
export interface DehydratedRouter {
|
|
78
78
|
manifest: Manifest | undefined
|
|
79
79
|
dehydratedData: any
|
|
80
|
-
lastMatchId: string
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
export
|
|
82
|
+
export function hydrate(router: AnyRouter) {
|
|
84
83
|
invariant(
|
|
85
84
|
window.__TSR_SSR__?.dehydrated,
|
|
86
85
|
'Expected to find a dehydrated data on window.__TSR_SSR__.dehydrated... but we did not. Please file an issue!',
|
|
87
86
|
)
|
|
88
87
|
|
|
89
|
-
const { manifest, dehydratedData
|
|
88
|
+
const { manifest, dehydratedData } = startSerializer.parse(
|
|
90
89
|
window.__TSR_SSR__.dehydrated,
|
|
91
90
|
) as DehydratedRouter
|
|
92
91
|
|
|
@@ -117,7 +116,6 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
117
116
|
|
|
118
117
|
// Hydrate the router state
|
|
119
118
|
const matches = router.matchRoutes(router.state.location)
|
|
120
|
-
|
|
121
119
|
// kick off loading the route chunks
|
|
122
120
|
const routeChunkPromise = Promise.all(
|
|
123
121
|
matches.map((match) => {
|
|
@@ -125,7 +123,6 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
125
123
|
return router.loadRouteChunk(route)
|
|
126
124
|
}),
|
|
127
125
|
)
|
|
128
|
-
|
|
129
126
|
// Right after hydration and before the first render, we need to rehydrate each match
|
|
130
127
|
// First step is to reyhdrate loaderData and __beforeLoadContext
|
|
131
128
|
matches.forEach((match) => {
|
|
@@ -133,36 +130,39 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
133
130
|
(d) => d.id === match.id,
|
|
134
131
|
)
|
|
135
132
|
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
}
|
|
133
|
+
if (dehydratedMatch) {
|
|
134
|
+
Object.assign(match, dehydratedMatch)
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
// Handle beforeLoadContext
|
|
137
|
+
if (dehydratedMatch.__beforeLoadContext) {
|
|
138
|
+
match.__beforeLoadContext = router.ssr!.serializer.parse(
|
|
139
|
+
dehydratedMatch.__beforeLoadContext,
|
|
140
|
+
) as any
|
|
141
|
+
}
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
// Handle loaderData
|
|
144
|
+
if (dehydratedMatch.loaderData) {
|
|
145
|
+
match.loaderData = router.ssr!.serializer.parse(
|
|
146
|
+
dehydratedMatch.loaderData,
|
|
147
|
+
)
|
|
148
|
+
}
|
|
148
149
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
}
|
|
150
|
+
// Handle error
|
|
151
|
+
if (dehydratedMatch.error) {
|
|
152
|
+
match.error = router.ssr!.serializer.parse(dehydratedMatch.error)
|
|
153
|
+
}
|
|
155
154
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
155
|
+
// Handle extracted
|
|
156
|
+
;(match as unknown as SsrMatch).extracted?.forEach((ex) => {
|
|
157
|
+
deepMutableSetByPath(match, ['loaderData', ...ex.path], ex.value)
|
|
158
|
+
})
|
|
159
|
+
} else {
|
|
160
|
+
Object.assign(match, {
|
|
161
|
+
status: 'success',
|
|
162
|
+
updatedAt: Date.now(),
|
|
163
|
+
})
|
|
159
164
|
}
|
|
160
165
|
|
|
161
|
-
// Handle extracted
|
|
162
|
-
;(match as unknown as SsrMatch).extracted?.forEach((ex) => {
|
|
163
|
-
deepMutableSetByPath(match, ['loaderData', ...ex.path], ex.value)
|
|
164
|
-
})
|
|
165
|
-
|
|
166
166
|
return match
|
|
167
167
|
})
|
|
168
168
|
|
|
@@ -224,10 +224,6 @@ export async function hydrate(router: AnyRouter): Promise<any> {
|
|
|
224
224
|
match.scripts = scripts
|
|
225
225
|
})
|
|
226
226
|
|
|
227
|
-
if (matches[matches.length - 1]!.id !== lastMatchId) {
|
|
228
|
-
return await Promise.all([routeChunkPromise, router.load()])
|
|
229
|
-
}
|
|
230
|
-
|
|
231
227
|
return routeChunkPromise
|
|
232
228
|
}
|
|
233
229
|
|
|
@@ -60,25 +60,21 @@ test('createServerFn with validator', () => {
|
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
test('createServerFn with middleware and context', () => {
|
|
63
|
-
const middleware1 = createMiddleware({
|
|
64
|
-
({
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
)
|
|
63
|
+
const middleware1 = createMiddleware().server(({ next }) => {
|
|
64
|
+
return next({ context: { a: 'a' } as const })
|
|
65
|
+
})
|
|
68
66
|
|
|
69
|
-
const middleware2 = createMiddleware({
|
|
70
|
-
({
|
|
71
|
-
|
|
72
|
-
},
|
|
73
|
-
)
|
|
67
|
+
const middleware2 = createMiddleware().server(({ next }) => {
|
|
68
|
+
return next({ context: { b: 'b' } as const })
|
|
69
|
+
})
|
|
74
70
|
|
|
75
|
-
const middleware3 = createMiddleware(
|
|
71
|
+
const middleware3 = createMiddleware()
|
|
76
72
|
.middleware([middleware1, middleware2])
|
|
77
73
|
.client(({ next }) => {
|
|
78
74
|
return next({ context: { c: 'c' } as const })
|
|
79
75
|
})
|
|
80
76
|
|
|
81
|
-
const middleware4 = createMiddleware(
|
|
77
|
+
const middleware4 = createMiddleware()
|
|
82
78
|
.middleware([middleware3])
|
|
83
79
|
.client(({ context, next }) => {
|
|
84
80
|
return next({ sendContext: context })
|
|
@@ -117,24 +113,21 @@ test('createServerFn with middleware and context', () => {
|
|
|
117
113
|
})
|
|
118
114
|
|
|
119
115
|
describe('createServerFn with middleware and validator', () => {
|
|
120
|
-
const middleware1 = createMiddleware(
|
|
116
|
+
const middleware1 = createMiddleware().validator(
|
|
121
117
|
(input: { readonly inputA: 'inputA' }) =>
|
|
122
118
|
({
|
|
123
119
|
outputA: 'outputA',
|
|
124
120
|
}) as const,
|
|
125
121
|
)
|
|
126
122
|
|
|
127
|
-
const middleware2 = createMiddleware(
|
|
123
|
+
const middleware2 = createMiddleware().validator(
|
|
128
124
|
(input: { readonly inputB: 'inputB' }) =>
|
|
129
125
|
({
|
|
130
126
|
outputB: 'outputB',
|
|
131
127
|
}) as const,
|
|
132
128
|
)
|
|
133
129
|
|
|
134
|
-
const middleware3 = createMiddleware(
|
|
135
|
-
middleware1,
|
|
136
|
-
middleware2,
|
|
137
|
-
])
|
|
130
|
+
const middleware3 = createMiddleware().middleware([middleware1, middleware2])
|
|
138
131
|
|
|
139
132
|
test(`response: 'data'`, () => {
|
|
140
133
|
const fn = createServerFn({ method: 'GET', response: 'data' })
|
|
@@ -229,7 +222,7 @@ describe('createServerFn with middleware and validator', () => {
|
|
|
229
222
|
})
|
|
230
223
|
|
|
231
224
|
test('createServerFn overrides properties', () => {
|
|
232
|
-
const middleware1 = createMiddleware(
|
|
225
|
+
const middleware1 = createMiddleware()
|
|
233
226
|
.validator(
|
|
234
227
|
() =>
|
|
235
228
|
({
|
|
@@ -253,7 +246,7 @@ test('createServerFn overrides properties', () => {
|
|
|
253
246
|
return next({ sendContext: newContext, context: newContext })
|
|
254
247
|
})
|
|
255
248
|
|
|
256
|
-
const middleware2 = createMiddleware(
|
|
249
|
+
const middleware2 = createMiddleware()
|
|
257
250
|
.middleware([middleware1])
|
|
258
251
|
.validator(
|
|
259
252
|
() =>
|