Skip to content

Commit 3d9b855

Browse files
feat: add universal IDs to client nodes
1 parent 3459122 commit 3d9b855

File tree

5 files changed

+40
-37
lines changed

5 files changed

+40
-37
lines changed

packages/kit/src/core/sync/write_client_manifest.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export function write_client_manifest(kit, manifest_data, output, metadata) {
2929
);
3030
}
3131

32+
if (kit.tracing === 'client' || kit.tracing === true) {
33+
// we don't need to include these if tracing is disabled -- they make the manifest bigger
34+
declarations.push(`export const universal_id = ${s(node.universal)};`);
35+
}
36+
3237
if (node.component) {
3338
declarations.push(
3439
`export { default as component } from ${s(

packages/kit/src/runtime/client/client.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ import {
3636
import { validate_page_exports } from '../../utils/exports.js';
3737
import { compact } from '../../utils/array.js';
3838
import { HttpError, Redirect, SvelteKitError } from '../control.js';
39-
import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../shared.js';
39+
import {
40+
INVALIDATED_PARAM,
41+
TRAILING_SLASH_PARAM,
42+
validate_depends,
43+
validate_load_response
44+
} from '../shared.js';
4045
import { get_message, get_status } from '../../utils/error.js';
4146
import { writable } from 'svelte/store';
4247
import { page, update, navigating } from './state.svelte.js';
@@ -776,19 +781,11 @@ async function load_node({ loader, parent, url, params, route, server_data_node
776781
lock_fetch();
777782
data = await traced_load();
778783

779-
if (data != null && Object.getPrototypeOf(data) !== Object.prototype) {
780-
throw new Error(
781-
`the load function located in ${node.universal_id} returned ${
782-
typeof data !== 'object'
783-
? `a ${typeof data}`
784-
: data instanceof Response
785-
? 'a Response object'
786-
: Array.isArray(data)
787-
? 'an array'
788-
: 'a non-plain object'
789-
}, but must return a plain object at the top level (i.e. \`return {...}\`)`
790-
);
791-
}
784+
validate_load_response(
785+
data,
786+
// universal_id isn't populated if tracing is disabled because it adds otherwise unnecessary bloat to the manifest
787+
node.universal_id ? `in ${node.universal_id}` : `related to route '${route.id}'`
788+
);
792789
} finally {
793790
unlock_fetch();
794791
}

packages/kit/src/runtime/server/page/load_data.js

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DEV } from 'esm-env';
22
import { disable_search, make_trackable } from '../../../utils/url.js';
3-
import { validate_depends } from '../../shared.js';
3+
import { validate_depends, validate_load_response } from '../../shared.js';
44
import { b64_encode } from '../../utils.js';
55
import { with_event } from '../../app/server/event.js';
66
import { record_span } from '../../telemetry/record_span.js';
@@ -176,7 +176,7 @@ export async function load_server_data({ event, state, node, parent, tracing })
176176
});
177177

178178
if (__SVELTEKIT_DEV__) {
179-
validate_load_response(result, node.server_id);
179+
validate_load_response(result, `in ${node.server_id}`);
180180
}
181181

182182
done = true;
@@ -252,7 +252,7 @@ export async function load_data({
252252
});
253253

254254
if (__SVELTEKIT_DEV__) {
255-
validate_load_response(result, node.universal_id);
255+
validate_load_response(result, `in ${node.universal_id}`);
256256
}
257257

258258
return result ?? null;
@@ -436,23 +436,3 @@ async function stream_to_string(stream) {
436436
}
437437
return result;
438438
}
439-
440-
/**
441-
* @param {any} data
442-
* @param {string} [id]
443-
*/
444-
function validate_load_response(data, id) {
445-
if (data != null && Object.getPrototypeOf(data) !== Object.prototype) {
446-
throw new Error(
447-
`a load function in ${id} returned ${
448-
typeof data !== 'object'
449-
? `a ${typeof data}`
450-
: data instanceof Response
451-
? 'a Response object'
452-
: Array.isArray(data)
453-
? 'an array'
454-
: 'a non-plain object'
455-
}, but must return a plain object at the top level (i.e. \`return {...}\`)`
456-
);
457-
}
458-
}

packages/kit/src/runtime/shared.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,23 @@ export function validate_depends(route_id, dep) {
1414
export const INVALIDATED_PARAM = 'x-sveltekit-invalidated';
1515

1616
export const TRAILING_SLASH_PARAM = 'x-sveltekit-trailing-slash';
17+
18+
/**
19+
* @param {any} data
20+
* @param {string} [location_description]
21+
*/
22+
export function validate_load_response(data, location_description) {
23+
if (data != null && Object.getPrototypeOf(data) !== Object.prototype) {
24+
throw new Error(
25+
`a load function ${location_description} returned ${
26+
typeof data !== 'object'
27+
? `a ${typeof data}`
28+
: data instanceof Response
29+
? 'a Response object'
30+
: Array.isArray(data)
31+
? 'an array'
32+
: 'a non-plain object'
33+
}, but must return a plain object at the top level (i.e. \`return {...}\`)`
34+
);
35+
}
36+
}

packages/kit/src/types/internal.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ export interface CSRPageNode {
111111
load?: Load;
112112
trailingSlash?: TrailingSlash;
113113
};
114+
universal_id?: string;
114115
}
115116

116117
export type CSRPageNodeLoader = () => Promise<CSRPageNode>;

0 commit comments

Comments
 (0)