@tanstack/react-start-client 1.114.3 → 1.114.5
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/StartClient.cjs +2 -2
- package/dist/cjs/StartClient.cjs.map +1 -1
- package/dist/cjs/StartClient.d.cts +1 -1
- package/dist/cjs/createServerFn.cjs +13 -230
- package/dist/cjs/createServerFn.cjs.map +1 -1
- package/dist/cjs/createServerFn.d.cts +1 -141
- package/dist/cjs/index.cjs +37 -16
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +11 -9
- package/dist/cjs/tests/setupTests.d.cts +0 -0
- package/dist/esm/StartClient.d.ts +1 -1
- package/dist/esm/StartClient.js +1 -1
- package/dist/esm/StartClient.js.map +1 -1
- package/dist/esm/createServerFn.d.ts +1 -141
- package/dist/esm/createServerFn.js +6 -201
- package/dist/esm/createServerFn.js.map +1 -1
- package/dist/esm/index.d.ts +11 -9
- package/dist/esm/index.js +1 -7
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tests/setupTests.d.ts +0 -0
- package/package.json +4 -3
- package/src/StartClient.tsx +2 -2
- package/src/createServerFn.ts +29 -692
- package/src/index.tsx +20 -20
- package/src/tests/createServerFn.test-d.tsx +1 -1
- package/src/tests/setupTests.tsx +1 -0
- package/dist/cjs/createIsomorphicFn.cjs +0 -7
- package/dist/cjs/createIsomorphicFn.cjs.map +0 -1
- package/dist/cjs/createIsomorphicFn.d.cts +0 -12
- package/dist/cjs/createMiddleware.cjs +0 -34
- package/dist/cjs/createMiddleware.cjs.map +0 -1
- package/dist/cjs/createMiddleware.d.cts +0 -131
- package/dist/cjs/envOnly.cjs +0 -7
- package/dist/cjs/envOnly.cjs.map +0 -1
- package/dist/cjs/envOnly.d.cts +0 -4
- package/dist/cjs/headers.cjs +0 -30
- package/dist/cjs/headers.cjs.map +0 -1
- package/dist/cjs/headers.d.cts +0 -5
- package/dist/cjs/json.cjs +0 -14
- package/dist/cjs/json.cjs.map +0 -1
- package/dist/cjs/json.d.cts +0 -2
- package/dist/cjs/registerGlobalMiddleware.cjs +0 -9
- package/dist/cjs/registerGlobalMiddleware.cjs.map +0 -1
- package/dist/cjs/registerGlobalMiddleware.d.cts +0 -5
- package/dist/cjs/serializer.cjs +0 -152
- package/dist/cjs/serializer.cjs.map +0 -1
- package/dist/cjs/serializer.d.cts +0 -2
- package/dist/cjs/ssr-client.cjs +0 -130
- package/dist/cjs/ssr-client.cjs.map +0 -1
- package/dist/cjs/ssr-client.d.cts +0 -65
- package/dist/cjs/tests/createIsomorphicFn.test-d.d.cts +0 -1
- package/dist/cjs/tests/createServerMiddleware.test-d.d.cts +0 -1
- package/dist/cjs/tests/envOnly.test-d.d.cts +0 -1
- package/dist/cjs/tests/json.test.d.cts +0 -1
- package/dist/cjs/tests/transformer.test.d.cts +0 -1
- package/dist/esm/createIsomorphicFn.d.ts +0 -12
- package/dist/esm/createIsomorphicFn.js +0 -7
- package/dist/esm/createIsomorphicFn.js.map +0 -1
- package/dist/esm/createMiddleware.d.ts +0 -131
- package/dist/esm/createMiddleware.js +0 -34
- package/dist/esm/createMiddleware.js.map +0 -1
- package/dist/esm/envOnly.d.ts +0 -4
- package/dist/esm/envOnly.js +0 -7
- package/dist/esm/envOnly.js.map +0 -1
- package/dist/esm/headers.d.ts +0 -5
- package/dist/esm/headers.js +0 -30
- package/dist/esm/headers.js.map +0 -1
- package/dist/esm/json.d.ts +0 -2
- package/dist/esm/json.js +0 -14
- package/dist/esm/json.js.map +0 -1
- package/dist/esm/registerGlobalMiddleware.d.ts +0 -5
- package/dist/esm/registerGlobalMiddleware.js +0 -9
- package/dist/esm/registerGlobalMiddleware.js.map +0 -1
- package/dist/esm/serializer.d.ts +0 -2
- package/dist/esm/serializer.js +0 -152
- package/dist/esm/serializer.js.map +0 -1
- package/dist/esm/ssr-client.d.ts +0 -65
- package/dist/esm/ssr-client.js +0 -130
- package/dist/esm/ssr-client.js.map +0 -1
- package/dist/esm/tests/createIsomorphicFn.test-d.d.ts +0 -1
- package/dist/esm/tests/createServerMiddleware.test-d.d.ts +0 -1
- package/dist/esm/tests/envOnly.test-d.d.ts +0 -1
- package/dist/esm/tests/json.test.d.ts +0 -1
- package/dist/esm/tests/transformer.test.d.ts +0 -1
- package/src/createIsomorphicFn.ts +0 -36
- package/src/createMiddleware.ts +0 -595
- package/src/envOnly.ts +0 -9
- package/src/headers.ts +0 -50
- package/src/json.ts +0 -15
- package/src/registerGlobalMiddleware.ts +0 -9
- package/src/serializer.ts +0 -177
- package/src/ssr-client.tsx +0 -246
- package/src/tests/createIsomorphicFn.test-d.ts +0 -72
- package/src/tests/createServerMiddleware.test-d.ts +0 -611
- package/src/tests/envOnly.test-d.ts +0 -34
- package/src/tests/json.test.ts +0 -37
- package/src/tests/transformer.test.tsx +0 -147
package/src/createServerFn.ts
CHANGED
|
@@ -1,501 +1,30 @@
|
|
|
1
|
-
import { default as invariant } from 'tiny-invariant'
|
|
2
|
-
import { default as warning } from 'tiny-warning'
|
|
3
1
|
import { isNotFound, isRedirect } from '@tanstack/react-router'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
SerializerStringify,
|
|
15
|
-
SerializerStringifyBy,
|
|
16
|
-
Validator,
|
|
17
|
-
} from '@tanstack/router-core'
|
|
2
|
+
import {
|
|
3
|
+
applyMiddleware,
|
|
4
|
+
execValidator,
|
|
5
|
+
extractFormDataContext,
|
|
6
|
+
flattenMiddlewares,
|
|
7
|
+
globalMiddleware,
|
|
8
|
+
serverFnBaseToMiddleware,
|
|
9
|
+
serverFnStaticCache,
|
|
10
|
+
} from '@tanstack/start-client-core'
|
|
11
|
+
import invariant from 'tiny-invariant'
|
|
18
12
|
import type {
|
|
19
13
|
AnyMiddleware,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
data: unknown
|
|
35
|
-
response?: ServerFnResponseType
|
|
36
|
-
headers?: HeadersInit
|
|
37
|
-
signal?: AbortSignal
|
|
38
|
-
context?: any
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export type Fetcher<
|
|
42
|
-
TMiddlewares,
|
|
43
|
-
TValidator,
|
|
44
|
-
TResponse,
|
|
45
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
46
|
-
> =
|
|
47
|
-
undefined extends IntersectAllValidatorInputs<TMiddlewares, TValidator>
|
|
48
|
-
? OptionalFetcher<
|
|
49
|
-
TMiddlewares,
|
|
50
|
-
TValidator,
|
|
51
|
-
TResponse,
|
|
52
|
-
TServerFnResponseType
|
|
53
|
-
>
|
|
54
|
-
: RequiredFetcher<
|
|
55
|
-
TMiddlewares,
|
|
56
|
-
TValidator,
|
|
57
|
-
TResponse,
|
|
58
|
-
TServerFnResponseType
|
|
59
|
-
>
|
|
60
|
-
|
|
61
|
-
export interface FetcherBase {
|
|
62
|
-
url: string
|
|
63
|
-
__executeServer: (opts: {
|
|
64
|
-
method: Method
|
|
65
|
-
response?: ServerFnResponseType
|
|
66
|
-
data: unknown
|
|
67
|
-
headers?: HeadersInit
|
|
68
|
-
context?: any
|
|
69
|
-
signal: AbortSignal
|
|
70
|
-
}) => Promise<unknown>
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export type FetchResult<
|
|
74
|
-
TMiddlewares,
|
|
75
|
-
TResponse,
|
|
76
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
77
|
-
> = TServerFnResponseType extends 'raw'
|
|
78
|
-
? Promise<Response>
|
|
79
|
-
: TServerFnResponseType extends 'full'
|
|
80
|
-
? Promise<FullFetcherData<TMiddlewares, TResponse>>
|
|
81
|
-
: Promise<FetcherData<TResponse>>
|
|
82
|
-
|
|
83
|
-
export interface OptionalFetcher<
|
|
84
|
-
TMiddlewares,
|
|
85
|
-
TValidator,
|
|
86
|
-
TResponse,
|
|
87
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
88
|
-
> extends FetcherBase {
|
|
89
|
-
(
|
|
90
|
-
options?: OptionalFetcherDataOptions<TMiddlewares, TValidator>,
|
|
91
|
-
): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface RequiredFetcher<
|
|
95
|
-
TMiddlewares,
|
|
96
|
-
TValidator,
|
|
97
|
-
TResponse,
|
|
98
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
99
|
-
> extends FetcherBase {
|
|
100
|
-
(
|
|
101
|
-
opts: RequiredFetcherDataOptions<TMiddlewares, TValidator>,
|
|
102
|
-
): FetchResult<TMiddlewares, TResponse, TServerFnResponseType>
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export type FetcherBaseOptions = {
|
|
106
|
-
headers?: HeadersInit
|
|
107
|
-
type?: ServerFnType
|
|
108
|
-
signal?: AbortSignal
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export type ServerFnType = 'static' | 'dynamic'
|
|
112
|
-
|
|
113
|
-
export interface OptionalFetcherDataOptions<TMiddlewares, TValidator>
|
|
114
|
-
extends FetcherBaseOptions {
|
|
115
|
-
data?: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export interface RequiredFetcherDataOptions<TMiddlewares, TValidator>
|
|
119
|
-
extends FetcherBaseOptions {
|
|
120
|
-
data: Expand<IntersectAllValidatorInputs<TMiddlewares, TValidator>>
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface FullFetcherData<TMiddlewares, TResponse> {
|
|
124
|
-
error: unknown
|
|
125
|
-
result: FetcherData<TResponse>
|
|
126
|
-
context: AssignAllClientSendContext<TMiddlewares>
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export type FetcherData<TResponse> =
|
|
130
|
-
TResponse extends JsonResponse<any>
|
|
131
|
-
? SerializerParse<ReturnType<TResponse['json']>>
|
|
132
|
-
: SerializerParse<TResponse>
|
|
133
|
-
|
|
134
|
-
export type RscStream<T> = {
|
|
135
|
-
__cacheState: T
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export type Method = 'GET' | 'POST'
|
|
139
|
-
export type ServerFnResponseType = 'data' | 'full' | 'raw'
|
|
140
|
-
|
|
141
|
-
// see https://h3.unjs.io/guide/event-handler#responses-types
|
|
142
|
-
export type RawResponse = Response | ReadableStream | Readable | null | string
|
|
143
|
-
|
|
144
|
-
export type ServerFnReturnType<
|
|
145
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
146
|
-
TResponse,
|
|
147
|
-
> = TServerFnResponseType extends 'raw'
|
|
148
|
-
? RawResponse | Promise<RawResponse>
|
|
149
|
-
: Promise<SerializerStringify<TResponse>> | SerializerStringify<TResponse>
|
|
150
|
-
export type ServerFn<
|
|
151
|
-
TMethod,
|
|
152
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
153
|
-
TMiddlewares,
|
|
154
|
-
TValidator,
|
|
155
|
-
TResponse,
|
|
156
|
-
> = (
|
|
157
|
-
ctx: ServerFnCtx<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
|
|
158
|
-
) => ServerFnReturnType<TServerFnResponseType, TResponse>
|
|
159
|
-
|
|
160
|
-
export interface ServerFnCtx<
|
|
161
|
-
TMethod,
|
|
162
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
163
|
-
TMiddlewares,
|
|
164
|
-
TValidator,
|
|
165
|
-
> {
|
|
166
|
-
method: TMethod
|
|
167
|
-
response: TServerFnResponseType
|
|
168
|
-
data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TValidator>>
|
|
169
|
-
context: Expand<AssignAllServerContext<TMiddlewares>>
|
|
170
|
-
signal: AbortSignal
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export type CompiledFetcherFn<
|
|
174
|
-
TResponse,
|
|
175
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
176
|
-
> = {
|
|
177
|
-
(
|
|
178
|
-
opts: CompiledFetcherFnOptions &
|
|
179
|
-
ServerFnBaseOptions<Method, TServerFnResponseType>,
|
|
180
|
-
): Promise<TResponse>
|
|
181
|
-
url: string
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
type ServerFnBaseOptions<
|
|
185
|
-
TMethod extends Method = 'GET',
|
|
186
|
-
TServerFnResponseType extends ServerFnResponseType = 'data',
|
|
187
|
-
TResponse = unknown,
|
|
188
|
-
TMiddlewares = unknown,
|
|
189
|
-
TInput = unknown,
|
|
190
|
-
> = {
|
|
191
|
-
method: TMethod
|
|
192
|
-
response?: TServerFnResponseType
|
|
193
|
-
validateClient?: boolean
|
|
194
|
-
middleware?: Constrain<TMiddlewares, ReadonlyArray<AnyMiddleware>>
|
|
195
|
-
validator?: ConstrainValidator<TInput>
|
|
196
|
-
extractedFn?: CompiledFetcherFn<TResponse, TServerFnResponseType>
|
|
197
|
-
serverFn?: ServerFn<
|
|
198
|
-
TMethod,
|
|
199
|
-
TServerFnResponseType,
|
|
200
|
-
TMiddlewares,
|
|
201
|
-
TInput,
|
|
202
|
-
TResponse
|
|
203
|
-
>
|
|
204
|
-
functionId: string
|
|
205
|
-
type: ServerFnTypeOrTypeFn<
|
|
206
|
-
TMethod,
|
|
207
|
-
TServerFnResponseType,
|
|
208
|
-
TMiddlewares,
|
|
209
|
-
AnyValidator
|
|
210
|
-
>
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export type ValidatorSerializerStringify<TValidator> = Validator<
|
|
214
|
-
SerializerStringifyBy<
|
|
215
|
-
ResolveValidatorInput<TValidator>,
|
|
216
|
-
Date | undefined | FormData
|
|
217
|
-
>,
|
|
218
|
-
any
|
|
219
|
-
>
|
|
220
|
-
|
|
221
|
-
export type ConstrainValidator<TValidator> = unknown extends TValidator
|
|
222
|
-
? TValidator
|
|
223
|
-
: Constrain<TValidator, ValidatorSerializerStringify<TValidator>>
|
|
224
|
-
|
|
225
|
-
export interface ServerFnMiddleware<
|
|
226
|
-
TMethod extends Method,
|
|
227
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
228
|
-
TValidator,
|
|
229
|
-
> {
|
|
230
|
-
middleware: <const TNewMiddlewares = undefined>(
|
|
231
|
-
middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyMiddleware>>,
|
|
232
|
-
) => ServerFnAfterMiddleware<
|
|
233
|
-
TMethod,
|
|
234
|
-
TServerFnResponseType,
|
|
235
|
-
TNewMiddlewares,
|
|
236
|
-
TValidator
|
|
237
|
-
>
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
export interface ServerFnAfterMiddleware<
|
|
241
|
-
TMethod extends Method,
|
|
242
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
243
|
-
TMiddlewares,
|
|
244
|
-
TValidator,
|
|
245
|
-
> extends ServerFnValidator<TMethod, TServerFnResponseType, TMiddlewares>,
|
|
246
|
-
ServerFnTyper<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
|
|
247
|
-
ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}
|
|
248
|
-
|
|
249
|
-
export type ValidatorFn<
|
|
250
|
-
TMethod extends Method,
|
|
251
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
252
|
-
TMiddlewares,
|
|
253
|
-
> = <TValidator>(
|
|
254
|
-
validator: ConstrainValidator<TValidator>,
|
|
255
|
-
) => ServerFnAfterValidator<
|
|
256
|
-
TMethod,
|
|
257
|
-
TServerFnResponseType,
|
|
258
|
-
TMiddlewares,
|
|
259
|
-
TValidator
|
|
260
|
-
>
|
|
261
|
-
|
|
262
|
-
export interface ServerFnValidator<
|
|
263
|
-
TMethod extends Method,
|
|
264
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
265
|
-
TMiddlewares,
|
|
266
|
-
> {
|
|
267
|
-
validator: ValidatorFn<TMethod, TServerFnResponseType, TMiddlewares>
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export interface ServerFnAfterValidator<
|
|
271
|
-
TMethod extends Method,
|
|
272
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
273
|
-
TMiddlewares,
|
|
274
|
-
TValidator,
|
|
275
|
-
> extends ServerFnMiddleware<TMethod, TServerFnResponseType, TValidator>,
|
|
276
|
-
ServerFnTyper<TMethod, TServerFnResponseType, TMiddlewares, TValidator>,
|
|
277
|
-
ServerFnHandler<TMethod, TServerFnResponseType, TMiddlewares, TValidator> {}
|
|
278
|
-
|
|
279
|
-
// Typer
|
|
280
|
-
export interface ServerFnTyper<
|
|
281
|
-
TMethod extends Method,
|
|
282
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
283
|
-
TMiddlewares,
|
|
284
|
-
TValidator,
|
|
285
|
-
> {
|
|
286
|
-
type: (
|
|
287
|
-
typer: ServerFnTypeOrTypeFn<
|
|
288
|
-
TMethod,
|
|
289
|
-
TServerFnResponseType,
|
|
290
|
-
TMiddlewares,
|
|
291
|
-
TValidator
|
|
292
|
-
>,
|
|
293
|
-
) => ServerFnAfterTyper<
|
|
294
|
-
TMethod,
|
|
295
|
-
TServerFnResponseType,
|
|
296
|
-
TMiddlewares,
|
|
297
|
-
TValidator
|
|
298
|
-
>
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
export type ServerFnTypeOrTypeFn<
|
|
302
|
-
TMethod extends Method,
|
|
303
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
304
|
-
TMiddlewares,
|
|
305
|
-
TValidator,
|
|
306
|
-
> =
|
|
307
|
-
| ServerFnType
|
|
308
|
-
| ((
|
|
309
|
-
ctx: ServerFnCtx<
|
|
310
|
-
TMethod,
|
|
311
|
-
TServerFnResponseType,
|
|
312
|
-
TMiddlewares,
|
|
313
|
-
TValidator
|
|
314
|
-
>,
|
|
315
|
-
) => ServerFnType)
|
|
316
|
-
|
|
317
|
-
export interface ServerFnAfterTyper<
|
|
318
|
-
TMethod extends Method,
|
|
319
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
320
|
-
TMiddlewares,
|
|
321
|
-
TValidator,
|
|
322
|
-
> extends ServerFnHandler<
|
|
323
|
-
TMethod,
|
|
324
|
-
TServerFnResponseType,
|
|
325
|
-
TMiddlewares,
|
|
326
|
-
TValidator
|
|
327
|
-
> {}
|
|
328
|
-
|
|
329
|
-
// Handler
|
|
330
|
-
export interface ServerFnHandler<
|
|
331
|
-
TMethod extends Method,
|
|
332
|
-
TServerFnResponseType extends ServerFnResponseType,
|
|
333
|
-
TMiddlewares,
|
|
334
|
-
TValidator,
|
|
335
|
-
> {
|
|
336
|
-
handler: <TNewResponse>(
|
|
337
|
-
fn?: ServerFn<
|
|
338
|
-
TMethod,
|
|
339
|
-
TServerFnResponseType,
|
|
340
|
-
TMiddlewares,
|
|
341
|
-
TValidator,
|
|
342
|
-
TNewResponse
|
|
343
|
-
>,
|
|
344
|
-
) => Fetcher<TMiddlewares, TValidator, TNewResponse, TServerFnResponseType>
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export interface ServerFnBuilder<
|
|
348
|
-
TMethod extends Method = 'GET',
|
|
349
|
-
TServerFnResponseType extends ServerFnResponseType = 'data',
|
|
350
|
-
> extends ServerFnMiddleware<TMethod, TServerFnResponseType, undefined>,
|
|
351
|
-
ServerFnValidator<TMethod, TServerFnResponseType, undefined>,
|
|
352
|
-
ServerFnTyper<TMethod, TServerFnResponseType, undefined, undefined>,
|
|
353
|
-
ServerFnHandler<TMethod, TServerFnResponseType, undefined, undefined> {
|
|
354
|
-
options: ServerFnBaseOptions<
|
|
355
|
-
TMethod,
|
|
356
|
-
TServerFnResponseType,
|
|
357
|
-
unknown,
|
|
358
|
-
undefined,
|
|
359
|
-
undefined
|
|
360
|
-
>
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
type StaticCachedResult = {
|
|
364
|
-
ctx?: {
|
|
365
|
-
result: any
|
|
366
|
-
context: any
|
|
367
|
-
}
|
|
368
|
-
error?: any
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
export type ServerFnStaticCache = {
|
|
372
|
-
getItem: (
|
|
373
|
-
ctx: MiddlewareResult,
|
|
374
|
-
) => StaticCachedResult | Promise<StaticCachedResult | undefined>
|
|
375
|
-
setItem: (
|
|
376
|
-
ctx: MiddlewareResult,
|
|
377
|
-
response: StaticCachedResult,
|
|
378
|
-
) => Promise<void>
|
|
379
|
-
fetchItem: (
|
|
380
|
-
ctx: MiddlewareResult,
|
|
381
|
-
) => StaticCachedResult | Promise<StaticCachedResult | undefined>
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
let serverFnStaticCache: ServerFnStaticCache | undefined
|
|
385
|
-
|
|
386
|
-
export function setServerFnStaticCache(
|
|
387
|
-
cache?: ServerFnStaticCache | (() => ServerFnStaticCache | undefined),
|
|
388
|
-
) {
|
|
389
|
-
const previousCache = serverFnStaticCache
|
|
390
|
-
serverFnStaticCache = typeof cache === 'function' ? cache() : cache
|
|
391
|
-
|
|
392
|
-
return () => {
|
|
393
|
-
serverFnStaticCache = previousCache
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
export function createServerFnStaticCache(
|
|
398
|
-
serverFnStaticCache: ServerFnStaticCache,
|
|
399
|
-
) {
|
|
400
|
-
return serverFnStaticCache
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
setServerFnStaticCache(() => {
|
|
404
|
-
const getStaticCacheUrl = (options: MiddlewareResult, hash: string) => {
|
|
405
|
-
return `/__tsr/staticServerFnCache/${options.functionId}__${hash}.json`
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
const jsonToFilenameSafeString = (json: any) => {
|
|
409
|
-
// Custom replacer to sort keys
|
|
410
|
-
const sortedKeysReplacer = (key: string, value: any) =>
|
|
411
|
-
value && typeof value === 'object' && !Array.isArray(value)
|
|
412
|
-
? Object.keys(value)
|
|
413
|
-
.sort()
|
|
414
|
-
.reduce((acc: any, curr: string) => {
|
|
415
|
-
acc[curr] = value[curr]
|
|
416
|
-
return acc
|
|
417
|
-
}, {})
|
|
418
|
-
: value
|
|
419
|
-
|
|
420
|
-
// Convert JSON to string with sorted keys
|
|
421
|
-
const jsonString = JSON.stringify(json ?? '', sortedKeysReplacer)
|
|
422
|
-
|
|
423
|
-
// Replace characters invalid in filenames
|
|
424
|
-
return jsonString
|
|
425
|
-
.replace(/[/\\?%*:|"<>]/g, '-') // Replace invalid characters with a dash
|
|
426
|
-
.replace(/\s+/g, '_') // Optionally replace whitespace with underscores
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
const staticClientCache =
|
|
430
|
-
typeof document !== 'undefined' ? new Map<string, any>() : null
|
|
431
|
-
|
|
432
|
-
return createServerFnStaticCache({
|
|
433
|
-
getItem: async (ctx) => {
|
|
434
|
-
if (typeof document === 'undefined') {
|
|
435
|
-
const hash = jsonToFilenameSafeString(ctx.data)
|
|
436
|
-
const url = getStaticCacheUrl(ctx, hash)
|
|
437
|
-
const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!
|
|
438
|
-
|
|
439
|
-
// Use fs instead of fetch to read from filesystem
|
|
440
|
-
const { promises: fs } = await import('node:fs')
|
|
441
|
-
const path = await import('node:path')
|
|
442
|
-
const filePath = path.join(publicUrl, url)
|
|
443
|
-
|
|
444
|
-
const [cachedResult, readError] = await fs
|
|
445
|
-
.readFile(filePath, 'utf-8')
|
|
446
|
-
.then((c) => [
|
|
447
|
-
startSerializer.parse(c) as {
|
|
448
|
-
ctx: unknown
|
|
449
|
-
error: any
|
|
450
|
-
},
|
|
451
|
-
null,
|
|
452
|
-
])
|
|
453
|
-
.catch((e) => [null, e])
|
|
454
|
-
|
|
455
|
-
if (readError && readError.code !== 'ENOENT') {
|
|
456
|
-
throw readError
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
return cachedResult as StaticCachedResult
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return undefined
|
|
463
|
-
},
|
|
464
|
-
setItem: async (ctx, response) => {
|
|
465
|
-
const { promises: fs } = await import('node:fs')
|
|
466
|
-
const path = await import('node:path')
|
|
467
|
-
|
|
468
|
-
const hash = jsonToFilenameSafeString(ctx.data)
|
|
469
|
-
const url = getStaticCacheUrl(ctx, hash)
|
|
470
|
-
const publicUrl = process.env.TSS_OUTPUT_PUBLIC_DIR!
|
|
471
|
-
const filePath = path.join(publicUrl, url)
|
|
472
|
-
|
|
473
|
-
// Ensure the directory exists
|
|
474
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true })
|
|
475
|
-
|
|
476
|
-
// Store the result with fs
|
|
477
|
-
await fs.writeFile(filePath, startSerializer.stringify(response))
|
|
478
|
-
},
|
|
479
|
-
fetchItem: async (ctx) => {
|
|
480
|
-
const hash = jsonToFilenameSafeString(ctx.data)
|
|
481
|
-
const url = getStaticCacheUrl(ctx, hash)
|
|
482
|
-
|
|
483
|
-
let result: any = staticClientCache?.get(url)
|
|
484
|
-
|
|
485
|
-
if (!result) {
|
|
486
|
-
result = await fetch(url, {
|
|
487
|
-
method: 'GET',
|
|
488
|
-
})
|
|
489
|
-
.then((r) => r.text())
|
|
490
|
-
.then((d) => startSerializer.parse(d))
|
|
491
|
-
|
|
492
|
-
staticClientCache?.set(url, result)
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
return result
|
|
496
|
-
},
|
|
497
|
-
})
|
|
498
|
-
})
|
|
14
|
+
CompiledFetcherFn,
|
|
15
|
+
CompiledFetcherFnOptions,
|
|
16
|
+
Method,
|
|
17
|
+
MiddlewareFn,
|
|
18
|
+
NextFn,
|
|
19
|
+
ServerFn,
|
|
20
|
+
ServerFnBaseOptions,
|
|
21
|
+
ServerFnBuilder,
|
|
22
|
+
ServerFnMiddlewareOptions,
|
|
23
|
+
ServerFnMiddlewareResult,
|
|
24
|
+
ServerFnResponseType,
|
|
25
|
+
ServerFnType,
|
|
26
|
+
StaticCachedResult,
|
|
27
|
+
} from '@tanstack/start-client-core'
|
|
499
28
|
|
|
500
29
|
export function createServerFn<
|
|
501
30
|
TMethod extends Method,
|
|
@@ -588,6 +117,7 @@ export function createServerFn<
|
|
|
588
117
|
|
|
589
118
|
// We want to make sure the new function has the same
|
|
590
119
|
// properties as the original function
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
591
121
|
return Object.assign(
|
|
592
122
|
async (opts?: CompiledFetcherFnOptions) => {
|
|
593
123
|
// Start by executing the client-side middleware chain
|
|
@@ -686,144 +216,11 @@ export function createServerFn<
|
|
|
686
216
|
}
|
|
687
217
|
}
|
|
688
218
|
|
|
689
|
-
function extractFormDataContext(formData: FormData) {
|
|
690
|
-
const serializedContext = formData.get('__TSR_CONTEXT')
|
|
691
|
-
formData.delete('__TSR_CONTEXT')
|
|
692
|
-
|
|
693
|
-
if (typeof serializedContext !== 'string') {
|
|
694
|
-
return {
|
|
695
|
-
context: {},
|
|
696
|
-
data: formData,
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
try {
|
|
701
|
-
const context = startSerializer.parse(serializedContext)
|
|
702
|
-
return {
|
|
703
|
-
context,
|
|
704
|
-
data: formData,
|
|
705
|
-
}
|
|
706
|
-
} catch {
|
|
707
|
-
return {
|
|
708
|
-
data: formData,
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
function flattenMiddlewares(
|
|
714
|
-
middlewares: Array<AnyMiddleware>,
|
|
715
|
-
): Array<AnyMiddleware> {
|
|
716
|
-
const seen = new Set<AnyMiddleware>()
|
|
717
|
-
const flattened: Array<AnyMiddleware> = []
|
|
718
|
-
|
|
719
|
-
const recurse = (middleware: Array<AnyMiddleware>) => {
|
|
720
|
-
middleware.forEach((m) => {
|
|
721
|
-
if (m.options.middleware) {
|
|
722
|
-
recurse(m.options.middleware)
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
if (!seen.has(m)) {
|
|
726
|
-
seen.add(m)
|
|
727
|
-
flattened.push(m)
|
|
728
|
-
}
|
|
729
|
-
})
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
recurse(middlewares)
|
|
733
|
-
|
|
734
|
-
return flattened
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
export type MiddlewareOptions = {
|
|
738
|
-
method: Method
|
|
739
|
-
response?: ServerFnResponseType
|
|
740
|
-
data: any
|
|
741
|
-
headers?: HeadersInit
|
|
742
|
-
signal?: AbortSignal
|
|
743
|
-
sendContext?: any
|
|
744
|
-
context?: any
|
|
745
|
-
type: ServerFnTypeOrTypeFn<any, any, any, any>
|
|
746
|
-
functionId: string
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
export type MiddlewareResult = MiddlewareOptions & {
|
|
750
|
-
result?: unknown
|
|
751
|
-
error?: unknown
|
|
752
|
-
type: ServerFnTypeOrTypeFn<any, any, any, any>
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
export type NextFn = (ctx: MiddlewareResult) => Promise<MiddlewareResult>
|
|
756
|
-
|
|
757
|
-
export type MiddlewareFn = (
|
|
758
|
-
ctx: MiddlewareOptions & {
|
|
759
|
-
next: NextFn
|
|
760
|
-
},
|
|
761
|
-
) => Promise<MiddlewareResult>
|
|
762
|
-
|
|
763
|
-
const applyMiddleware = async (
|
|
764
|
-
middlewareFn: MiddlewareFn,
|
|
765
|
-
ctx: MiddlewareOptions,
|
|
766
|
-
nextFn: NextFn,
|
|
767
|
-
) => {
|
|
768
|
-
return middlewareFn({
|
|
769
|
-
...ctx,
|
|
770
|
-
next: (async (userCtx: MiddlewareResult | undefined = {} as any) => {
|
|
771
|
-
// Return the next middleware
|
|
772
|
-
return nextFn({
|
|
773
|
-
...ctx,
|
|
774
|
-
...userCtx,
|
|
775
|
-
context: {
|
|
776
|
-
...ctx.context,
|
|
777
|
-
...userCtx.context,
|
|
778
|
-
},
|
|
779
|
-
sendContext: {
|
|
780
|
-
...ctx.sendContext,
|
|
781
|
-
...(userCtx.sendContext ?? {}),
|
|
782
|
-
},
|
|
783
|
-
headers: mergeHeaders(ctx.headers, userCtx.headers),
|
|
784
|
-
result:
|
|
785
|
-
userCtx.result !== undefined
|
|
786
|
-
? userCtx.result
|
|
787
|
-
: ctx.response === 'raw'
|
|
788
|
-
? userCtx
|
|
789
|
-
: (ctx as any).result,
|
|
790
|
-
error: userCtx.error ?? (ctx as any).error,
|
|
791
|
-
})
|
|
792
|
-
}) as any,
|
|
793
|
-
} as any)
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
function execValidator(validator: AnyValidator, input: unknown): unknown {
|
|
797
|
-
if (validator == null) return {}
|
|
798
|
-
|
|
799
|
-
if ('~standard' in validator) {
|
|
800
|
-
const result = validator['~standard'].validate(input)
|
|
801
|
-
|
|
802
|
-
if (result instanceof Promise)
|
|
803
|
-
throw new Error('Async validation not supported')
|
|
804
|
-
|
|
805
|
-
if (result.issues)
|
|
806
|
-
throw new Error(JSON.stringify(result.issues, undefined, 2))
|
|
807
|
-
|
|
808
|
-
return result.value
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
if ('parse' in validator) {
|
|
812
|
-
return validator.parse(input)
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (typeof validator === 'function') {
|
|
816
|
-
return validator(input)
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
throw new Error('Invalid validator type!')
|
|
820
|
-
}
|
|
821
|
-
|
|
822
219
|
async function executeMiddleware(
|
|
823
220
|
middlewares: Array<AnyMiddleware>,
|
|
824
221
|
env: 'client' | 'server',
|
|
825
|
-
opts:
|
|
826
|
-
): Promise<
|
|
222
|
+
opts: ServerFnMiddlewareOptions,
|
|
223
|
+
): Promise<ServerFnMiddlewareResult> {
|
|
827
224
|
const flattenedMiddlewares = flattenMiddlewares([
|
|
828
225
|
...globalMiddleware,
|
|
829
226
|
...middlewares,
|
|
@@ -846,6 +243,7 @@ async function executeMiddleware(
|
|
|
846
243
|
ctx.data = await execValidator(nextMiddleware.options.validator, ctx.data)
|
|
847
244
|
}
|
|
848
245
|
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
849
247
|
const middlewareFn = (
|
|
850
248
|
env === 'client'
|
|
851
249
|
? nextMiddleware.options.client
|
|
@@ -855,7 +253,7 @@ async function executeMiddleware(
|
|
|
855
253
|
if (middlewareFn) {
|
|
856
254
|
// Execute the middleware
|
|
857
255
|
return applyMiddleware(middlewareFn, ctx, async (newCtx) => {
|
|
858
|
-
return next(newCtx).catch((error) => {
|
|
256
|
+
return next(newCtx).catch((error: any) => {
|
|
859
257
|
if (isRedirect(error) || isNotFound(error)) {
|
|
860
258
|
return {
|
|
861
259
|
...newCtx,
|
|
@@ -879,64 +277,3 @@ async function executeMiddleware(
|
|
|
879
277
|
context: opts.context || {},
|
|
880
278
|
})
|
|
881
279
|
}
|
|
882
|
-
|
|
883
|
-
function serverFnBaseToMiddleware(
|
|
884
|
-
options: ServerFnBaseOptions<any, any, any, any, any>,
|
|
885
|
-
): AnyMiddleware {
|
|
886
|
-
return {
|
|
887
|
-
_types: undefined!,
|
|
888
|
-
options: {
|
|
889
|
-
validator: options.validator,
|
|
890
|
-
validateClient: options.validateClient,
|
|
891
|
-
client: async ({ next, sendContext, ...ctx }) => {
|
|
892
|
-
const payload = {
|
|
893
|
-
...ctx,
|
|
894
|
-
// switch the sendContext over to context
|
|
895
|
-
context: sendContext,
|
|
896
|
-
type: typeof ctx.type === 'function' ? ctx.type(ctx) : ctx.type,
|
|
897
|
-
} as any
|
|
898
|
-
|
|
899
|
-
if (
|
|
900
|
-
ctx.type === 'static' &&
|
|
901
|
-
process.env.NODE_ENV === 'production' &&
|
|
902
|
-
typeof document !== 'undefined'
|
|
903
|
-
) {
|
|
904
|
-
invariant(
|
|
905
|
-
serverFnStaticCache,
|
|
906
|
-
'serverFnStaticCache.fetchItem is not available!',
|
|
907
|
-
)
|
|
908
|
-
|
|
909
|
-
const result = await serverFnStaticCache.fetchItem(payload)
|
|
910
|
-
|
|
911
|
-
if (result) {
|
|
912
|
-
if (result.error) {
|
|
913
|
-
throw result.error
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
return next(result.ctx)
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
warning(
|
|
920
|
-
result,
|
|
921
|
-
`No static cache item found for ${payload.functionId}__${JSON.stringify(payload.data)}, falling back to server function...`,
|
|
922
|
-
)
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
// Execute the extracted function
|
|
926
|
-
// but not before serializing the context
|
|
927
|
-
const res = await options.extractedFn?.(payload)
|
|
928
|
-
|
|
929
|
-
return next(res) as unknown as MiddlewareClientFnResult<any, any, any>
|
|
930
|
-
},
|
|
931
|
-
server: async ({ next, ...ctx }) => {
|
|
932
|
-
// Execute the server function
|
|
933
|
-
const result = await options.serverFn?.(ctx)
|
|
934
|
-
|
|
935
|
-
return next({
|
|
936
|
-
...ctx,
|
|
937
|
-
result,
|
|
938
|
-
} as any) as unknown as MiddlewareServerFnResult<any, any, any, any>
|
|
939
|
-
},
|
|
940
|
-
},
|
|
941
|
-
}
|
|
942
|
-
}
|