From 2b077b5ba6d72bbe08643ffa3acf43d642140ac6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 8 Dec 2023 23:04:31 -0500 Subject: [PATCH 1/2] remove promise awaiting --- .changeset/real-brooms-jog.md | 5 ++ packages/kit/src/runtime/client/client.js | 2 - .../kit/src/runtime/server/page/load_data.js | 5 +- packages/kit/src/utils/promises.js | 61 ------------------- .../fetch-cache-control/headers-diff/+page.js | 4 +- 5 files changed, 9 insertions(+), 68 deletions(-) create mode 100644 .changeset/real-brooms-jog.md delete mode 100644 packages/kit/src/utils/promises.js diff --git a/.changeset/real-brooms-jog.md b/.changeset/real-brooms-jog.md new file mode 100644 index 000000000000..d915d7a83f98 --- /dev/null +++ b/.changeset/real-brooms-jog.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': major +--- + +breaking: stop awaiting top-level promises returned from load functions diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 5afcd6e63bda..b2cc0a7b5fcc 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -30,7 +30,6 @@ import { base } from '__sveltekit/paths'; import * as devalue from 'devalue'; import { compact } from '../../utils/array.js'; import { validate_page_exports } from '../../utils/exports.js'; -import { unwrap_promises } from '../../utils/promises.js'; import { HttpError, Redirect } from '../control.js'; import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../shared.js'; import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY, SNAPSHOT_KEY } from './constants.js'; @@ -555,7 +554,6 @@ export function create_client(app, target) { } else { data = (await node.universal.load.call(null, load_input)) ?? null; } - data = data ? await unwrap_promises(data, route.id) : null; } return { diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index d8be3ff6b9c8..20c3a9457234 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,5 +1,4 @@ import { disable_search, make_trackable } from '../../../utils/url.js'; -import { unwrap_promises } from '../../../utils/promises.js'; import { DEV } from 'esm-env'; import { validate_depends } from '../../shared.js'; @@ -125,7 +124,7 @@ export async function load_server_data({ url }); - const data = result ? await unwrap_promises(result, node.server_id) : null; + const data = result ?? null; if (__SVELTEKIT_DEV__) { validate_load_response(data, node.server_id); } @@ -181,7 +180,7 @@ export async function load_data({ parent }); - const data = result ? await unwrap_promises(result, node.universal_id) : null; + const data = result ?? null; if (__SVELTEKIT_DEV__) { validate_load_response(data, node.universal_id); } diff --git a/packages/kit/src/utils/promises.js b/packages/kit/src/utils/promises.js deleted file mode 100644 index ab9286722747..000000000000 --- a/packages/kit/src/utils/promises.js +++ /dev/null @@ -1,61 +0,0 @@ -import { DEV } from 'esm-env'; - -/** @type {Set | null} */ -let warned = null; - -// TODO v2: remove all references to unwrap_promises - -/** - * Given an object, return a new object where all top level values are awaited - * - * @param {Record} object - * @param {string | null} [id] - * @returns {Promise>} - */ -export async function unwrap_promises(object, id) { - if (DEV) { - /** @type {string[]} */ - const promises = []; - - for (const key in object) { - if (typeof object[key]?.then === 'function') { - promises.push(key); - } - } - - if (promises.length > 0) { - if (!warned) warned = new Set(); - - const last = promises.pop(); - - const properties = - promises.length > 0 - ? `${promises.map((p) => `"${p}"`).join(', ')} and "${last}" properties` - : `"${last}" property`; - - const location = id ? `the \`load\` function in ${id}` : 'a `load` function'; - - const description = promises.length > 0 ? 'are promises' : 'is a promise'; - - const message = `The top-level ${properties} returned from ${location} ${description}.`; - - if (!warned.has(message)) { - console.warn( - `\n${message}\n\nIn SvelteKit 2.0, these will longer be awaited automatically. To get rid of this warning, await all promises included as top-level properties in \`load\` return values.\n` - ); - - warned.add(message); - } - } - } - - for (const key in object) { - if (typeof object[key]?.then === 'function') { - return Object.fromEntries( - await Promise.all(Object.entries(object).map(async ([key, value]) => [key, await value])) - ); - } - } - - return object; -} diff --git a/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js b/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js index b64c9e0a9a68..5e2505fc57ec 100644 --- a/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js +++ b/packages/kit/test/apps/basics/src/routes/load/fetch-cache-control/headers-diff/+page.js @@ -12,7 +12,7 @@ export async function load({ fetch, url }) { }); return { - a: r1.json(), - b: r2.json() + a: await r1.json(), + b: await r2.json() }; } From e9cf405193137504ffaa7989d66a3a0eedb4af81 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 8 Dec 2023 23:06:54 -0500 Subject: [PATCH 2/2] update types --- packages/kit/src/core/sync/write_types/index.js | 2 +- packages/kit/src/exports/public.d.ts | 5 ----- packages/kit/test/types/load.test.ts | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/kit/src/core/sync/write_types/index.js b/packages/kit/src/core/sync/write_types/index.js index d21030e01109..affb9f5c1196 100644 --- a/packages/kit/src/core/sync/write_types/index.js +++ b/packages/kit/src/core/sync/write_types/index.js @@ -480,7 +480,7 @@ function process_node(node, outdir, is_page, proxies, all_pages_have_load = true const from = proxy.modified ? `./proxy${replace_ext_with_js(path.basename(file_path))}` : path_to_original(outdir, file_path); - const type = `Kit.AwaitedProperties>>`; + const type = `Awaited>`; return expand ? `Expand>>` : type; } else { return fallback; diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 0b16948b1d73..6d0bc1564801 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -49,11 +49,6 @@ type AwaitedPropertiesUnion | void> = input ex ? input : unknown; -export type AwaitedProperties | void> = - AwaitedPropertiesUnion extends Record - ? OptionalUnion> - : AwaitedPropertiesUnion; - export type AwaitedActions any>> = OptionalUnion< { [Key in keyof T]: UnpackValidationError>>; diff --git a/packages/kit/test/types/load.test.ts b/packages/kit/test/types/load.test.ts index 321d70931bdd..7447de022f9c 100644 --- a/packages/kit/test/types/load.test.ts +++ b/packages/kit/test/types/load.test.ts @@ -3,7 +3,7 @@ import Kit, { Deferred } from '@sveltejs/kit'; // Test: Return types inferred correctly and transformed into a union type LoadReturn1 = { success: true } | { message: Promise }; -let result1: Kit.AwaitedProperties = null as any; +let result1: LoadReturn1 = null as any; result1.message = ''; result1.success = true; // @ts-expect-error - cannot both be present at the same time @@ -12,7 +12,7 @@ result1 = { message: '', success: true }; // Test: Return types keep promise for Deferred type LoadReturn2 = { success: true } | Deferred<{ message: Promise; eager: true }>; -let result2: Kit.AwaitedProperties = null as any; +let result2: LoadReturn2 = null as any; result2.message = Promise.resolve(''); result2.eager = true; result2.success = true;