@sveltejs/kit 2.57.0 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "2.57.0",
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.3.5",
45
+ "vite": "^6.4.2",
46
46
  "vitest": "^4.0.0"
47
47
  },
48
48
  "peerDependencies": {
@@ -106,7 +106,7 @@ export function isHttpError(e, status) {
106
106
  * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number)} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
107
107
  * @param {string | URL} location The location to redirect to.
108
108
  * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location.
109
- * @throws {Error} If the provided status is invalid.
109
+ * @throws {Error} If the provided status is invalid or the location cannot be used as a header value.
110
110
  * @return {never}
111
111
  */
112
112
  export function redirect(status, location) {
@@ -27,6 +27,15 @@ export class Redirect {
27
27
  * @param {string} location
28
28
  */
29
29
  constructor(status, location) {
30
+ try {
31
+ new Headers({ location });
32
+ } catch {
33
+ throw new Error(
34
+ `Invalid redirect location ${JSON.stringify(location)}: ` +
35
+ 'this string contains characters that cannot be used in HTTP headers'
36
+ );
37
+ }
38
+
30
39
  this.status = status;
31
40
  this.location = location;
32
41
  }
@@ -16,10 +16,11 @@ function get_raw_body(req, body_size_limit) {
16
16
  }
17
17
 
18
18
  const content_length = Number(h['content-length']);
19
+ const has_content_length = Number.isFinite(content_length);
19
20
 
20
21
  // check if no request body
21
22
  if (
22
- (req.httpVersionMajor === 1 && isNaN(content_length) && h['transfer-encoding'] == null) ||
23
+ (req.httpVersionMajor === 1 && !has_content_length && h['transfer-encoding'] == null) ||
23
24
  content_length === 0
24
25
  ) {
25
26
  return null;
@@ -36,7 +37,7 @@ function get_raw_body(req, body_size_limit) {
36
37
 
37
38
  return new ReadableStream({
38
39
  start(controller) {
39
- if (body_size_limit !== undefined && content_length > body_size_limit) {
40
+ if (body_size_limit !== undefined && has_content_length && content_length > body_size_limit) {
40
41
  let message = `Content-length of ${content_length} exceeds limit of ${body_size_limit} bytes.`;
41
42
 
42
43
  if (body_size_limit === 0) {
@@ -65,11 +66,22 @@ function get_raw_body(req, body_size_limit) {
65
66
  if (cancelled) return;
66
67
 
67
68
  size += chunk.length;
68
- if (size > content_length) {
69
+
70
+ if (body_size_limit !== undefined && size > body_size_limit) {
71
+ cancelled = true;
72
+
73
+ const message = `request body size exceeded BODY_SIZE_LIMIT of ${body_size_limit}`;
74
+
75
+ const error = new SvelteKitError(413, 'Payload Too Large', message);
76
+ controller.error(error);
77
+
78
+ return;
79
+ }
80
+
81
+ if (has_content_length && size > content_length) {
69
82
  cancelled = true;
70
83
 
71
- const constraint = content_length ? 'content-length' : 'BODY_SIZE_LIMIT';
72
- const message = `request body size exceeded ${constraint} of ${content_length}`;
84
+ const message = `request body size exceeded content-length of ${content_length}`;
73
85
 
74
86
  const error = new SvelteKitError(413, 'Payload Too Large', message);
75
87
  controller.error(error);
@@ -1452,16 +1452,27 @@ export interface Page<
1452
1452
  */
1453
1453
  export type ParamMatcher = (param: string) => boolean;
1454
1454
 
1455
- export type RequestedResult<T> = Iterable<T> &
1456
- AsyncIterable<T> & {
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 arg of requested(query, ...) {
1464
- * void query(arg).refresh();
1474
+ * for await (const { query } of requested(getPost, ...)) {
1475
+ * void query.refresh();
1465
1476
  * }
1466
1477
  * ```
1467
1478
  */
@@ -1932,6 +1943,15 @@ type RemoteFormFieldMethods<T> = {
1932
1943
  issues(): RemoteFormIssue[] | undefined;
1933
1944
  };
1934
1945
 
1946
+ // These two types use "T extends unknown ? .. : .." to distribute over unions.
1947
+ // Example: if "type T = A | b" then "keyof T" only contains keys that both A and B have, with "KeysOfUnion<T>" we get the keys of both A and B
1948
+ type KeysOfUnion<T> = T extends unknown ? keyof T : never;
1949
+ type ValueOfUnionKey<T, K extends PropertyKey> = T extends unknown
1950
+ ? K extends keyof T
1951
+ ? T[K]
1952
+ : never
1953
+ : never;
1954
+
1935
1955
  export type RemoteFormFieldValue = string | string[] | number | boolean | File | File[];
1936
1956
 
1937
1957
  type AsArgs<Type extends keyof InputTypeMap, Value> = Type extends 'checkbox'
@@ -2004,14 +2024,19 @@ export type RemoteFormFields<T> =
2004
2024
  ? RecursiveFormFields
2005
2025
  : NonNullable<T> extends string | number | boolean | File
2006
2026
  ? RemoteFormField<NonNullable<T>>
2007
- : T extends string[] | File[]
2008
- ? RemoteFormField<T> & { [K in number]: RemoteFormField<T[number]> }
2009
- : T extends Array<infer U>
2010
- ? RemoteFormFieldContainer<T> & {
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>> & {
2011
2036
  [K in number]: RemoteFormFields<U>;
2012
2037
  }
2013
2038
  : RemoteFormFieldContainer<T> & {
2014
- [K in keyof T]-?: RemoteFormFields<T[K]>;
2039
+ [K in KeysOfUnion<T>]-?: RemoteFormFields<ValueOfUnionKey<T, K>>;
2015
2040
  };
2016
2041
 
2017
2042
  // By breaking this out into its own type, we avoid the TS recursion depth limit
@@ -2085,7 +2110,7 @@ export type RemoteForm<Input extends RemoteFormInput | void, Output> = {
2085
2110
  submit: () => Promise<boolean> & {
2086
2111
  updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
2087
2112
  };
2088
- }) => void
2113
+ }) => MaybePromise<void>
2089
2114
  ): {
2090
2115
  method: 'POST';
2091
2116
  action: string;
@@ -2211,8 +2236,17 @@ export type RemotePrerenderFunction<Input, Output> = (
2211
2236
 
2212
2237
  /**
2213
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`.
2214
2248
  */
2215
- export type RemoteQueryFunction<Input, Output> = (
2249
+ export type RemoteQueryFunction<Input, Output, _Validated = Input> = (
2216
2250
  arg: undefined extends Input ? Input | void : Input
2217
2251
  ) => RemoteQuery<Output>;
2218
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(__, arg, state, async () => {
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[key] ??= {
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(__, arg, state, () =>
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 __ = { type: 'query', id: '', name: '', validate };
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
- // if the user got this argument from `requested(query)`, it will have already passed validation
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(__, arg, state, () =>
81
- run_remote_function(event, state, false, () => (is_validated ? arg : validate(arg)), fn)
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(__, arg, state, () => {
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 key = stringify_remote_arg(arg, state.transport);
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(key, {
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 {any} arg
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(__, arg, state, fn) {
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(__, arg, state, fn));
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', arg);
306
- const is_immediate_refresh = !refresh_context.cache[refresh_context.cache_key];
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(__, arg, state, fn);
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', arg), value);
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 {any} [arg]
345
- * @returns {{ __: RemoteInternals; state: any; refreshes: Record<string, Promise<any>>; cache: Record<string, { serialize: boolean; data: any }>; refreshes_key: string; cache_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, arg) {
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 cache_key = stringify_remote_arg(arg, state.transport);
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, cache_key };
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; cache_key: string }} context
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, cache_key },
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[cache_key] = { serialize: true, data: promise };
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 client-requested refreshes' validated arguments up to the supplied limit.
11
- * Arguments that fail validation or exceed the limit are recorded as failures in
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
- * // it's safe to throw away this promise -- SvelteKit
20
- * // will await it for us and handle any errors by sending
21
- * // them to the client.
22
- * void getPost(arg).refresh();
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
- * @param {RemoteQueryFunction<Input, Output>} query
37
- * @param {number} [limit=Infinity]
38
- * @returns {RequestedResult<Input>}
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 = Infinity) {
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 mark_argument_validated(internals, state, validated);
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 mark_argument_validated(internals, state, validated);
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 arg of this) {
109
- void query(arg).refresh();
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 {any} arg
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, arg, state, get_result) {
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 key = stringify_remote_arg(arg, state.transport);
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, key);
85
+ const remote_key = create_remote_key(internals.id, payload);
92
86
 
93
87
  Promise.resolve(entry.data)
94
88
  .then((value) => {
@@ -1188,7 +1188,7 @@ async function load_route({ id, invalidating, url, params, route, preload }) {
1188
1188
 
1189
1189
  const server_data_node = server_data_nodes?.[i];
1190
1190
 
1191
- // re-use data from previous load if it's still valid
1191
+ // reuse data from previous load if it's still valid
1192
1192
  const valid =
1193
1193
  (!server_data_node || server_data_node.type === 'skip') &&
1194
1194
  loader[1] === previous?.loader &&
@@ -35,8 +35,8 @@ export function command(id) {
35
35
  // Increment pending count when command starts
36
36
  pending_count++;
37
37
 
38
- // Noone should call commands during rendering but belts and braces.
39
- // Do this here, after await Svelte' reactivity context is gone.
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.#get_cached_query().current;
508
+ return this.#safe_get_cached_query()?.current;
538
509
  }
539
510
 
540
511
  get error() {
541
- return this.#get_cached_query().error;
512
+ return this.#safe_get_cached_query()?.error;
542
513
  }
543
514
 
544
515
  get loading() {
545
- return this.#get_cached_query().loading;
516
+ return this.#safe_get_cached_query()?.loading ?? false;
546
517
  }
547
518
 
548
519
  get ready() {
549
- return this.#get_cached_query().ready;
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 exists = Object.hasOwn(current, key);
507
- const inner = current[key];
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]}`);
@@ -714,7 +714,7 @@ export function create_field_proxy(target, get_input, set_input, get_issues, pat
714
714
  value: {
715
715
  enumerable: true,
716
716
  get() {
717
- return input_value !== undefined ? input_value : get_value();
717
+ return get_value() ?? input_value;
718
718
  }
719
719
  }
720
720
  });
@@ -800,7 +800,7 @@ export function create_field_proxy(target, get_input, set_input, get_issues, pat
800
800
  value: {
801
801
  enumerable: true,
802
802
  get() {
803
- const value = input_value !== undefined ? input_value : get_value();
803
+ const value = get_value() ?? input_value;
804
804
  return value != null ? String(value) : '';
805
805
  }
806
806
  }
@@ -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 {import('@sveltejs/kit').RequestEvent} event
29
- * @param {import('types').RequestState} event_state
30
- * @param {import('types').PageNodeIndexes} page
31
- * @param {import('types').SSROptions} options
32
- * @param {import('@sveltejs/kit').SSRManifest} manifest
33
- * @param {import('types').SSRState} state
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 {import('types').RequiredResolveOptions} resolve_opts
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 {import('types').SSRNode} */ (nodes.page());
63
+ const leaf_node = /** @type {SSRNode} */ (nodes.page());
62
64
 
63
65
  let status = 200;
64
66
 
65
- /** @type {import('@sveltejs/kit').ActionResult | undefined} */
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
- branch: [],
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<import('types').ServerDataNode | null>>} */
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: !ssr ? [] : compact(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 {import('types').SSROptions} options
401
+ * @param {SSROptions} options
392
402
  * @param {boolean} ssr
393
403
  * @param {Array<import('./types.js').Loaded | null>} branch
394
- * @param {import('types').PageNodeIndexes} page
395
- * @param {import('@sveltejs/kit').SSRManifest} manifest
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<import('types').SSRComponent | undefined> | undefined} */
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
- for (const { node } of branch) {
272
- for (const url of node.imports) modulepreloads.add(url);
273
- for (const url of node.stylesheets) stylesheets.add(url);
274
- for (const url of node.fonts) fonts.add(url);
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
- if (node.inline_styles && !client.inline) {
277
- Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
278
- if (typeof css === 'string') {
279
- inline_styles.set(filename, css);
280
- return;
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
- inline_styles.set(filename, css(`${assets}/${paths.app_dir}/immutable/assets`, assets));
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.split('<!--').length < html.split('<!--').length) {
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,
@@ -525,14 +520,18 @@ export async function internal_respond(request, options, manifest, state) {
525
520
  return response;
526
521
  } catch (e) {
527
522
  if (e instanceof Redirect) {
528
- const response =
529
- is_data_request || remote_id
530
- ? redirect_json_response(e)
531
- : route?.page && is_action_json_request(event)
532
- ? action_json_redirect(e)
533
- : redirect_response(e.status, e.location);
534
- add_cookies_to_headers(response.headers, new_cookies.values());
535
- return response;
523
+ try {
524
+ const response =
525
+ is_data_request || remote_id
526
+ ? redirect_json_response(e)
527
+ : route?.page && is_action_json_request(event)
528
+ ? action_json_redirect(e)
529
+ : redirect_response(e.status, e.location);
530
+ add_cookies_to_headers(response.headers, new_cookies.values());
531
+ return response;
532
+ } catch (err) {
533
+ return await handle_fatal_error(event, event_state, options, err);
534
+ }
536
535
  }
537
536
  return await handle_fatal_error(event, event_state, options, e);
538
537
  }
@@ -562,7 +561,14 @@ export async function internal_respond(request, options, manifest, state) {
562
561
  page_config: { ssr: false, csr: true },
563
562
  status: 200,
564
563
  error: null,
565
- 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
+ ],
566
572
  fetched: [],
567
573
  resolve_opts,
568
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
+ }
@@ -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 = new TextEncoder().encode(json_string);
264
+ const bytes = text_encoder.encode(json_string);
265
265
  return base64_encode(bytes).replaceAll('=', '').replaceAll('+', '-').replaceAll('/', '_');
266
266
  }
267
267
 
@@ -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;
@@ -6,6 +6,7 @@ import {
6
6
  } from './exports.js';
7
7
 
8
8
  export class PageNodes {
9
+ /** All layout nodes and the page node, if any */
9
10
  data;
10
11
 
11
12
  /**
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')] = (depth, opts, inspect) => {
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')] = (depth, opts, inspect) => {
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')] = (depth, opts, inspect) => {
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
@@ -1,4 +1,4 @@
1
1
  // generated during release, do not modify
2
2
 
3
3
  /** @type {string} */
4
- export const VERSION = '2.57.0';
4
+ export const VERSION = '2.58.0';
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
- export type RequestedResult<T> = Iterable<T> &
1430
- AsyncIterable<T> & {
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 arg of requested(query, ...) {
1438
- * void query(arg).refresh();
1448
+ * for await (const { query } of requested(getPost, ...)) {
1449
+ * void query.refresh();
1439
1450
  * }
1440
1451
  * ```
1441
1452
  */
@@ -1906,6 +1917,15 @@ declare module '@sveltejs/kit' {
1906
1917
  issues(): RemoteFormIssue[] | undefined;
1907
1918
  };
1908
1919
 
1920
+ // These two types use "T extends unknown ? .. : .." to distribute over unions.
1921
+ // Example: if "type T = A | b" then "keyof T" only contains keys that both A and B have, with "KeysOfUnion<T>" we get the keys of both A and B
1922
+ type KeysOfUnion<T> = T extends unknown ? keyof T : never;
1923
+ type ValueOfUnionKey<T, K extends PropertyKey> = T extends unknown
1924
+ ? K extends keyof T
1925
+ ? T[K]
1926
+ : never
1927
+ : never;
1928
+
1909
1929
  export type RemoteFormFieldValue = string | string[] | number | boolean | File | File[];
1910
1930
 
1911
1931
  type AsArgs<Type extends keyof InputTypeMap, Value> = Type extends 'checkbox'
@@ -1978,14 +1998,19 @@ declare module '@sveltejs/kit' {
1978
1998
  ? RecursiveFormFields
1979
1999
  : NonNullable<T> extends string | number | boolean | File
1980
2000
  ? RemoteFormField<NonNullable<T>>
1981
- : T extends string[] | File[]
1982
- ? RemoteFormField<T> & { [K in number]: RemoteFormField<T[number]> }
1983
- : T extends Array<infer U>
1984
- ? RemoteFormFieldContainer<T> & {
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>> & {
1985
2010
  [K in number]: RemoteFormFields<U>;
1986
2011
  }
1987
2012
  : RemoteFormFieldContainer<T> & {
1988
- [K in keyof T]-?: RemoteFormFields<T[K]>;
2013
+ [K in KeysOfUnion<T>]-?: RemoteFormFields<ValueOfUnionKey<T, K>>;
1989
2014
  };
1990
2015
 
1991
2016
  // By breaking this out into its own type, we avoid the TS recursion depth limit
@@ -2059,7 +2084,7 @@ declare module '@sveltejs/kit' {
2059
2084
  submit: () => Promise<boolean> & {
2060
2085
  updates: (...updates: RemoteQueryUpdate[]) => Promise<boolean>;
2061
2086
  };
2062
- }) => void
2087
+ }) => MaybePromise<void>
2063
2088
  ): {
2064
2089
  method: 'POST';
2065
2090
  action: string;
@@ -2185,8 +2210,17 @@ declare module '@sveltejs/kit' {
2185
2210
 
2186
2211
  /**
2187
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`.
2188
2222
  */
2189
- export type RemoteQueryFunction<Input, Output> = (
2223
+ export type RemoteQueryFunction<Input, Output, _Validated = Input> = (
2190
2224
  arg: undefined extends Input ? Input | void : Input
2191
2225
  ) => RemoteQuery<Output>;
2192
2226
  interface AdapterEntry {
@@ -2718,7 +2752,7 @@ declare module '@sveltejs/kit' {
2718
2752
  * @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
2719
2753
  * @param location The location to redirect to.
2720
2754
  * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location.
2721
- * @throws {Error} If the provided status is invalid.
2755
+ * @throws {Error} If the provided status is invalid or the location cannot be used as a header value.
2722
2756
  * */
2723
2757
  export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never;
2724
2758
  /**
@@ -3382,7 +3416,7 @@ declare module '$app/server' {
3382
3416
  *
3383
3417
  * @since 2.27
3384
3418
  */
3385
- 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>>;
3386
3420
  export namespace query {
3387
3421
  /**
3388
3422
  * Creates a batch query function that collects multiple calls and executes them in a single request
@@ -3399,23 +3433,29 @@ declare module '$app/server' {
3399
3433
  *
3400
3434
  * @since 2.35
3401
3435
  */
3402
- 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>>;
3403
3437
  }
3404
3438
  /**
3405
3439
  * In the context of a remote `command` or `form` request, returns an iterable
3406
- * of the client-requested refreshes' validated arguments up to the supplied limit.
3407
- * Arguments that fail validation or exceed the limit are recorded as failures in
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
3408
3448
  * the response to the client.
3409
3449
  *
3410
3450
  * @example
3411
3451
  * ```ts
3412
3452
  * import { requested } from '$app/server';
3413
3453
  *
3414
- * for (const arg of requested(getPost, 5)) {
3415
- * // it's safe to throw away this promise -- SvelteKit
3416
- * // will await it for us and handle any errors by sending
3417
- * // them to the client.
3418
- * void getPost(arg).refresh();
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();
3419
3459
  * }
3420
3460
  * ```
3421
3461
  *
@@ -3428,7 +3468,7 @@ declare module '$app/server' {
3428
3468
  * ```
3429
3469
  *
3430
3470
  * */
3431
- export function requested<Input, Output>(query: RemoteQueryFunction<Input, Output>, limit?: number): RequestedResult<Input>;
3471
+ export function requested<Input, Output, Validated = Input>(query: RemoteQueryFunction<Input, Output, Validated>, limit: number): RequestedResult<Validated, Output>;
3432
3472
  type RemotePrerenderInputsGenerator<Input = any> = () => MaybePromise<Input[]>;
3433
3473
  type MaybePromise<T> = T | Promise<T>;
3434
3474
 
@@ -44,6 +44,7 @@
44
44
  "AfterNavigate",
45
45
  "Page",
46
46
  "ParamMatcher",
47
+ "RequestedEntry",
47
48
  "RequestedResult",
48
49
  "RequestEvent",
49
50
  "RequestHandler",
@@ -66,6 +67,8 @@
66
67
  "RemoteFormFieldType",
67
68
  "InputElementProps",
68
69
  "RemoteFormFieldMethods",
70
+ "KeysOfUnion",
71
+ "ValueOfUnionKey",
69
72
  "RemoteFormFieldValue",
70
73
  "AsArgs",
71
74
  "RemoteFormField",
@@ -232,6 +235,6 @@
232
235
  null,
233
236
  null
234
237
  ],
235
- "mappings": "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",
238
+ "mappings": "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",
236
239
  "ignoreList": []
237
240
  }