@sveltejs/kit 2.57.1 → 2.58.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.
- package/package.json +2 -2
- package/src/exports/public.d.ts +35 -11
- package/src/runtime/app/paths/client.js +7 -0
- package/src/runtime/app/paths/server.js +7 -0
- package/src/runtime/app/server/remote/prerender.js +3 -4
- package/src/runtime/app/server/remote/query.js +39 -54
- package/src/runtime/app/server/remote/requested.js +22 -16
- package/src/runtime/app/server/remote/shared.js +5 -11
- package/src/runtime/client/remote-functions/command.svelte.js +2 -2
- package/src/runtime/client/remote-functions/form.svelte.js +1 -0
- package/src/runtime/client/remote-functions/query.svelte.js +33 -33
- package/src/runtime/form-utils.js +2 -2
- package/src/runtime/server/page/index.js +26 -16
- package/src/runtime/server/page/render.js +17 -17
- package/src/runtime/server/respond.js +10 -8
- package/src/runtime/server/utils.js +10 -0
- package/src/runtime/shared.js +2 -2
- package/src/types/internal.d.ts +10 -2
- package/src/utils/page_nodes.js +1 -0
- package/src/utils/url.js +3 -3
- package/src/version.js +1 -1
- package/types/index.d.ts +51 -21
- package/types/index.d.ts.map +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltejs/kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.58.0",
|
|
4
4
|
"description": "SvelteKit is the fastest way to build Svelte apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"rollup": "^4.59.0",
|
|
43
43
|
"svelte": "^5.53.12",
|
|
44
44
|
"typescript": "^5.3.3",
|
|
45
|
-
"vite": "^6.
|
|
45
|
+
"vite": "^6.4.2",
|
|
46
46
|
"vitest": "^4.0.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
package/src/exports/public.d.ts
CHANGED
|
@@ -1452,16 +1452,27 @@ export interface Page<
|
|
|
1452
1452
|
*/
|
|
1453
1453
|
export type ParamMatcher = (param: string) => boolean;
|
|
1454
1454
|
|
|
1455
|
-
|
|
1456
|
-
|
|
1455
|
+
/**
|
|
1456
|
+
* A single entry yielded by [`requested`](https://svelte.dev/docs/kit/$app-server#requested).
|
|
1457
|
+
* `arg` is the validated argument (the input *after* the query's schema validated and
|
|
1458
|
+
* transformed it, if applicable); `query` is a `RemoteQuery` bound to the client's
|
|
1459
|
+
* original cache key, so `refresh()` / `set()` will update the correct client entry.
|
|
1460
|
+
*/
|
|
1461
|
+
export type RequestedEntry<Validated, Output> = {
|
|
1462
|
+
arg: Validated;
|
|
1463
|
+
query: RemoteQuery<Output>;
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
export type RequestedResult<Validated, Output> = Iterable<RequestedEntry<Validated, Output>> &
|
|
1467
|
+
AsyncIterable<RequestedEntry<Validated, Output>> & {
|
|
1457
1468
|
/**
|
|
1458
1469
|
* Call `refresh` on all queries selected by this `requested` invocation.
|
|
1459
1470
|
* This is identical to:
|
|
1460
1471
|
* ```ts
|
|
1461
1472
|
* import { requested } from '$app/server';
|
|
1462
1473
|
*
|
|
1463
|
-
* for await (const
|
|
1464
|
-
* void query
|
|
1474
|
+
* for await (const { query } of requested(getPost, ...)) {
|
|
1475
|
+
* void query.refresh();
|
|
1465
1476
|
* }
|
|
1466
1477
|
* ```
|
|
1467
1478
|
*/
|
|
@@ -2013,11 +2024,15 @@ export type RemoteFormFields<T> =
|
|
|
2013
2024
|
? RecursiveFormFields
|
|
2014
2025
|
: NonNullable<T> extends string | number | boolean | File
|
|
2015
2026
|
? RemoteFormField<NonNullable<T>>
|
|
2016
|
-
: // [T] is used to prevent distributing over union
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2027
|
+
: // [NonNullable<T>] is used to prevent distributing over union while still allowing
|
|
2028
|
+
// nullable wrappers (e.g. `string[] | undefined` from a schema with `.default([])`)
|
|
2029
|
+
// to be treated as arrays; only the last condition should distribute over unions
|
|
2030
|
+
[NonNullable<T>] extends [string[] | File[]]
|
|
2031
|
+
? RemoteFormField<NonNullable<T>> & {
|
|
2032
|
+
[K in number]: RemoteFormField<NonNullable<T>[number]>;
|
|
2033
|
+
}
|
|
2034
|
+
: [NonNullable<T>] extends [Array<infer U>]
|
|
2035
|
+
? RemoteFormFieldContainer<NonNullable<T>> & {
|
|
2021
2036
|
[K in number]: RemoteFormFields<U>;
|
|
2022
2037
|
}
|
|
2023
2038
|
: RemoteFormFieldContainer<T> & {
|
|
@@ -2095,7 +2110,7 @@ export type RemoteForm<Input extends RemoteFormInput | void, Output> = {
|
|
|
2095
2110
|
submit: () => Promise<boolean> & {
|
|
2096
2111
|
updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
|
|
2097
2112
|
};
|
|
2098
|
-
}) => void
|
|
2113
|
+
}) => MaybePromise<void>
|
|
2099
2114
|
): {
|
|
2100
2115
|
method: 'POST';
|
|
2101
2116
|
action: string;
|
|
@@ -2221,8 +2236,17 @@ export type RemotePrerenderFunction<Input, Output> = (
|
|
|
2221
2236
|
|
|
2222
2237
|
/**
|
|
2223
2238
|
* The return value of a remote `query` function. See [Remote functions](https://svelte.dev/docs/kit/remote-functions#query) for full documentation.
|
|
2239
|
+
*
|
|
2240
|
+
* The optional `Validated` generic parameter represents the argument type *after* the
|
|
2241
|
+
* query's schema has validated and (optionally) transformed it — this is the type the
|
|
2242
|
+
* query's implementation function receives on the server, and the type yielded by
|
|
2243
|
+
* [`requested`](https://svelte.dev/docs/kit/$app-server#requested). For queries declared
|
|
2244
|
+
* with [Standard Schema](https://standardschema.dev/) it differs from `Input` when the
|
|
2245
|
+
* schema contains a transform (e.g. `v.pipe(v.number(), v.transform(String))` has
|
|
2246
|
+
* `Input = number` but `Validated = string`). For `'unchecked'` validators and queries
|
|
2247
|
+
* without arguments it defaults to `Input`.
|
|
2224
2248
|
*/
|
|
2225
|
-
export type RemoteQueryFunction<Input, Output> = (
|
|
2249
|
+
export type RemoteQueryFunction<Input, Output, _Validated = Input> = (
|
|
2226
2250
|
arg: undefined extends Input ? Input | void : Input
|
|
2227
2251
|
) => RemoteQuery<Output>;
|
|
2228
2252
|
|
|
@@ -52,6 +52,13 @@ const pathname_prefix = hash_routing ? '#' : '';
|
|
|
52
52
|
* @returns {ResolvedPathname}
|
|
53
53
|
*/
|
|
54
54
|
export function resolve(...args) {
|
|
55
|
+
if (!args[0].startsWith('/')) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Cannot use \`resolve(...)\` with a non-absolute pathname or route ID (got "${args[0]}"). ` +
|
|
58
|
+
'`resolve` is only for internal pathnames and route IDs; external URLs should be used directly.'
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
55
62
|
// The type error is correct here, and if someone doesn't pass params when they should there's a runtime error,
|
|
56
63
|
// but we don't want to adjust the internal resolve_route function to accept `undefined`, hence the type cast.
|
|
57
64
|
return (
|
|
@@ -13,6 +13,13 @@ export function asset(file) {
|
|
|
13
13
|
|
|
14
14
|
/** @type {import('./client.js').resolve} */
|
|
15
15
|
export function resolve(id, params) {
|
|
16
|
+
if (!id.startsWith('/')) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Cannot use \`resolve(...)\` with a non-absolute pathname or route ID (got "${id}"). ` +
|
|
19
|
+
'`resolve` is only for internal pathnames and route IDs; external URLs should be used directly.'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
16
23
|
const resolved = resolve_route(id, /** @type {Record<string, string>} */ (params));
|
|
17
24
|
|
|
18
25
|
if (relative) {
|
|
@@ -98,13 +98,12 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
98
98
|
|
|
99
99
|
if (!state.prerendering && !DEV && !event.isRemoteRequest) {
|
|
100
100
|
try {
|
|
101
|
-
return await get_response(__,
|
|
102
|
-
const key = stringify_remote_arg(arg, state.transport);
|
|
101
|
+
return await get_response(__, payload, state, async () => {
|
|
103
102
|
const cache = get_cache(__, state);
|
|
104
103
|
|
|
105
104
|
// TODO adapters can provide prerendered data more efficiently than
|
|
106
105
|
// fetching from the public internet
|
|
107
|
-
const promise = (cache[
|
|
106
|
+
const promise = (cache[payload] ??= {
|
|
108
107
|
serialize: true,
|
|
109
108
|
data: fetch(new URL(url, event.url.origin).href).then(async (response) => {
|
|
110
109
|
if (!response.ok) {
|
|
@@ -132,7 +131,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
132
131
|
return /** @type {Promise<any>} */ (state.prerendering.remote_responses.get(url));
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
const promise = get_response(__,
|
|
134
|
+
const promise = get_response(__, payload, state, () =>
|
|
136
135
|
run_remote_function(event, state, false, () => validate(arg), fn)
|
|
137
136
|
);
|
|
138
137
|
|
|
@@ -43,7 +43,7 @@ import { HttpError, SvelteKitError } from '@sveltejs/kit/internal';
|
|
|
43
43
|
* @overload
|
|
44
44
|
* @param {Schema} schema
|
|
45
45
|
* @param {(arg: StandardSchemaV1.InferOutput<Schema>) => MaybePromise<Output>} fn
|
|
46
|
-
* @returns {RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output
|
|
46
|
+
* @returns {RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output, StandardSchemaV1.InferOutput<Schema>>}
|
|
47
47
|
* @since 2.27
|
|
48
48
|
*/
|
|
49
49
|
/**
|
|
@@ -63,7 +63,19 @@ export function query(validate_or_fn, maybe_fn) {
|
|
|
63
63
|
const validate = create_validator(validate_or_fn, maybe_fn);
|
|
64
64
|
|
|
65
65
|
/** @type {RemoteQueryInternals} */
|
|
66
|
-
const __ = {
|
|
66
|
+
const __ = {
|
|
67
|
+
type: 'query',
|
|
68
|
+
id: '',
|
|
69
|
+
name: '',
|
|
70
|
+
validate,
|
|
71
|
+
bind(payload, validated_arg) {
|
|
72
|
+
const { event, state } = get_request_store();
|
|
73
|
+
|
|
74
|
+
return create_query_resource(__, payload, state, () =>
|
|
75
|
+
run_remote_function(event, state, false, () => validated_arg, fn)
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
67
79
|
|
|
68
80
|
/** @type {RemoteQueryFunction<Input, Output> & { __: RemoteQueryInternals }} */
|
|
69
81
|
const wrapper = (arg) => {
|
|
@@ -74,11 +86,10 @@ export function query(validate_or_fn, maybe_fn) {
|
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
const { event, state } = get_request_store();
|
|
77
|
-
|
|
78
|
-
const is_validated = is_validated_argument(__, state, arg);
|
|
89
|
+
const payload = stringify_remote_arg(arg, state.transport);
|
|
79
90
|
|
|
80
|
-
return create_query_resource(__,
|
|
81
|
-
run_remote_function(event, state, false, () =>
|
|
91
|
+
return create_query_resource(__, payload, state, () =>
|
|
92
|
+
run_remote_function(event, state, false, () => validate(arg), fn)
|
|
82
93
|
);
|
|
83
94
|
};
|
|
84
95
|
|
|
@@ -87,33 +98,6 @@ export function query(validate_or_fn, maybe_fn) {
|
|
|
87
98
|
return wrapper;
|
|
88
99
|
}
|
|
89
100
|
|
|
90
|
-
/**
|
|
91
|
-
* @param {RemoteQueryInternals} __
|
|
92
|
-
* @param {RequestState} state
|
|
93
|
-
* @param {any} arg
|
|
94
|
-
*/
|
|
95
|
-
function is_validated_argument(__, state, arg) {
|
|
96
|
-
return state.remote.validated?.get(__.id)?.has(arg) ?? false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* @param {RemoteQueryInternals} __
|
|
101
|
-
* @param {RequestState} state
|
|
102
|
-
* @param {any} arg
|
|
103
|
-
*/
|
|
104
|
-
export function mark_argument_validated(__, state, arg) {
|
|
105
|
-
const validated = (state.remote.validated ??= new Map());
|
|
106
|
-
let validated_args = validated.get(__.id);
|
|
107
|
-
|
|
108
|
-
if (!validated_args) {
|
|
109
|
-
validated_args = new Set();
|
|
110
|
-
validated.set(__.id, validated_args);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
validated_args.add(arg);
|
|
114
|
-
return arg;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
101
|
/**
|
|
118
102
|
* Creates a batch query function that collects multiple calls and executes them in a single request
|
|
119
103
|
*
|
|
@@ -137,7 +121,7 @@ export function mark_argument_validated(__, state, arg) {
|
|
|
137
121
|
* @overload
|
|
138
122
|
* @param {Schema} schema
|
|
139
123
|
* @param {(args: StandardSchemaV1.InferOutput<Schema>[]) => MaybePromise<(arg: StandardSchemaV1.InferOutput<Schema>, idx: number) => Output>} fn
|
|
140
|
-
* @returns {RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output
|
|
124
|
+
* @returns {RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output, StandardSchemaV1.InferOutput<Schema>>}
|
|
141
125
|
* @since 2.35
|
|
142
126
|
*/
|
|
143
127
|
/**
|
|
@@ -206,20 +190,22 @@ function batch(validate_or_fn, maybe_fn) {
|
|
|
206
190
|
}
|
|
207
191
|
|
|
208
192
|
const { event, state } = get_request_store();
|
|
193
|
+
// batched queries do not participate in `requested(...)`, so `arg` is
|
|
194
|
+
// always the raw user-supplied value and can be used for the cache key directly
|
|
195
|
+
const payload = stringify_remote_arg(arg, state.transport);
|
|
209
196
|
|
|
210
|
-
return create_query_resource(__,
|
|
197
|
+
return create_query_resource(__, payload, state, () => {
|
|
211
198
|
// Collect all the calls to the same query in the same macrotask,
|
|
212
199
|
// then execute them as one backend request.
|
|
213
200
|
return new Promise((resolve, reject) => {
|
|
214
|
-
const
|
|
215
|
-
const entry = batching.get(key);
|
|
201
|
+
const entry = batching.get(payload);
|
|
216
202
|
|
|
217
203
|
if (entry) {
|
|
218
204
|
entry.resolvers.push({ resolve, reject });
|
|
219
205
|
return;
|
|
220
206
|
}
|
|
221
207
|
|
|
222
|
-
batching.set(
|
|
208
|
+
batching.set(payload, {
|
|
223
209
|
arg,
|
|
224
210
|
resolvers: [{ resolve, reject }]
|
|
225
211
|
});
|
|
@@ -275,17 +261,17 @@ function batch(validate_or_fn, maybe_fn) {
|
|
|
275
261
|
|
|
276
262
|
/**
|
|
277
263
|
* @param {RemoteInternals} __
|
|
278
|
-
* @param {
|
|
264
|
+
* @param {string} payload — the stringified raw argument (i.e. the cache key the client will use)
|
|
279
265
|
* @param {RequestState} state
|
|
280
266
|
* @param {() => Promise<any>} fn
|
|
281
267
|
* @returns {RemoteQuery<any>}
|
|
282
268
|
*/
|
|
283
|
-
function create_query_resource(__,
|
|
269
|
+
function create_query_resource(__, payload, state, fn) {
|
|
284
270
|
/** @type {Promise<any> | null} */
|
|
285
271
|
let promise = null;
|
|
286
272
|
|
|
287
273
|
const get_promise = () => {
|
|
288
|
-
return (promise ??= get_response(__,
|
|
274
|
+
return (promise ??= get_response(__, payload, state, fn));
|
|
289
275
|
};
|
|
290
276
|
|
|
291
277
|
return {
|
|
@@ -302,8 +288,8 @@ function create_query_resource(__, arg, state, fn) {
|
|
|
302
288
|
loading: true,
|
|
303
289
|
ready: false,
|
|
304
290
|
refresh() {
|
|
305
|
-
const refresh_context = get_refresh_context(__, 'refresh',
|
|
306
|
-
const is_immediate_refresh = !refresh_context.cache[refresh_context.
|
|
291
|
+
const refresh_context = get_refresh_context(__, 'refresh', payload);
|
|
292
|
+
const is_immediate_refresh = !refresh_context.cache[refresh_context.payload];
|
|
307
293
|
const value = is_immediate_refresh ? get_promise() : fn();
|
|
308
294
|
return update_refresh_value(refresh_context, value, is_immediate_refresh);
|
|
309
295
|
},
|
|
@@ -316,11 +302,11 @@ function create_query_resource(__, arg, state, fn) {
|
|
|
316
302
|
'On the server, .run() can only be called in universal `load` functions. Anywhere else, just await the query directly'
|
|
317
303
|
);
|
|
318
304
|
}
|
|
319
|
-
return get_response(__,
|
|
305
|
+
return get_response(__, payload, state, fn);
|
|
320
306
|
},
|
|
321
307
|
/** @param {any} value */
|
|
322
308
|
set(value) {
|
|
323
|
-
return update_refresh_value(get_refresh_context(__, 'set',
|
|
309
|
+
return update_refresh_value(get_refresh_context(__, 'set', payload), value);
|
|
324
310
|
},
|
|
325
311
|
/** @type {Promise<any>['then']} */
|
|
326
312
|
then(onfulfilled, onrejected) {
|
|
@@ -341,10 +327,10 @@ Object.defineProperty(query, 'batch', { value: batch, enumerable: true });
|
|
|
341
327
|
/**
|
|
342
328
|
* @param {RemoteInternals} __
|
|
343
329
|
* @param {'set' | 'refresh'} action
|
|
344
|
-
* @param {
|
|
345
|
-
* @returns {{ __: RemoteInternals; state: any; refreshes: Record<string, Promise<any>>; cache: Record<string, { serialize: boolean; data: any }>; refreshes_key: string;
|
|
330
|
+
* @param {string} payload — the stringified raw argument
|
|
331
|
+
* @returns {{ __: RemoteInternals; state: any; refreshes: Record<string, Promise<any>>; cache: Record<string, { serialize: boolean; data: any }>; refreshes_key: string; payload: string }}
|
|
346
332
|
*/
|
|
347
|
-
function get_refresh_context(__, action,
|
|
333
|
+
function get_refresh_context(__, action, payload) {
|
|
348
334
|
const { state } = get_request_store();
|
|
349
335
|
const { refreshes } = state.remote;
|
|
350
336
|
|
|
@@ -356,27 +342,26 @@ function get_refresh_context(__, action, arg) {
|
|
|
356
342
|
}
|
|
357
343
|
|
|
358
344
|
const cache = get_cache(__, state);
|
|
359
|
-
const
|
|
360
|
-
const refreshes_key = create_remote_key(__.id, cache_key);
|
|
345
|
+
const refreshes_key = create_remote_key(__.id, payload);
|
|
361
346
|
|
|
362
|
-
return { __, state, refreshes, refreshes_key, cache,
|
|
347
|
+
return { __, state, refreshes, refreshes_key, cache, payload };
|
|
363
348
|
}
|
|
364
349
|
|
|
365
350
|
/**
|
|
366
|
-
* @param {{ __: RemoteInternals; refreshes: Record<string, Promise<any>>; cache: Record<string, { serialize: boolean; data: any }>; refreshes_key: string;
|
|
351
|
+
* @param {{ __: RemoteInternals; refreshes: Record<string, Promise<any>>; cache: Record<string, { serialize: boolean; data: any }>; refreshes_key: string; payload: string }} context
|
|
367
352
|
* @param {any} value
|
|
368
353
|
* @param {boolean} [is_immediate_refresh=false]
|
|
369
354
|
* @returns {Promise<void>}
|
|
370
355
|
*/
|
|
371
356
|
function update_refresh_value(
|
|
372
|
-
{ __, refreshes, refreshes_key, cache,
|
|
357
|
+
{ __, refreshes, refreshes_key, cache, payload },
|
|
373
358
|
value,
|
|
374
359
|
is_immediate_refresh = false
|
|
375
360
|
) {
|
|
376
361
|
const promise = Promise.resolve(value);
|
|
377
362
|
|
|
378
363
|
if (!is_immediate_refresh) {
|
|
379
|
-
cache[
|
|
364
|
+
cache[payload] = { serialize: true, data: promise };
|
|
380
365
|
}
|
|
381
366
|
|
|
382
367
|
if (__.id) {
|
|
@@ -3,23 +3,28 @@
|
|
|
3
3
|
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
4
4
|
import { create_remote_key, parse_remote_arg } from '../../../shared.js';
|
|
5
5
|
import { noop } from '../../../../utils/functions.js';
|
|
6
|
-
import { mark_argument_validated } from './query.js';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* In the context of a remote `command` or `form` request, returns an iterable
|
|
10
|
-
* of the
|
|
11
|
-
*
|
|
9
|
+
* of `{ arg, query }` entries for the refreshes requested by the client, up to
|
|
10
|
+
* the supplied `limit`. Each `query` is a `RemoteQuery` bound to the original
|
|
11
|
+
* client-side cache key, so `refresh()` / `set()` propagate correctly even when
|
|
12
|
+
* the query's schema transforms the input. `arg` is the *validated* argument,
|
|
13
|
+
* i.e. the value after the schema has run (so `InferOutput<Schema>` for queries
|
|
14
|
+
* declared with a Standard Schema).
|
|
15
|
+
*
|
|
16
|
+
* Arguments that fail validation or exceed `limit` are recorded as failures in
|
|
12
17
|
* the response to the client.
|
|
13
18
|
*
|
|
14
19
|
* @example
|
|
15
20
|
* ```ts
|
|
16
21
|
* import { requested } from '$app/server';
|
|
17
22
|
*
|
|
18
|
-
* for (const arg of requested(getPost, 5)) {
|
|
19
|
-
* //
|
|
20
|
-
* //
|
|
21
|
-
* //
|
|
22
|
-
* void
|
|
23
|
+
* for (const { arg, query } of requested(getPost, 5)) {
|
|
24
|
+
* // `arg` is the validated argument; `query` is bound to the client's
|
|
25
|
+
* // cache key. It's safe to throw away this promise -- SvelteKit will
|
|
26
|
+
* // await it and forward any errors to the client.
|
|
27
|
+
* void query.refresh();
|
|
23
28
|
* }
|
|
24
29
|
* ```
|
|
25
30
|
*
|
|
@@ -33,11 +38,12 @@ import { mark_argument_validated } from './query.js';
|
|
|
33
38
|
*
|
|
34
39
|
* @template Input
|
|
35
40
|
* @template Output
|
|
36
|
-
* @
|
|
37
|
-
* @param {
|
|
38
|
-
* @
|
|
41
|
+
* @template [Validated=Input]
|
|
42
|
+
* @param {RemoteQueryFunction<Input, Output, Validated>} query
|
|
43
|
+
* @param {number} limit
|
|
44
|
+
* @returns {RequestedResult<Validated, Output>}
|
|
39
45
|
*/
|
|
40
|
-
export function requested(query, limit
|
|
46
|
+
export function requested(query, limit) {
|
|
41
47
|
const { state } = get_request_store();
|
|
42
48
|
const internals = /** @type {RemoteQueryInternals | undefined} */ (/** @type {any} */ (query).__);
|
|
43
49
|
|
|
@@ -85,7 +91,7 @@ export function requested(query, limit = Infinity) {
|
|
|
85
91
|
);
|
|
86
92
|
}
|
|
87
93
|
|
|
88
|
-
yield
|
|
94
|
+
yield { arg: validated, query: internals.bind(payload, validated) };
|
|
89
95
|
} catch (error) {
|
|
90
96
|
record_failure(payload, error);
|
|
91
97
|
continue;
|
|
@@ -97,7 +103,7 @@ export function requested(query, limit = Infinity) {
|
|
|
97
103
|
try {
|
|
98
104
|
const parsed = parse_remote_arg(payload, state.transport);
|
|
99
105
|
const validated = await internals.validate(parsed);
|
|
100
|
-
return
|
|
106
|
+
return { arg: validated, query: internals.bind(payload, validated) };
|
|
101
107
|
} catch (error) {
|
|
102
108
|
record_failure(payload, error);
|
|
103
109
|
throw new Error(`Skipping ${internals.name}(${payload})`, { cause: error });
|
|
@@ -105,8 +111,8 @@ export function requested(query, limit = Infinity) {
|
|
|
105
111
|
});
|
|
106
112
|
},
|
|
107
113
|
async refreshAll() {
|
|
108
|
-
for await (const
|
|
109
|
-
void query
|
|
114
|
+
for await (const { query } of this) {
|
|
115
|
+
void query.refresh();
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
};
|
|
@@ -4,12 +4,7 @@ import { parse } from 'devalue';
|
|
|
4
4
|
import { error } from '@sveltejs/kit';
|
|
5
5
|
import { with_request_store, get_request_store } from '@sveltejs/kit/internal/server';
|
|
6
6
|
import { noop } from '../../../../utils/functions.js';
|
|
7
|
-
import {
|
|
8
|
-
stringify_remote_arg,
|
|
9
|
-
create_remote_key,
|
|
10
|
-
stringify,
|
|
11
|
-
unfriendly_hydratable
|
|
12
|
-
} from '../../../shared.js';
|
|
7
|
+
import { create_remote_key, stringify, unfriendly_hydratable } from '../../../shared.js';
|
|
13
8
|
|
|
14
9
|
/**
|
|
15
10
|
* @param {any} validate_or_fn
|
|
@@ -68,19 +63,18 @@ export function create_validator(validate_or_fn, maybe_fn) {
|
|
|
68
63
|
*
|
|
69
64
|
* @template {MaybePromise<any>} T
|
|
70
65
|
* @param {RemoteInternals} internals
|
|
71
|
-
* @param {
|
|
66
|
+
* @param {string} payload — the stringified raw argument (i.e. the cache key the client will use)
|
|
72
67
|
* @param {RequestState} state
|
|
73
68
|
* @param {() => Promise<T>} get_result
|
|
74
69
|
* @returns {Promise<T>}
|
|
75
70
|
*/
|
|
76
|
-
export async function get_response(internals,
|
|
71
|
+
export async function get_response(internals, payload, state, get_result) {
|
|
77
72
|
// wait a beat, in case `myQuery().set(...)` or `myQuery().refresh()` is immediately called
|
|
78
73
|
// eslint-disable-next-line @typescript-eslint/await-thenable
|
|
79
74
|
await 0;
|
|
80
75
|
|
|
81
76
|
const cache = get_cache(internals, state);
|
|
82
|
-
const
|
|
83
|
-
const entry = (cache[key] ??= {
|
|
77
|
+
const entry = (cache[payload] ??= {
|
|
84
78
|
serialize: false,
|
|
85
79
|
data: get_result()
|
|
86
80
|
});
|
|
@@ -88,7 +82,7 @@ export async function get_response(internals, arg, state, get_result) {
|
|
|
88
82
|
entry.serialize ||= !!state.is_in_universal_load;
|
|
89
83
|
|
|
90
84
|
if (state.is_in_render && internals.id) {
|
|
91
|
-
const remote_key = create_remote_key(internals.id,
|
|
85
|
+
const remote_key = create_remote_key(internals.id, payload);
|
|
92
86
|
|
|
93
87
|
Promise.resolve(entry.data)
|
|
94
88
|
.then((value) => {
|
|
@@ -35,8 +35,8 @@ export function command(id) {
|
|
|
35
35
|
// Increment pending count when command starts
|
|
36
36
|
pending_count++;
|
|
37
37
|
|
|
38
|
-
//
|
|
39
|
-
// Do this here, after
|
|
38
|
+
// No one should call commands during rendering, but this is belt and braces.
|
|
39
|
+
// Do this here, after Svelte's reactivity context is gone.
|
|
40
40
|
const headers = {
|
|
41
41
|
'Content-Type': 'application/json',
|
|
42
42
|
...get_remote_request_headers()
|
|
@@ -228,6 +228,7 @@ export function form(id) {
|
|
|
228
228
|
|
|
229
229
|
// reset issues in case it's a redirect or error (but issues passed in that case)
|
|
230
230
|
raw_issues = [];
|
|
231
|
+
result = undefined;
|
|
231
232
|
|
|
232
233
|
if (form_result.type === 'result') {
|
|
233
234
|
({ issues: raw_issues = [], result } = devalue.parse(form_result.result, app.decoders));
|
|
@@ -500,53 +500,24 @@ class QueryProxy {
|
|
|
500
500
|
};
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
-
#get_cached_query() {
|
|
504
|
-
// TODO iterate on error messages
|
|
505
|
-
if (!this.#tracking) {
|
|
506
|
-
throw new Error(
|
|
507
|
-
'This query was not created in a reactive context and is limited to calling `.run`, `.refresh`, and `.set`.'
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (!this.#active) {
|
|
512
|
-
throw new Error(
|
|
513
|
-
'This query instance is no longer active and can no longer be used for reactive state access. ' +
|
|
514
|
-
'This typically means you created the query in a tracking context and stashed it somewhere outside of a tracking context.'
|
|
515
|
-
);
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
const cached = query_map.get(this.#id)?.get(this.#payload);
|
|
519
|
-
|
|
520
|
-
if (!cached) {
|
|
521
|
-
// The only case where `this.#active` can be `true` is when we've added an entry to `query_map`, and the
|
|
522
|
-
// only way that entry can get removed is if this instance (and all others) have been deactivated.
|
|
523
|
-
// So if we get here, someone (us, check git blame and point fingers) did `entry.count -= 1` improperly.
|
|
524
|
-
throw new Error(
|
|
525
|
-
'No cached query found. This should be impossible. Please file a bug report.'
|
|
526
|
-
);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
return cached.resource;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
503
|
#safe_get_cached_query() {
|
|
533
504
|
return query_map.get(this.#id)?.get(this.#payload)?.resource;
|
|
534
505
|
}
|
|
535
506
|
|
|
536
507
|
get current() {
|
|
537
|
-
return this.#
|
|
508
|
+
return this.#safe_get_cached_query()?.current;
|
|
538
509
|
}
|
|
539
510
|
|
|
540
511
|
get error() {
|
|
541
|
-
return this.#
|
|
512
|
+
return this.#safe_get_cached_query()?.error;
|
|
542
513
|
}
|
|
543
514
|
|
|
544
515
|
get loading() {
|
|
545
|
-
return this.#
|
|
516
|
+
return this.#safe_get_cached_query()?.loading ?? false;
|
|
546
517
|
}
|
|
547
518
|
|
|
548
519
|
get ready() {
|
|
549
|
-
return this.#
|
|
520
|
+
return this.#safe_get_cached_query()?.ready ?? false;
|
|
550
521
|
}
|
|
551
522
|
|
|
552
523
|
run() {
|
|
@@ -588,6 +559,35 @@ class QueryProxy {
|
|
|
588
559
|
return release;
|
|
589
560
|
}
|
|
590
561
|
|
|
562
|
+
#get_cached_query() {
|
|
563
|
+
// TODO iterate on error messages
|
|
564
|
+
if (!this.#tracking) {
|
|
565
|
+
throw new Error(
|
|
566
|
+
'This query was not created in a reactive context and cannot be awaited. Use `.run()` to execute the query instead.'
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if (!this.#active) {
|
|
571
|
+
throw new Error(
|
|
572
|
+
'This query instance is no longer active and can no longer be awaited. ' +
|
|
573
|
+
'This typically means you created the query in a tracking context and stashed it somewhere outside of a tracking context.'
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
const cached = query_map.get(this.#id)?.get(this.#payload);
|
|
578
|
+
|
|
579
|
+
if (!cached) {
|
|
580
|
+
// The only case where `this.#active` can be `true` is when we've added an entry to `query_map`, and the
|
|
581
|
+
// only way that entry can get removed is if this instance (and all others) have been deactivated.
|
|
582
|
+
// So if we get here, someone (us, check git blame and point fingers) did `entry.count -= 1` improperly.
|
|
583
|
+
throw new Error(
|
|
584
|
+
'No cached query found. This should be impossible. Please file a bug report.'
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
return cached.resource;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
591
|
/** @type {Query<T>['then']} */
|
|
592
592
|
get then() {
|
|
593
593
|
const cached = this.#get_cached_query();
|
|
@@ -503,8 +503,8 @@ export function deep_set(object, keys, value) {
|
|
|
503
503
|
check_prototype_pollution(key);
|
|
504
504
|
|
|
505
505
|
const is_array = /^\d+$/.test(keys[i + 1]);
|
|
506
|
-
const
|
|
507
|
-
const
|
|
506
|
+
const inner = Object.hasOwn(current, key) ? current[key] : undefined;
|
|
507
|
+
const exists = inner != null;
|
|
508
508
|
|
|
509
509
|
if (exists && is_array !== Array.isArray(inner)) {
|
|
510
510
|
throw new Error(`Invalid array key ${keys[i + 1]}`);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** @import { ActionResult, RequestEvent, SSRManifest } from '@sveltejs/kit' */
|
|
2
|
+
/** @import { PageNodeIndexes, RequestState, RequiredResolveOptions, ServerDataNode, SSRComponent, SSRNode, SSROptions, SSRState } from 'types' */
|
|
1
3
|
import { text } from '@sveltejs/kit';
|
|
2
4
|
import { HttpError, Redirect } from '@sveltejs/kit/internal';
|
|
3
5
|
import { compact } from '../../../utils/array.js';
|
|
@@ -25,14 +27,14 @@ import { PageNodes } from '../../../utils/page_nodes.js';
|
|
|
25
27
|
const MAX_DEPTH = 10;
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
|
-
* @param {
|
|
29
|
-
* @param {
|
|
30
|
-
* @param {
|
|
31
|
-
* @param {
|
|
32
|
-
* @param {
|
|
33
|
-
* @param {
|
|
30
|
+
* @param {RequestEvent} event
|
|
31
|
+
* @param {RequestState} event_state
|
|
32
|
+
* @param {PageNodeIndexes} page
|
|
33
|
+
* @param {SSROptions} options
|
|
34
|
+
* @param {SSRManifest} manifest
|
|
35
|
+
* @param {SSRState} state
|
|
34
36
|
* @param {import('../../../utils/page_nodes.js').PageNodes} nodes
|
|
35
|
-
* @param {
|
|
37
|
+
* @param {RequiredResolveOptions} resolve_opts
|
|
36
38
|
* @returns {Promise<Response>}
|
|
37
39
|
*/
|
|
38
40
|
export async function render_page(
|
|
@@ -58,11 +60,11 @@ export async function render_page(
|
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
try {
|
|
61
|
-
const leaf_node = /** @type {
|
|
63
|
+
const leaf_node = /** @type {SSRNode} */ (nodes.page());
|
|
62
64
|
|
|
63
65
|
let status = 200;
|
|
64
66
|
|
|
65
|
-
/** @type {
|
|
67
|
+
/** @type {ActionResult | undefined} */
|
|
66
68
|
let action_result = undefined;
|
|
67
69
|
|
|
68
70
|
if (is_action_request(event)) {
|
|
@@ -135,7 +137,15 @@ export async function render_page(
|
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
return await render_response({
|
|
138
|
-
|
|
140
|
+
// provide nodes without running load functions so that the styles and
|
|
141
|
+
// fonts are linked in the head before CSR takes over
|
|
142
|
+
branch: compact(nodes.data).map((node) => {
|
|
143
|
+
return {
|
|
144
|
+
node,
|
|
145
|
+
data: null,
|
|
146
|
+
server_data: null
|
|
147
|
+
};
|
|
148
|
+
}),
|
|
139
149
|
fetched,
|
|
140
150
|
page_config: {
|
|
141
151
|
ssr: false,
|
|
@@ -165,7 +175,7 @@ export async function render_page(
|
|
|
165
175
|
? server_data_serializer_json(event, event_state, options)
|
|
166
176
|
: null;
|
|
167
177
|
|
|
168
|
-
/** @type {Array<Promise<
|
|
178
|
+
/** @type {Array<Promise<ServerDataNode | null>>} */
|
|
169
179
|
const server_promises = nodes.data.map((node, i) => {
|
|
170
180
|
if (load_error) {
|
|
171
181
|
// if an error happens immediately, don't bother with the rest of the nodes
|
|
@@ -359,7 +369,7 @@ export async function render_page(
|
|
|
359
369
|
},
|
|
360
370
|
status,
|
|
361
371
|
error: null,
|
|
362
|
-
branch:
|
|
372
|
+
branch: compact(branch),
|
|
363
373
|
action_result,
|
|
364
374
|
fetched,
|
|
365
375
|
data_serializer: !ssr ? server_data_serializer(event, event_state, options) : data_serializer,
|
|
@@ -388,14 +398,14 @@ export async function render_page(
|
|
|
388
398
|
|
|
389
399
|
/**
|
|
390
400
|
*
|
|
391
|
-
* @param {
|
|
401
|
+
* @param {SSROptions} options
|
|
392
402
|
* @param {boolean} ssr
|
|
393
403
|
* @param {Array<import('./types.js').Loaded | null>} branch
|
|
394
|
-
* @param {
|
|
395
|
-
* @param {
|
|
404
|
+
* @param {PageNodeIndexes} page
|
|
405
|
+
* @param {SSRManifest} manifest
|
|
396
406
|
*/
|
|
397
407
|
async function load_error_components(options, ssr, branch, page, manifest) {
|
|
398
|
-
/** @type {Array<
|
|
408
|
+
/** @type {Array<SSRComponent | undefined> | undefined} */
|
|
399
409
|
let error_components;
|
|
400
410
|
|
|
401
411
|
if (options.server_error_boundaries && ssr) {
|
|
@@ -15,7 +15,7 @@ import { create_server_routing_response, generate_route_object } from './server_
|
|
|
15
15
|
import { add_resolution_suffix } from '../../pathname.js';
|
|
16
16
|
import { try_get_request_store, with_request_store } from '@sveltejs/kit/internal/server';
|
|
17
17
|
import { text_encoder } from '../../utils.js';
|
|
18
|
-
import { get_global_name, handle_error_and_jsonify } from '../utils.js';
|
|
18
|
+
import { count_non_ssi_comments, get_global_name, handle_error_and_jsonify } from '../utils.js';
|
|
19
19
|
import { create_remote_key } from '../../shared.js';
|
|
20
20
|
import { get_status } from '../../../utils/error.js';
|
|
21
21
|
|
|
@@ -267,25 +267,25 @@ export async function render_response({
|
|
|
267
267
|
|
|
268
268
|
paths.reset(); // just in case `options.root.render(...)` failed
|
|
269
269
|
}
|
|
270
|
+
} else {
|
|
271
|
+
rendered = { head: '', html: '', css: { code: '', map: null }, hashes: { script: [] } };
|
|
272
|
+
}
|
|
270
273
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
for (const { node } of branch) {
|
|
275
|
+
for (const url of node.imports) modulepreloads.add(url);
|
|
276
|
+
for (const url of node.stylesheets) stylesheets.add(url);
|
|
277
|
+
for (const url of node.fonts) fonts.add(url);
|
|
275
278
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
if (node.inline_styles && !client.inline) {
|
|
280
|
+
Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
|
|
281
|
+
if (typeof css === 'string') {
|
|
282
|
+
inline_styles.set(filename, css);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
282
285
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
+
inline_styles.set(filename, css(`${assets}/${paths.app_dir}/immutable/assets`, assets));
|
|
287
|
+
});
|
|
286
288
|
}
|
|
287
|
-
} else {
|
|
288
|
-
rendered = { head: '', html: '', css: { code: '', map: null }, hashes: { script: [] } };
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
const head = new Head(rendered.head, !!state.prerendering);
|
|
@@ -691,7 +691,7 @@ export async function render_response({
|
|
|
691
691
|
|
|
692
692
|
if (DEV) {
|
|
693
693
|
if (page_config.csr) {
|
|
694
|
-
if (transformed
|
|
694
|
+
if (count_non_ssi_comments(transformed) < count_non_ssi_comments(html)) {
|
|
695
695
|
// the \u001B stuff is ANSI codes, so that we don't need to add a library to the runtime
|
|
696
696
|
// https://svelte.dev/playground/1b3f49696f0c44c881c34587f2537aa2?version=4.2.19
|
|
697
697
|
console.warn(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { RequestState } from 'types' */
|
|
1
|
+
/** @import { RequestState, SSRNode } from 'types' */
|
|
2
2
|
import { DEV } from 'esm-env';
|
|
3
3
|
import { json, text } from '@sveltejs/kit';
|
|
4
4
|
import { Redirect, SvelteKitError } from '@sveltejs/kit/internal';
|
|
@@ -153,12 +153,7 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
153
153
|
/** A map of remote function key to corresponding single-flight-mutation promise */
|
|
154
154
|
refreshes: null,
|
|
155
155
|
/** A map of remote function ID to payloads requested for refreshing by the client */
|
|
156
|
-
requested: null
|
|
157
|
-
/**
|
|
158
|
-
* A map of remote function ID to objects that have passed validation;
|
|
159
|
-
* used to prevent revalidating parameters returned from `requested`
|
|
160
|
-
*/
|
|
161
|
-
validated: null
|
|
156
|
+
requested: null
|
|
162
157
|
},
|
|
163
158
|
is_in_remote_function: false,
|
|
164
159
|
is_in_render: false,
|
|
@@ -566,7 +561,14 @@ export async function internal_respond(request, options, manifest, state) {
|
|
|
566
561
|
page_config: { ssr: false, csr: true },
|
|
567
562
|
status: 200,
|
|
568
563
|
error: null,
|
|
569
|
-
branch: [
|
|
564
|
+
branch: [
|
|
565
|
+
// include the root layout because it applies to every page
|
|
566
|
+
{
|
|
567
|
+
node: /** @type {SSRNode} */ (await manifest._.nodes[0]()),
|
|
568
|
+
data: null,
|
|
569
|
+
server_data: null
|
|
570
|
+
}
|
|
571
|
+
],
|
|
570
572
|
fetched: [],
|
|
571
573
|
resolve_opts,
|
|
572
574
|
data_serializer: server_data_serializer(event, event_state, options)
|
|
@@ -251,3 +251,13 @@ export function get_node_type(node_id) {
|
|
|
251
251
|
const dot_parts = filename.split('.');
|
|
252
252
|
return dot_parts.slice(0, -1).join('.');
|
|
253
253
|
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Counts HTML comments that are not SSI directives (which start with `<!--#`).
|
|
257
|
+
* Used to detect when `transformPageChunk` removes comments that Svelte needs for hydration.
|
|
258
|
+
* @param {string} str
|
|
259
|
+
* @returns {number}
|
|
260
|
+
*/
|
|
261
|
+
export function count_non_ssi_comments(str) {
|
|
262
|
+
return (str.match(/<!--(?!#)/g) ?? []).length;
|
|
263
|
+
}
|
package/src/runtime/shared.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @import { Transport } from '@sveltejs/kit' */
|
|
2
2
|
import * as devalue from 'devalue';
|
|
3
|
-
import { base64_decode, base64_encode, text_decoder } from './utils.js';
|
|
3
|
+
import { base64_decode, base64_encode, text_decoder, text_encoder } from './utils.js';
|
|
4
4
|
import * as svelte from 'svelte';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -261,7 +261,7 @@ export function stringify_remote_arg(value, transport, sort = true) {
|
|
|
261
261
|
create_remote_arg_reducers(transport, sort, new Map())
|
|
262
262
|
);
|
|
263
263
|
|
|
264
|
-
const bytes =
|
|
264
|
+
const bytes = text_encoder.encode(json_string);
|
|
265
265
|
return base64_encode(bytes).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');
|
|
266
266
|
}
|
|
267
267
|
|
package/src/types/internal.d.ts
CHANGED
|
@@ -22,7 +22,8 @@ import {
|
|
|
22
22
|
ClientInit,
|
|
23
23
|
Transport,
|
|
24
24
|
HandleValidationError,
|
|
25
|
-
RemoteFormIssue
|
|
25
|
+
RemoteFormIssue,
|
|
26
|
+
RemoteQuery
|
|
26
27
|
} from '@sveltejs/kit';
|
|
27
28
|
import {
|
|
28
29
|
HttpMethod,
|
|
@@ -593,6 +594,14 @@ interface BaseRemoteInternals {
|
|
|
593
594
|
export interface RemoteQueryInternals extends BaseRemoteInternals {
|
|
594
595
|
type: 'query';
|
|
595
596
|
validate: (arg?: any) => MaybePromise<any>;
|
|
597
|
+
/**
|
|
598
|
+
* Creates a `RemoteQuery` bound directly to a specific client payload (the
|
|
599
|
+
* stringified raw argument) and a pre-validated argument, skipping the query
|
|
600
|
+
* wrapper's re-validation step. Used by `requested(query)` to ensure
|
|
601
|
+
* `refresh()` / `set()` target the same cache key the client is listening on
|
|
602
|
+
* even when the schema transforms the input.
|
|
603
|
+
*/
|
|
604
|
+
bind(payload: string, arg: any): RemoteQuery<any>;
|
|
596
605
|
}
|
|
597
606
|
export interface RemoteQueryLiveInternals extends BaseRemoteInternals {
|
|
598
607
|
type: 'query_live';
|
|
@@ -663,7 +672,6 @@ export interface RequestState {
|
|
|
663
672
|
forms: null | Map<any, any>;
|
|
664
673
|
refreshes: null | Record<string, Promise<any>>;
|
|
665
674
|
requested: null | Map<string, string[]>;
|
|
666
|
-
validated: null | Map<string, Set<any>>;
|
|
667
675
|
};
|
|
668
676
|
readonly is_in_remote_function: boolean;
|
|
669
677
|
readonly is_in_render: boolean;
|
package/src/utils/page_nodes.js
CHANGED
package/src/utils/url.js
CHANGED
|
@@ -138,12 +138,12 @@ export function make_trackable(url, callback, search_params_callback, allow_hash
|
|
|
138
138
|
|
|
139
139
|
if (!BROWSER) {
|
|
140
140
|
// @ts-ignore
|
|
141
|
-
tracked[Symbol.for('nodejs.util.inspect.custom')] = (
|
|
141
|
+
tracked[Symbol.for('nodejs.util.inspect.custom')] = (_depth, opts, inspect) => {
|
|
142
142
|
return inspect(url, opts);
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
// @ts-ignore
|
|
146
|
-
tracked.searchParams[Symbol.for('nodejs.util.inspect.custom')] = (
|
|
146
|
+
tracked.searchParams[Symbol.for('nodejs.util.inspect.custom')] = (_depth, opts, inspect) => {
|
|
147
147
|
return inspect(url.searchParams, opts);
|
|
148
148
|
};
|
|
149
149
|
}
|
|
@@ -194,7 +194,7 @@ export function disable_search(url) {
|
|
|
194
194
|
function allow_nodejs_console_log(url) {
|
|
195
195
|
if (!BROWSER) {
|
|
196
196
|
// @ts-ignore
|
|
197
|
-
url[Symbol.for('nodejs.util.inspect.custom')] = (
|
|
197
|
+
url[Symbol.for('nodejs.util.inspect.custom')] = (_depth, opts, inspect) => {
|
|
198
198
|
return inspect(new URL(url), opts);
|
|
199
199
|
};
|
|
200
200
|
}
|
package/src/version.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -1426,16 +1426,27 @@ declare module '@sveltejs/kit' {
|
|
|
1426
1426
|
*/
|
|
1427
1427
|
export type ParamMatcher = (param: string) => boolean;
|
|
1428
1428
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1429
|
+
/**
|
|
1430
|
+
* A single entry yielded by [`requested`](https://svelte.dev/docs/kit/$app-server#requested).
|
|
1431
|
+
* `arg` is the validated argument (the input *after* the query's schema validated and
|
|
1432
|
+
* transformed it, if applicable); `query` is a `RemoteQuery` bound to the client's
|
|
1433
|
+
* original cache key, so `refresh()` / `set()` will update the correct client entry.
|
|
1434
|
+
*/
|
|
1435
|
+
export type RequestedEntry<Validated, Output> = {
|
|
1436
|
+
arg: Validated;
|
|
1437
|
+
query: RemoteQuery<Output>;
|
|
1438
|
+
};
|
|
1439
|
+
|
|
1440
|
+
export type RequestedResult<Validated, Output> = Iterable<RequestedEntry<Validated, Output>> &
|
|
1441
|
+
AsyncIterable<RequestedEntry<Validated, Output>> & {
|
|
1431
1442
|
/**
|
|
1432
1443
|
* Call `refresh` on all queries selected by this `requested` invocation.
|
|
1433
1444
|
* This is identical to:
|
|
1434
1445
|
* ```ts
|
|
1435
1446
|
* import { requested } from '$app/server';
|
|
1436
1447
|
*
|
|
1437
|
-
* for await (const
|
|
1438
|
-
* void query
|
|
1448
|
+
* for await (const { query } of requested(getPost, ...)) {
|
|
1449
|
+
* void query.refresh();
|
|
1439
1450
|
* }
|
|
1440
1451
|
* ```
|
|
1441
1452
|
*/
|
|
@@ -1987,11 +1998,15 @@ declare module '@sveltejs/kit' {
|
|
|
1987
1998
|
? RecursiveFormFields
|
|
1988
1999
|
: NonNullable<T> extends string | number | boolean | File
|
|
1989
2000
|
? RemoteFormField<NonNullable<T>>
|
|
1990
|
-
: // [T] is used to prevent distributing over union
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
2001
|
+
: // [NonNullable<T>] is used to prevent distributing over union while still allowing
|
|
2002
|
+
// nullable wrappers (e.g. `string[] | undefined` from a schema with `.default([])`)
|
|
2003
|
+
// to be treated as arrays; only the last condition should distribute over unions
|
|
2004
|
+
[NonNullable<T>] extends [string[] | File[]]
|
|
2005
|
+
? RemoteFormField<NonNullable<T>> & {
|
|
2006
|
+
[K in number]: RemoteFormField<NonNullable<T>[number]>;
|
|
2007
|
+
}
|
|
2008
|
+
: [NonNullable<T>] extends [Array<infer U>]
|
|
2009
|
+
? RemoteFormFieldContainer<NonNullable<T>> & {
|
|
1995
2010
|
[K in number]: RemoteFormFields<U>;
|
|
1996
2011
|
}
|
|
1997
2012
|
: RemoteFormFieldContainer<T> & {
|
|
@@ -2069,7 +2084,7 @@ declare module '@sveltejs/kit' {
|
|
|
2069
2084
|
submit: () => Promise<boolean> & {
|
|
2070
2085
|
updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
|
|
2071
2086
|
};
|
|
2072
|
-
}) => void
|
|
2087
|
+
}) => MaybePromise<void>
|
|
2073
2088
|
): {
|
|
2074
2089
|
method: 'POST';
|
|
2075
2090
|
action: string;
|
|
@@ -2195,8 +2210,17 @@ declare module '@sveltejs/kit' {
|
|
|
2195
2210
|
|
|
2196
2211
|
/**
|
|
2197
2212
|
* The return value of a remote `query` function. See [Remote functions](https://svelte.dev/docs/kit/remote-functions#query) for full documentation.
|
|
2213
|
+
*
|
|
2214
|
+
* The optional `Validated` generic parameter represents the argument type *after* the
|
|
2215
|
+
* query's schema has validated and (optionally) transformed it — this is the type the
|
|
2216
|
+
* query's implementation function receives on the server, and the type yielded by
|
|
2217
|
+
* [`requested`](https://svelte.dev/docs/kit/$app-server#requested). For queries declared
|
|
2218
|
+
* with [Standard Schema](https://standardschema.dev/) it differs from `Input` when the
|
|
2219
|
+
* schema contains a transform (e.g. `v.pipe(v.number(), v.transform(String))` has
|
|
2220
|
+
* `Input = number` but `Validated = string`). For `'unchecked'` validators and queries
|
|
2221
|
+
* without arguments it defaults to `Input`.
|
|
2198
2222
|
*/
|
|
2199
|
-
export type RemoteQueryFunction<Input, Output> = (
|
|
2223
|
+
export type RemoteQueryFunction<Input, Output, _Validated = Input> = (
|
|
2200
2224
|
arg: undefined extends Input ? Input | void : Input
|
|
2201
2225
|
) => RemoteQuery<Output>;
|
|
2202
2226
|
interface AdapterEntry {
|
|
@@ -3392,7 +3416,7 @@ declare module '$app/server' {
|
|
|
3392
3416
|
*
|
|
3393
3417
|
* @since 2.27
|
|
3394
3418
|
*/
|
|
3395
|
-
export function query<Schema extends StandardSchemaV1, Output>(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput<Schema>) => MaybePromise<Output>): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output
|
|
3419
|
+
export function query<Schema extends StandardSchemaV1, Output>(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput<Schema>) => MaybePromise<Output>): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output, StandardSchemaV1.InferOutput<Schema>>;
|
|
3396
3420
|
export namespace query {
|
|
3397
3421
|
/**
|
|
3398
3422
|
* Creates a batch query function that collects multiple calls and executes them in a single request
|
|
@@ -3409,23 +3433,29 @@ declare module '$app/server' {
|
|
|
3409
3433
|
*
|
|
3410
3434
|
* @since 2.35
|
|
3411
3435
|
*/
|
|
3412
|
-
function batch<Schema extends StandardSchemaV1, Output>(schema: Schema, fn: (args: StandardSchemaV1.InferOutput<Schema>[]) => MaybePromise<(arg: StandardSchemaV1.InferOutput<Schema>, idx: number) => Output>): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output
|
|
3436
|
+
function batch<Schema extends StandardSchemaV1, Output>(schema: Schema, fn: (args: StandardSchemaV1.InferOutput<Schema>[]) => MaybePromise<(arg: StandardSchemaV1.InferOutput<Schema>, idx: number) => Output>): RemoteQueryFunction<StandardSchemaV1.InferInput<Schema>, Output, StandardSchemaV1.InferOutput<Schema>>;
|
|
3413
3437
|
}
|
|
3414
3438
|
/**
|
|
3415
3439
|
* In the context of a remote `command` or `form` request, returns an iterable
|
|
3416
|
-
* of the
|
|
3417
|
-
*
|
|
3440
|
+
* of `{ arg, query }` entries for the refreshes requested by the client, up to
|
|
3441
|
+
* the supplied `limit`. Each `query` is a `RemoteQuery` bound to the original
|
|
3442
|
+
* client-side cache key, so `refresh()` / `set()` propagate correctly even when
|
|
3443
|
+
* the query's schema transforms the input. `arg` is the *validated* argument,
|
|
3444
|
+
* i.e. the value after the schema has run (so `InferOutput<Schema>` for queries
|
|
3445
|
+
* declared with a Standard Schema).
|
|
3446
|
+
*
|
|
3447
|
+
* Arguments that fail validation or exceed `limit` are recorded as failures in
|
|
3418
3448
|
* the response to the client.
|
|
3419
3449
|
*
|
|
3420
3450
|
* @example
|
|
3421
3451
|
* ```ts
|
|
3422
3452
|
* import { requested } from '$app/server';
|
|
3423
3453
|
*
|
|
3424
|
-
* for (const arg of requested(getPost, 5)) {
|
|
3425
|
-
* //
|
|
3426
|
-
* //
|
|
3427
|
-
* //
|
|
3428
|
-
* void
|
|
3454
|
+
* for (const { arg, query } of requested(getPost, 5)) {
|
|
3455
|
+
* // `arg` is the validated argument; `query` is bound to the client's
|
|
3456
|
+
* // cache key. It's safe to throw away this promise -- SvelteKit will
|
|
3457
|
+
* // await it and forward any errors to the client.
|
|
3458
|
+
* void query.refresh();
|
|
3429
3459
|
* }
|
|
3430
3460
|
* ```
|
|
3431
3461
|
*
|
|
@@ -3438,7 +3468,7 @@ declare module '$app/server' {
|
|
|
3438
3468
|
* ```
|
|
3439
3469
|
*
|
|
3440
3470
|
* */
|
|
3441
|
-
export function requested<Input, Output>(query: RemoteQueryFunction<Input, Output>, limit
|
|
3471
|
+
export function requested<Input, Output, Validated = Input>(query: RemoteQueryFunction<Input, Output, Validated>, limit: number): RequestedResult<Validated, Output>;
|
|
3442
3472
|
type RemotePrerenderInputsGenerator<Input = any> = () => MaybePromise<Input[]>;
|
|
3443
3473
|
type MaybePromise<T> = T | Promise<T>;
|
|
3444
3474
|
|
package/types/index.d.ts.map
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"AfterNavigate",
|
|
45
45
|
"Page",
|
|
46
46
|
"ParamMatcher",
|
|
47
|
+
"RequestedEntry",
|
|
47
48
|
"RequestedResult",
|
|
48
49
|
"RequestEvent",
|
|
49
50
|
"RequestHandler",
|
|
@@ -234,6 +235,6 @@
|
|
|
234
235
|
null,
|
|
235
236
|
null
|
|
236
237
|
],
|
|
237
|
-
"mappings": ";;;;;;;;MAiCKA,IAAIA;;;;;kBAKQC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCZC,cAAcA;;;;;;aAMdC,cAAcA;;;;;;;;MAQrBC,aAAaA;;;;;OAKJC,YAAYA;;kBAETC,aAAaA;;;;;;MAMzBC,qBAAqBA;;;;;;;;;;;kBAWTC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8IPC,MAAMA;;;;;;;;;;;kBAWNC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4DPC,QAAQA;;;;;;;;kBAQRC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAklBdC,MAAMA;;;;;;;;;;;aAWNC,iBAAiBA;;;;;;;;;;;;aAYjBC,qBAAqBA;;;;;;;;;aASrBC,iBAAiBA;;;;;;;;;;aAUjBC,WAAWA;;;;;;;;;;aAUXC,UAAUA;;;;;;aAMVC,UAAUA;;;;;;aAMVC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;aA0BPC,SAASA;;;;;kBAKJC,WAAWA;;;;;;;;;;;;aAYhBC,IAAIA;;;;;;;;;;;;kBAYCC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyHTC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0BfC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6CrBC,cAAcA;;kBAETC,cAAcA;;;;;;;;;;;;;;;;;;;;kBAoBdC,eAAeA;;;;;;;;;;;;;;;;;;aAkBpBC,kBAAkBA;;kBAEbC,cAAcA;;;;;;;;;;;;;;;kBAedC,eAAeA;;;;;;;;;;;;;;;kBAefC,oBAAoBA;;;;;;;;;;;;;;;;;;;;kBAoBpBC,kBAAkBA;;;;;;;;;;;;;;;;;;kBAkBlBC,cAAcA;;;;;;;;;;;;;;;;;;;;aAoBnBC,UAAUA;;;;;;;;;aASVC,cAAcA;;;;;;;;;;aAUdC,UAAUA;;;;;;;;;;;aAWVC,aAAaA;;;;;;;;;;;kBAWRC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8CTC,YAAYA
|
|
238
|
+
"mappings": ";;;;;;;;MAiCKA,IAAIA;;;;;kBAKQC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAiCZC,cAAcA;;;;;;aAMdC,cAAcA;;;;;;;;MAQrBC,aAAaA;;;;;OAKJC,YAAYA;;kBAETC,aAAaA;;;;;;MAMzBC,qBAAqBA;;;;;;;;;;;kBAWTC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8IPC,MAAMA;;;;;;;;;;;kBAWNC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4DPC,QAAQA;;;;;;;;kBAQRC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAklBdC,MAAMA;;;;;;;;;;;aAWNC,iBAAiBA;;;;;;;;;;;;aAYjBC,qBAAqBA;;;;;;;;;aASrBC,iBAAiBA;;;;;;;;;;aAUjBC,WAAWA;;;;;;;;;;aAUXC,UAAUA;;;;;;aAMVC,UAAUA;;;;;;aAMVC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;aA0BPC,SAASA;;;;;kBAKJC,WAAWA;;;;;;;;;;;;aAYhBC,IAAIA;;;;;;;;;;;;kBAYCC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAyHTC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;kBA0BfC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6CrBC,cAAcA;;kBAETC,cAAcA;;;;;;;;;;;;;;;;;;;;kBAoBdC,eAAeA;;;;;;;;;;;;;;;;;;aAkBpBC,kBAAkBA;;kBAEbC,cAAcA;;;;;;;;;;;;;;;kBAedC,eAAeA;;;;;;;;;;;;;;;kBAefC,oBAAoBA;;;;;;;;;;;;;;;;;;;;kBAoBpBC,kBAAkBA;;;;;;;;;;;;;;;;;;kBAkBlBC,cAAcA;;;;;;;;;;;;;;;;;;;;aAoBnBC,UAAUA;;;;;;;;;aASVC,cAAcA;;;;;;;;;;aAUdC,UAAUA;;;;;;;;;;;aAWVC,aAAaA;;;;;;;;;;;kBAWRC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8CTC,YAAYA;;;;;;;;aAQZC,cAAcA;;;;;aAKdC,eAAeA;;;;;;;;;;;;;;;;kBAgBVC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA+GjBC,cAAcA;;;;;kBAKTC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;kBAuBdC,eAAeA;;;;;;;;;;;;;;;cAenBC,MAAMA;;;;;;kBAMFC,iBAAiBA;;;;;;;kBAOjBC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;aAyBhBC,UAAUA;;;;;;;kBAOLC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAkFpBC,MAAMA;;;;;;;;;;aAUNC,OAAOA;;;;;;;;;;;;;;;;aAgBPC,YAAYA;;;;;;;;;;;;kBC1vDXC,SAASA;;;;;;;;;;kBAqBTC,QAAQA;;;;;;;aDkwDTC,cAAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA6BTC,QAAQA;;;;;;MAMpBC,uBAAuBA;;;MAGvBC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BLC,mBAAmBA;;;;;MAK1BC,iBAAiBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+CjBC,sBAAsBA;;;;;;;;;;;MAWtBC,WAAWA;MACXC,eAAeA;;;;;;aAMRC,oBAAoBA;;MAE3BC,MAAMA;;;;;;;;;;;;;aAaCC,eAAeA;;;;;;;;;;;;;;MActBC,wBAAwBA;;;;;MAKxBC,YAAYA;;;;;;;;;;;;;;;;;;MAkBZC,oBAAoBA;;;;;;;;;;;;;;;aAebC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;MAqBvBC,mBAAmBA;;;;MAInBC,UAAUA;;kBAEEC,eAAeA;;;;kBAIfC,eAAeA;;;;;;;MAO3BC,SAASA;;;;;;;;;;;;;aAaFC,YAAYA;;;;;;;;;;;;;;;;;;kBAkBPC,eAAeA;;;;;;;;aAQpBC,UAAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAuDVC,aAAaA;;;;;;;;aAQbC,iBAAiBA;;;;;aAKjBC,cAAcA;;;;;;;;;;;;;;;;;;aAkBdC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA2CXC,mBAAmBA;;;;;aAKnBC,uBAAuBA;;;;;;;;;;;;;;;;aAgBvBC,mBAAmBA;;;WElsEdC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAkDZC,GAAGA;;;;;;;;;;;;;;;;;;;;;WAqBHC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAmElBC,UAAUA;;WAELC,MAAMA;;;;;;;;;MASXC,YAAYA;;WAEPC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAmCXC,yBAAyBA;;;;;;;;;;WAUzBC,yBAAyBA;;;;WAIzBC,sCAAsCA;;;;WAItCC,4BAA4BA;;;;MAIjCC,8BAA8BA;MAC9BC,8BAA8BA;MAC9BC,iCAAiCA;;;;;MAKjCC,2CAA2CA;;;;;;aAM3CC,eAAeA;;WAIVC,cAAcA;;;;;WAKdC,YAAYA;;;;;;;MAOjBC,aAAaA;;MAEbC,WAAWA;;;;;;;;MAQXC,KAAKA;WCvMAC,KAAKA;;;;;;WAeLC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAuHTC,YAAYA;;;;;;;;;;;;;WAkBZC,QAAQA;;;;;;;;;;;;;;;;MAkCbC,iBAAiBA;;;;;;;;;WAWZC,UAAUA;;;;;;;;;;;;;WAaVC,SAASA;;;;;;;;;;;;;;;;;;;;;;;;;WAwITC,YAAYA;;;;;;;;;;;;;;;;;;;;MAoBjBC,kBAAkBA;;WAEbC,aAAaA;;;;;;;;;;;WAWbC,UAAUA;;;;;;;;;;;WAWVC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;MAyBZC,aAAaA;;WA+BRC,eAAeA;;;;;;MAMpBC,uBAAuBA;;MAGvBC,WAAWA;;;;;;;;WAQNC,QAAQA;;;;;;;;;WASRC,cAAcA;;;;;;;;;MA+CnBC,eAAeA;;;;;MAKfC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCzedC,WAAWA;;;;;;;;;;;;;;;;;;;iBAsBXC,QAAQA;;;;;iBAiBRC,UAAUA;;;;;;iBASVC,IAAIA;;;;;;iBA4BJC,IAAIA;;;;;;;;;;;;;;;;iBAkDJC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BfC,OAAOA;;;;;;iBAYPC,iBAAiBA;;;;;;;;;;;;;;iBAmBjBC,YAAYA;;;;;;;MCpQ2BC,eAAeA;MACjBC,WAAWA;OAd1DC,wBAAwBA;cCDjBC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC4EJC,QAAQA;;;;;;iBCyCFC,UAAUA;;;;;;iBAgDVC,WAAWA;;;;;iBAgFjBC,oBAAoBA;;;;;;;;;;;iBCtOpBC,gBAAgBA;;;;;;;;;;iBCuHVC,SAASA;;;;;;;;;cCtIlBC,OAAOA;;;;;cAKPC,GAAGA;;;;;cAKHC,QAAQA;;;;;cAKRC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;iBCaJC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;iBAgDXC,OAAOA;;;;;;;iBCm1EDC,WAAWA;;;;;;;;;;;iBA9UjBC,aAAaA;;;;;;;;;;;;iBAiBbC,cAAcA;;;;;;;;;;iBAedC,UAAUA;;;;;iBASVC,qBAAqBA;;;;;;;;;;iBA8BrBC,IAAIA;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCJC,UAAUA;;;;iBA0BVC,aAAaA;;;;;iBAebC,UAAUA;;;;;;;;;;;;;;iBAqBJC,WAAWA;;;;;;;;;;;;;;;;;;iBAoCXC,WAAWA;;;;;iBAsCjBC,SAASA;;;;;iBA+CTC,YAAYA;MX7tEhBzE,YAAYA;;;;;;;;;;;;;;YY/Ib0E,IAAIA;;;;;;;;;YASJC,MAAMA;;;;;iBAKDC,YAAYA;;;MCnBvBC,iBAAiBA;;;;;;MAMVC,WAAWA;;;;;;;;;;;;;;;;;;;;;;;;;;iBCWPC,KAAKA;;;;;;;;;;;;;;;;;;;;;iBA6BLC,OAAOA;;;;;;;;;;;;;;;;;;;iBAmCDC,KAAKA;;;;;;;;;;;;;;;;;;;;;;;iBCrEXC,IAAIA;;;;;;;;iBCSJC,eAAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCiBfC,SAASA;MhB8cbC,8BAA8BA;MDhW9BrF,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ckB1GXsF,IAAIA;;;;;cAQJC,UAAUA;;;;;;;;;;;cAMVC,OAAOA;;;;;;;;;iBCrDPC,SAASA;;;;;;;;;;;;;;;cAyBTH,IAAIA;;;;;;;;;;cAiBJC,UAAUA;;;;;;;;cAeVC,OAAOA",
|
|
238
239
|
"ignoreList": []
|
|
239
240
|
}
|