@sveltejs/kit 3.0.0-next.14 → 3.0.0-next.16
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 +6 -3
- package/src/cli.js +6 -3
- package/src/core/adapt/builder.js +12 -5
- package/src/core/config/index.js +4 -5
- package/src/core/env.js +3 -3
- package/src/core/postbuild/prerender.js +6 -10
- package/src/core/sync/sync.js +3 -2
- package/src/core/sync/utils.js +2 -2
- package/src/core/sync/write_tsconfig/index.js +71 -53
- package/src/core/sync/write_tsconfig/utils.js +0 -61
- package/src/core/sync/write_tsconfig/validate.js +128 -0
- package/src/core/sync/write_types/index.js +2 -2
- package/src/exports/public.d.ts +22 -16
- package/src/exports/vite/build/build_server.js +2 -3
- package/src/exports/vite/dev/index.js +44 -36
- package/src/exports/vite/index.js +46 -5
- package/src/exports/vite/utils.js +61 -8
- package/src/runner.js +4 -2
- package/src/runtime/app/forms.js +4 -7
- package/src/runtime/app/internal/transport.js +53 -0
- package/src/runtime/app/paths/client.js +2 -2
- package/src/runtime/app/paths/internal/client.js +2 -2
- package/src/runtime/app/server/remote/prerender.js +6 -10
- package/src/runtime/app/server/remote/query.js +3 -3
- package/src/runtime/app/server/remote/requested.js +2 -2
- package/src/runtime/app/server/remote/shared.js +1 -16
- package/src/runtime/client/client.js +29 -25
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/client/remote-functions/command.svelte.js +1 -2
- package/src/runtime/client/remote-functions/prerender.svelte.js +1 -1
- package/src/runtime/client/remote-functions/query/proxy.js +2 -2
- package/src/runtime/client/remote-functions/query-live/proxy.js +2 -2
- package/src/runtime/pathname.js +7 -1
- package/src/runtime/server/data/index.js +5 -8
- package/src/runtime/server/dev.js +22 -0
- package/src/runtime/server/endpoint.js +3 -4
- package/src/runtime/server/fetch.js +22 -24
- package/src/runtime/server/index.js +54 -22
- package/src/runtime/server/internal.js +12 -5
- package/src/runtime/server/page/actions.js +18 -43
- package/src/runtime/server/page/data_serializer.js +12 -13
- package/src/runtime/server/page/index.js +16 -32
- package/src/runtime/server/page/load_data.js +26 -15
- package/src/runtime/server/page/render.js +9 -11
- package/src/runtime/server/page/respond_with_error.js +8 -20
- package/src/runtime/server/remote-functions.js +11 -15
- package/src/runtime/server/respond.js +26 -31
- package/src/runtime/server/state.js +36 -19
- package/src/runtime/server/utils.js +0 -20
- package/src/runtime/shared.js +16 -38
- package/src/types/internal.d.ts +45 -52
- package/src/utils/filesystem.js +1 -23
- package/src/version.js +1 -1
- package/types/index.d.ts +24 -18
- package/types/index.d.ts.map +1 -1
- package/src/runtime/server/app.js +0 -9
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** @import { Transport } from '@sveltejs/kit' */
|
|
2
|
+
import * as devalue from 'devalue';
|
|
3
|
+
import { DEV } from 'esm-env';
|
|
4
|
+
|
|
5
|
+
/** @type {(thing: any) => string} */
|
|
6
|
+
export let uneval = () => {
|
|
7
|
+
throw new Error(DEV ? 'called uneval before init_transport' : '');
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/** @type {(data: any) => string} */
|
|
11
|
+
export let stringify = () => {
|
|
12
|
+
throw new Error(DEV ? 'called stringify before init_transport' : '');
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** @type {(data: string) => any} */
|
|
16
|
+
export let parse = () => {
|
|
17
|
+
throw new Error(DEV ? 'called parse before init_transport' : '');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** @type {Record<string, (data: any) => any>} */
|
|
21
|
+
export let encoders = {};
|
|
22
|
+
|
|
23
|
+
/** @type {Record<string, (data: any) => any>} */
|
|
24
|
+
export let decoders = {};
|
|
25
|
+
|
|
26
|
+
export let has_custom_transporters = false;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {Transport} transport
|
|
31
|
+
*/
|
|
32
|
+
export function init_transport(transport) {
|
|
33
|
+
const transporters = Object.entries(transport);
|
|
34
|
+
|
|
35
|
+
has_custom_transporters = transporters.length > 0;
|
|
36
|
+
|
|
37
|
+
/** @param {unknown} thing */
|
|
38
|
+
const replacer = (thing) => {
|
|
39
|
+
for (const key of Object.keys(transport)) {
|
|
40
|
+
const encoded = transport[key].encode(thing);
|
|
41
|
+
if (encoded) {
|
|
42
|
+
return `app.decode('${key}', ${devalue.uneval(encoded, replacer)})`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
encoders = Object.fromEntries(transporters.map(([k, v]) => [k, v.encode]));
|
|
48
|
+
decoders = Object.fromEntries(transporters.map(([k, v]) => [k, v.decode]));
|
|
49
|
+
|
|
50
|
+
uneval = (data) => devalue.uneval(data, replacer);
|
|
51
|
+
stringify = (data) => devalue.stringify(data, encoders);
|
|
52
|
+
parse = (data) => devalue.parse(data, decoders);
|
|
53
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { AssetPath, RouteId, RouteIdWithSearchOrHash,
|
|
1
|
+
/** @import { AssetPath, RouteId, RouteIdWithSearchOrHash, PathnameWithSearchOrHash, ResolvedPathname, RouteParams } from '$app/types' */
|
|
2
2
|
/** @import { ResolveArgs } from './types.js' */
|
|
3
3
|
import { base, assets, hash_routing, match_implementation } from './internal/client.js';
|
|
4
4
|
import { resolve_route } from '../../../utils/routing.js';
|
|
@@ -92,7 +92,7 @@ export function resolve(...args) {
|
|
|
92
92
|
* ```
|
|
93
93
|
* @since 2.52.0
|
|
94
94
|
*
|
|
95
|
-
* @param {
|
|
95
|
+
* @param {URL | string} url
|
|
96
96
|
* @returns {Promise<{ [K in RouteId]: { id: K; params: RouteParams<K>; } }[RouteId] | null>}
|
|
97
97
|
*/
|
|
98
98
|
export function match(url) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @import { RouteId
|
|
1
|
+
/** @import { RouteId } from '$app/types' */
|
|
2
2
|
import { payload } from '../../../client/payload.js';
|
|
3
3
|
|
|
4
4
|
export const base = payload.base ?? __SVELTEKIT_PATHS_BASE__;
|
|
@@ -9,7 +9,7 @@ export const hash_routing = __SVELTEKIT_HASH_ROUTING__;
|
|
|
9
9
|
/**
|
|
10
10
|
* We make this configurable per-environment so that it's possible to import `$app/paths`
|
|
11
11
|
* into a service worker without importing the entire client
|
|
12
|
-
* @param {
|
|
12
|
+
* @param {URL | string} _url
|
|
13
13
|
* @returns {Promise<{ [K in RouteId]: { id: K; params: import('$app/types').RouteParams<K>; } }[RouteId] | null>}
|
|
14
14
|
*/
|
|
15
15
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
@@ -4,15 +4,11 @@
|
|
|
4
4
|
import { json } from '@sveltejs/kit';
|
|
5
5
|
import { HttpError } from '@sveltejs/kit/internal';
|
|
6
6
|
import { get_request_store } from '@sveltejs/kit/internal/server';
|
|
7
|
-
import {
|
|
7
|
+
import { stringify_remote_arg } from '../../../shared.js';
|
|
8
|
+
import { parse, stringify } from '#app/internal/transport';
|
|
8
9
|
import { noop } from '../../../../utils/functions.js';
|
|
9
10
|
import { app_dir, base } from '$app/paths/internal/server';
|
|
10
|
-
import {
|
|
11
|
-
create_validator,
|
|
12
|
-
get_response,
|
|
13
|
-
parse_remote_response,
|
|
14
|
-
run_remote_function
|
|
15
|
-
} from './shared.js';
|
|
11
|
+
import { create_validator, get_response, run_remote_function } from './shared.js';
|
|
16
12
|
|
|
17
13
|
/**
|
|
18
14
|
* Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call.
|
|
@@ -89,7 +85,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
89
85
|
/** @type {RemotePrerenderFunction<Input, Output> & { __: RemotePrerenderInternals }} */
|
|
90
86
|
const wrapper = (arg) => {
|
|
91
87
|
const { event, state } = get_request_store();
|
|
92
|
-
const payload = stringify_remote_arg(arg
|
|
88
|
+
const payload = stringify_remote_arg(arg);
|
|
93
89
|
|
|
94
90
|
// `get_response` (as opposed to bare `get_cache`) also registers the call in the
|
|
95
91
|
// implicit lookup, so that the result is inlined into the page payload (`data.p`)
|
|
@@ -121,7 +117,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
121
117
|
throw new HttpError(prerendered.error);
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
return
|
|
120
|
+
return parse(prerendered.data)._;
|
|
125
121
|
}
|
|
126
122
|
}
|
|
127
123
|
|
|
@@ -146,7 +142,7 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) {
|
|
|
146
142
|
const result = await promise;
|
|
147
143
|
|
|
148
144
|
if (state.prerendering) {
|
|
149
|
-
const body = { type: 'result', data: stringify({ _: result }
|
|
145
|
+
const body = { type: 'result', data: stringify({ _: result }) };
|
|
150
146
|
state.prerendering.dependencies.set(url, {
|
|
151
147
|
body: JSON.stringify(body),
|
|
152
148
|
response: json(body)
|
|
@@ -98,7 +98,7 @@ export function query(validate_or_fn, maybe_fn) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
const { event, state } = get_request_store();
|
|
101
|
-
const payload = stringify_remote_arg(arg
|
|
101
|
+
const payload = stringify_remote_arg(arg);
|
|
102
102
|
|
|
103
103
|
return create_query_resource(__, payload, event, state, () =>
|
|
104
104
|
run_remote_function(
|
|
@@ -197,7 +197,7 @@ function live(validate_or_fn, maybe_fn) {
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
const { event, state } = get_request_store();
|
|
200
|
-
const payload = stringify_remote_arg(arg
|
|
200
|
+
const payload = stringify_remote_arg(arg);
|
|
201
201
|
|
|
202
202
|
return create_live_query_resource(__, payload, event, state, () =>
|
|
203
203
|
run(event, state, () => validate(arg))
|
|
@@ -376,7 +376,7 @@ function batch(validate_or_fn, maybe_fn) {
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
const { event, state } = get_request_store();
|
|
379
|
-
const payload = stringify_remote_arg(arg
|
|
379
|
+
const payload = stringify_remote_arg(arg);
|
|
380
380
|
|
|
381
381
|
return create_query_resource(__, payload, event, state, () =>
|
|
382
382
|
// Collect all the calls to the same query in the same macrotask,
|
|
@@ -163,7 +163,7 @@ export function requested(query, limit) {
|
|
|
163
163
|
*[Symbol.iterator]() {
|
|
164
164
|
for (const payload of selected) {
|
|
165
165
|
try {
|
|
166
|
-
const parsed = parse_remote_arg(payload
|
|
166
|
+
const parsed = parse_remote_arg(payload);
|
|
167
167
|
const validated = __.validate(parsed);
|
|
168
168
|
|
|
169
169
|
if (is_thenable(validated)) {
|
|
@@ -183,7 +183,7 @@ export function requested(query, limit) {
|
|
|
183
183
|
async *[Symbol.asyncIterator]() {
|
|
184
184
|
yield* race_all(selected, async (payload) => {
|
|
185
185
|
try {
|
|
186
|
-
const parsed = parse_remote_arg(payload
|
|
186
|
+
const parsed = parse_remote_arg(payload);
|
|
187
187
|
const validated = await __.validate(parsed);
|
|
188
188
|
return { arg: validated, query: __.bind(payload, validated) };
|
|
189
189
|
} catch (error) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** @import { RequestEvent } from '@sveltejs/kit' */
|
|
2
|
-
/** @import {
|
|
3
|
-
import { parse } from 'devalue';
|
|
2
|
+
/** @import { MaybePromise, RequestState, RemoteInternals, RequestStore, RemoteLiveQueryUserFunctionReturnType } from 'types' */
|
|
4
3
|
import { error } from '@sveltejs/kit';
|
|
5
4
|
import { with_request_store, get_request_store } from '@sveltejs/kit/internal/server';
|
|
6
5
|
|
|
@@ -80,20 +79,6 @@ export async function get_response(internals, payload, state, get_result) {
|
|
|
80
79
|
return (cache[payload] ??= get_result());
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
/**
|
|
84
|
-
* @param {any} data
|
|
85
|
-
* @param {ServerHooks['transport']} transport
|
|
86
|
-
*/
|
|
87
|
-
export function parse_remote_response(data, transport) {
|
|
88
|
-
/** @type {Record<string, any>} */
|
|
89
|
-
const revivers = {};
|
|
90
|
-
for (const key in transport) {
|
|
91
|
-
revivers[key] = transport[key].decode;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return parse(data, revivers);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
82
|
/**
|
|
98
83
|
* @param {RequestEvent} event
|
|
99
84
|
* @param {RequestState} state
|
|
@@ -9,7 +9,7 @@ import { settled, tick, fork, onMount, hydrate, mount } from 'svelte';
|
|
|
9
9
|
import { HttpError, Redirect, SvelteKitError } from '@sveltejs/kit/internal';
|
|
10
10
|
import { decode_pathname, strip_hash, make_trackable, normalize_path } from '../../utils/url.js';
|
|
11
11
|
import { dev_fetch, initial_fetch, lock_fetch, subsequent_fetch, unlock_fetch } from './fetcher.js';
|
|
12
|
-
import {
|
|
12
|
+
import { parse_routes, parse_server_route } from './parse.js';
|
|
13
13
|
import * as storage from './session-storage.js';
|
|
14
14
|
import {
|
|
15
15
|
find_anchor,
|
|
@@ -50,13 +50,14 @@ import { noop_span } from '../telemetry/noop.js';
|
|
|
50
50
|
import { read_ndjson } from './ndjson.js';
|
|
51
51
|
import Root from '../components/root.svelte';
|
|
52
52
|
import { Props, RenderNode } from '../props.svelte.js';
|
|
53
|
+
import { init_transport, parse, stringify } from '#app/internal/transport';
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
56
|
* @typedef {{
|
|
56
57
|
* historyIndex: number;
|
|
57
58
|
* navigationIndex: number;
|
|
58
59
|
* pageUrl?: string;
|
|
59
|
-
* state:
|
|
60
|
+
* state: string;
|
|
60
61
|
* persistState: boolean;
|
|
61
62
|
* resetIndex: number;
|
|
62
63
|
* }} HistoryMetadata
|
|
@@ -487,9 +488,11 @@ async function _start(_app, _target, data) {
|
|
|
487
488
|
|
|
488
489
|
app = _app;
|
|
489
490
|
|
|
491
|
+
init_transport(app.hooks.transport ?? {});
|
|
492
|
+
|
|
490
493
|
await _app.hooks.init?.();
|
|
491
494
|
|
|
492
|
-
routes = __SVELTEKIT_CLIENT_ROUTING__ ?
|
|
495
|
+
routes = __SVELTEKIT_CLIENT_ROUTING__ ? parse_routes(_app) : [];
|
|
493
496
|
container = __SVELTEKIT_EMBEDDED__ ? _target : document.documentElement;
|
|
494
497
|
target = _target;
|
|
495
498
|
|
|
@@ -530,7 +533,7 @@ async function _start(_app, _target, data) {
|
|
|
530
533
|
[HISTORY_METADATA_KEY]: {
|
|
531
534
|
historyIndex: current_history_index,
|
|
532
535
|
navigationIndex: current_navigation_index,
|
|
533
|
-
state: {},
|
|
536
|
+
state: stringify({}),
|
|
534
537
|
persistState: false,
|
|
535
538
|
resetIndex: current_history_index
|
|
536
539
|
}
|
|
@@ -563,7 +566,7 @@ async function _start(_app, _target, data) {
|
|
|
563
566
|
type: 'enter',
|
|
564
567
|
url: resolve_url(app.hash ? decode_hash(new URL(location.href)) : location.href),
|
|
565
568
|
replace_state: true,
|
|
566
|
-
state: history_metadata?.persistState ? history_metadata.state : {},
|
|
569
|
+
state: history_metadata?.persistState ? parse(history_metadata.state) : {},
|
|
567
570
|
persist_state: history_metadata?.persistState ?? false
|
|
568
571
|
});
|
|
569
572
|
|
|
@@ -2054,10 +2057,17 @@ async function navigate({
|
|
|
2054
2057
|
url.pathname = navigation_result.props.page.url.pathname;
|
|
2055
2058
|
}
|
|
2056
2059
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
//
|
|
2060
|
+
if (popped) {
|
|
2061
|
+
state = popped.state;
|
|
2062
|
+
} else {
|
|
2063
|
+
// we immediately serialize-then-parse to ensure that the value is
|
|
2064
|
+
// serializable, and to prevent the developer from dangerously
|
|
2065
|
+
// relying on the identity of the serialized objects
|
|
2066
|
+
const serialized_state = stringify(state);
|
|
2067
|
+
state = parse(serialized_state);
|
|
2068
|
+
|
|
2069
|
+
// Store the serialized state so the browser history can preserve custom transport values.
|
|
2070
|
+
// This is a new navigation, rather than a popstate.
|
|
2061
2071
|
const change = replace_state ? 0 : 1;
|
|
2062
2072
|
if (type !== 'enter') {
|
|
2063
2073
|
if (reset) current_reset_index += 1;
|
|
@@ -2067,7 +2077,7 @@ async function navigate({
|
|
|
2067
2077
|
[HISTORY_METADATA_KEY]: /** @satisfies {HistoryMetadata} */ ({
|
|
2068
2078
|
historyIndex: (current_history_index += change),
|
|
2069
2079
|
navigationIndex: (current_navigation_index += change),
|
|
2070
|
-
state,
|
|
2080
|
+
state: serialized_state,
|
|
2071
2081
|
persistState: persist_state,
|
|
2072
2082
|
resetIndex: current_reset_index
|
|
2073
2083
|
})
|
|
@@ -2874,18 +2884,8 @@ export async function replaceState(url, state) {
|
|
|
2874
2884
|
async function update_state(intent, state, { replace, persist_state, reset }, caller) {
|
|
2875
2885
|
const url = intent.url;
|
|
2876
2886
|
|
|
2877
|
-
if (DEV) {
|
|
2878
|
-
|
|
2879
|
-
throw new Error(`Cannot call ${caller}(...) before router is initialized`);
|
|
2880
|
-
}
|
|
2881
|
-
|
|
2882
|
-
try {
|
|
2883
|
-
// use `devalue.stringify` as a convenient way to ensure we exclude values that can't be properly rehydrated, such as custom class instances
|
|
2884
|
-
devalue.stringify(state);
|
|
2885
|
-
} catch (error) {
|
|
2886
|
-
// @ts-expect-error
|
|
2887
|
-
throw new Error(`Could not serialize state${error.path}`, { cause: error });
|
|
2888
|
-
}
|
|
2887
|
+
if (DEV && !started) {
|
|
2888
|
+
throw new Error(`Cannot call ${caller}(...) before router is initialized`);
|
|
2889
2889
|
}
|
|
2890
2890
|
|
|
2891
2891
|
const nav =
|
|
@@ -2906,12 +2906,16 @@ async function update_state(intent, state, { replace, persist_state, reset }, ca
|
|
|
2906
2906
|
if (!replace) capture_scroll(current_history_index);
|
|
2907
2907
|
if (reset) current_reset_index += 1;
|
|
2908
2908
|
|
|
2909
|
+
// as above, serialize-then-parse to prevent bugs
|
|
2910
|
+
const serialized_state = stringify(state);
|
|
2911
|
+
state = parse(serialized_state);
|
|
2912
|
+
|
|
2909
2913
|
const entry = {
|
|
2910
2914
|
[HISTORY_METADATA_KEY]: /** @satisfies {HistoryMetadata} */ ({
|
|
2911
2915
|
historyIndex: (current_history_index += replace ? 0 : 1),
|
|
2912
2916
|
navigationIndex: current_navigation_index,
|
|
2913
2917
|
pageUrl: page.url.href,
|
|
2914
|
-
state,
|
|
2918
|
+
state: serialized_state,
|
|
2915
2919
|
persistState: persist_state,
|
|
2916
2920
|
resetIndex: current_reset_index
|
|
2917
2921
|
})
|
|
@@ -3291,7 +3295,7 @@ function _start_router() {
|
|
|
3291
3295
|
const reset_index = history_metadata.resetIndex;
|
|
3292
3296
|
const reset = reset_index !== (source_info?.resetIndex ?? current_reset_index);
|
|
3293
3297
|
const scroll = history_info[history_index]?.scroll;
|
|
3294
|
-
const state = history_metadata.state;
|
|
3298
|
+
const state = parse(history_metadata.state);
|
|
3295
3299
|
const url = new URL(history_metadata.pageUrl ?? location.href);
|
|
3296
3300
|
const navigation_index = history_metadata.navigationIndex;
|
|
3297
3301
|
const is_hash_change =
|
|
@@ -3537,7 +3541,7 @@ async function _hydrate(
|
|
|
3537
3541
|
|
|
3538
3542
|
if (result.props.page) {
|
|
3539
3543
|
const history_metadata = get_history_metadata();
|
|
3540
|
-
result.props.page.state = history_metadata?.persistState ? history_metadata.state : {};
|
|
3544
|
+
result.props.page.state = history_metadata?.persistState ? parse(history_metadata.state) : {};
|
|
3541
3545
|
}
|
|
3542
3546
|
|
|
3543
3547
|
await initialize(result, target, should_hydrate);
|
|
@@ -4,7 +4,7 @@ import { exec, parse_route_id } from '../../utils/routing.js';
|
|
|
4
4
|
* @param {import('./types.js').SvelteKitApp} app
|
|
5
5
|
* @returns {import('types').CSRRoute[]}
|
|
6
6
|
*/
|
|
7
|
-
export function
|
|
7
|
+
export function parse_routes({ nodes, server_loads, dictionary, matchers }) {
|
|
8
8
|
const layouts_with_server_load = new Set(server_loads);
|
|
9
9
|
|
|
10
10
|
return Object.entries(dictionary).map(([id, [leaf, layouts, errors]]) => {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/** @import { RemoteCommand, RemoteQueryUpdate } from '@sveltejs/kit' */
|
|
2
2
|
import { app_dir, base } from '$app/paths/internal/client';
|
|
3
|
-
import { app } from '../client.js';
|
|
4
3
|
import { stringify_command_arg } from '../../shared.js';
|
|
5
4
|
import { get_remote_request_headers, categorize_updates, remote_request } from './shared.svelte.js';
|
|
6
5
|
|
|
@@ -48,7 +47,7 @@ export function command(id) {
|
|
|
48
47
|
const response = await remote_request(`${base}/${app_dir}/remote/${id}`, {
|
|
49
48
|
method: 'POST',
|
|
50
49
|
body: JSON.stringify({
|
|
51
|
-
payload: await stringify_command_arg(arg
|
|
50
|
+
payload: await stringify_command_arg(arg),
|
|
52
51
|
refreshes: Array.from(refreshes ?? [])
|
|
53
52
|
}),
|
|
54
53
|
headers
|
|
@@ -57,7 +57,7 @@ function put(url, encoded) {
|
|
|
57
57
|
*/
|
|
58
58
|
export function prerender(id) {
|
|
59
59
|
return (arg) => {
|
|
60
|
-
const payload = stringify_remote_arg(arg
|
|
60
|
+
const payload = stringify_remote_arg(arg);
|
|
61
61
|
const cache_key = create_remote_key(id, payload);
|
|
62
62
|
|
|
63
63
|
let resource = prerender_resources.get(cache_key)?.deref();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { query_map } from '../../client.js';
|
|
2
2
|
import {
|
|
3
3
|
pin_in_effect,
|
|
4
4
|
pin_while_resolving,
|
|
@@ -29,7 +29,7 @@ export class QueryProxy {
|
|
|
29
29
|
*/
|
|
30
30
|
constructor(id, arg, fn) {
|
|
31
31
|
this.#id = id;
|
|
32
|
-
this.#payload = stringify_remote_arg(arg
|
|
32
|
+
this.#payload = stringify_remote_arg(arg);
|
|
33
33
|
this.#key = create_remote_key(id, this.#payload);
|
|
34
34
|
Object.defineProperty(this, QUERY_RESOURCE_KEY, { value: this.#key });
|
|
35
35
|
this.#fn = fn;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { live_query_map } from '../../client.js';
|
|
2
2
|
import { pin_in_effect, pin_while_resolving, QUERY_RESOURCE_KEY } from '../shared.svelte.js';
|
|
3
3
|
import { create_remote_key, stringify_remote_arg } from '../../../shared.js';
|
|
4
4
|
import { LiveQuery } from './instance.svelte.js';
|
|
@@ -20,7 +20,7 @@ export class LiveQueryProxy {
|
|
|
20
20
|
*/
|
|
21
21
|
constructor(id, arg) {
|
|
22
22
|
this.#id = id;
|
|
23
|
-
this.#payload = stringify_remote_arg(arg
|
|
23
|
+
this.#payload = stringify_remote_arg(arg);
|
|
24
24
|
this.#key = create_remote_key(id, this.#payload);
|
|
25
25
|
Object.defineProperty(this, QUERY_RESOURCE_KEY, { value: this.#key });
|
|
26
26
|
|
package/src/runtime/pathname.js
CHANGED
|
@@ -22,13 +22,14 @@ export function strip_data_suffix(pathname) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const ROUTE_SUFFIX = '/__route.js';
|
|
25
|
+
const HTML_ROUTE_SUFFIX = '.html__route.js';
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* @param {string} pathname
|
|
28
29
|
* @returns {boolean}
|
|
29
30
|
*/
|
|
30
31
|
export function has_resolution_suffix(pathname) {
|
|
31
|
-
return pathname.endsWith(ROUTE_SUFFIX);
|
|
32
|
+
return pathname.endsWith(ROUTE_SUFFIX) || pathname.endsWith(HTML_ROUTE_SUFFIX);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -37,6 +38,7 @@ export function has_resolution_suffix(pathname) {
|
|
|
37
38
|
* @returns {string}
|
|
38
39
|
*/
|
|
39
40
|
export function add_resolution_suffix(pathname) {
|
|
41
|
+
if (pathname.endsWith('.html')) return pathname.replace(/\.html$/, HTML_ROUTE_SUFFIX);
|
|
40
42
|
return pathname.replace(/\/$/, '') + ROUTE_SUFFIX;
|
|
41
43
|
}
|
|
42
44
|
|
|
@@ -45,6 +47,10 @@ export function add_resolution_suffix(pathname) {
|
|
|
45
47
|
* @returns {string}
|
|
46
48
|
*/
|
|
47
49
|
export function strip_resolution_suffix(pathname) {
|
|
50
|
+
if (pathname.endsWith(HTML_ROUTE_SUFFIX)) {
|
|
51
|
+
return pathname.slice(0, -HTML_ROUTE_SUFFIX.length) + '.html';
|
|
52
|
+
}
|
|
53
|
+
|
|
48
54
|
return pathname.slice(0, -ROUTE_SUFFIX.length);
|
|
49
55
|
}
|
|
50
56
|
|
|
@@ -11,22 +11,20 @@ import { with_version_header } from '../utils.js';
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
14
|
-
* @param {import('types').RequestState}
|
|
14
|
+
* @param {import('types').RequestState} state
|
|
15
15
|
* @param {import('types').SSRRoute} route
|
|
16
16
|
* @param {import('types').SSROptions} options
|
|
17
17
|
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
18
|
-
* @param {import('types').SSRState} state
|
|
19
18
|
* @param {boolean[] | undefined} invalidated_data_nodes
|
|
20
19
|
* @param {import('types').TrailingSlash} trailing_slash
|
|
21
20
|
* @returns {Promise<Response>}
|
|
22
21
|
*/
|
|
23
22
|
export async function render_data(
|
|
24
23
|
event,
|
|
25
|
-
|
|
24
|
+
state,
|
|
26
25
|
route,
|
|
27
26
|
options,
|
|
28
27
|
manifest,
|
|
29
|
-
state,
|
|
30
28
|
invalidated_data_nodes,
|
|
31
29
|
trailing_slash
|
|
32
30
|
) {
|
|
@@ -60,7 +58,6 @@ export async function render_data(
|
|
|
60
58
|
// load this. for the child, return as is. for the final result, stream things
|
|
61
59
|
return load_server_data({
|
|
62
60
|
event: new_event,
|
|
63
|
-
event_state,
|
|
64
61
|
state,
|
|
65
62
|
node,
|
|
66
63
|
parent: async () => {
|
|
@@ -95,7 +92,7 @@ export async function render_data(
|
|
|
95
92
|
return fn();
|
|
96
93
|
});
|
|
97
94
|
|
|
98
|
-
const data_serializer = server_data_serializer_json(event,
|
|
95
|
+
const data_serializer = server_data_serializer_json(event, state, options);
|
|
99
96
|
await Promise.all(
|
|
100
97
|
promises.map(async (p, i) => {
|
|
101
98
|
const node = await p.catch(async (error) => {
|
|
@@ -103,7 +100,7 @@ export async function render_data(
|
|
|
103
100
|
throw error;
|
|
104
101
|
}
|
|
105
102
|
|
|
106
|
-
const transformed = await handle_error_and_jsonify(event,
|
|
103
|
+
const transformed = await handle_error_and_jsonify(event, state, options, error);
|
|
107
104
|
|
|
108
105
|
return /** @type {import('types').ServerErrorNode} */ ({
|
|
109
106
|
type: 'error',
|
|
@@ -151,7 +148,7 @@ export async function render_data(
|
|
|
151
148
|
if (error instanceof Redirect) {
|
|
152
149
|
return redirect_json_response(error);
|
|
153
150
|
} else {
|
|
154
|
-
const transformed = await handle_error_and_jsonify(event,
|
|
151
|
+
const transformed = await handle_error_and_jsonify(event, state, options, error);
|
|
155
152
|
return json_response(transformed, transformed.status);
|
|
156
153
|
}
|
|
157
154
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const symbol = Symbol.for('sveltekit.global_state');
|
|
2
|
+
const state = /** @type {Record<symbol, any>} */ (
|
|
3
|
+
/** @type {Record<symbol, unknown>} */ (/** @type {unknown} */ (globalThis))[symbol] ??= {}
|
|
4
|
+
);
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Persist a value across dev server reloads, in case a freshly-invalidated module
|
|
8
|
+
* reads global state that is not set until a request is handled
|
|
9
|
+
* @param {symbol} key
|
|
10
|
+
* @param {any} value
|
|
11
|
+
*/
|
|
12
|
+
export function save(key, value) {
|
|
13
|
+
state[key] = value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Restore a value after a dev server reload
|
|
18
|
+
* @param {symbol} key
|
|
19
|
+
*/
|
|
20
|
+
export function restore(key) {
|
|
21
|
+
return state[key];
|
|
22
|
+
}
|
|
@@ -6,12 +6,11 @@ import { method_not_allowed } from './utils.js';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {import('@sveltejs/kit').RequestEvent} event
|
|
9
|
-
* @param {import('types').RequestState}
|
|
9
|
+
* @param {import('types').RequestState} state
|
|
10
10
|
* @param {import('types').SSREndpoint} mod
|
|
11
|
-
* @param {import('types').SSRState} state
|
|
12
11
|
* @returns {Promise<Response>}
|
|
13
12
|
*/
|
|
14
|
-
export async function render_endpoint(event,
|
|
13
|
+
export async function render_endpoint(event, state, mod) {
|
|
15
14
|
const method = /** @type {import('types').HttpMethod} */ (event.request.method);
|
|
16
15
|
|
|
17
16
|
let handler = mod[method] || mod.fallback;
|
|
@@ -42,7 +41,7 @@ export async function render_endpoint(event, event_state, mod, state) {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
try {
|
|
45
|
-
const response = await with_request_store({ event, state
|
|
44
|
+
const response = await with_request_store({ event, state }, () =>
|
|
46
45
|
handler(/** @type {import('@sveltejs/kit').RequestEvent<Record<string, any>>} */ (event))
|
|
47
46
|
);
|
|
48
47
|
|
|
@@ -11,7 +11,7 @@ import { fork_state_for_subrequest } from './state.js';
|
|
|
11
11
|
* event: import('@sveltejs/kit').RequestEvent;
|
|
12
12
|
* options: import('types').SSROptions;
|
|
13
13
|
* manifest: import('@sveltejs/kit').SSRManifest;
|
|
14
|
-
* state: import('types').
|
|
14
|
+
* state: import('types').RequestState;
|
|
15
15
|
* get_cookie_header: (url: URL, header: string | null) => string;
|
|
16
16
|
* set_internal: (name: string, value: string, opts: import('./page/types.js').Cookie['options']) => void;
|
|
17
17
|
* }} opts
|
|
@@ -195,34 +195,32 @@ function normalize_fetch_input(info, init, url) {
|
|
|
195
195
|
* @param {Request} request
|
|
196
196
|
* @param {import('types').SSROptions} options
|
|
197
197
|
* @param {import('@sveltejs/kit').SSRManifest} manifest
|
|
198
|
-
* @param {import('types').
|
|
198
|
+
* @param {import('types').RequestState} state
|
|
199
199
|
* @returns {Promise<Response>}
|
|
200
200
|
*/
|
|
201
201
|
async function internal_fetch(request, options, manifest, state) {
|
|
202
|
-
|
|
202
|
+
if (request.signal?.aborted) {
|
|
203
|
+
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
204
|
+
}
|
|
203
205
|
|
|
204
|
-
|
|
205
|
-
if (request.signal.aborted) {
|
|
206
|
-
throw new DOMException('The operation was aborted.', 'AbortError');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
let remove_abort_listener = noop;
|
|
210
|
-
/** @type {Promise<never>} */
|
|
211
|
-
const abort_promise = new Promise((_, reject) => {
|
|
212
|
-
const on_abort = () => {
|
|
213
|
-
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
214
|
-
};
|
|
215
|
-
request.signal.addEventListener('abort', on_abort, { once: true });
|
|
216
|
-
remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
|
|
217
|
-
});
|
|
206
|
+
const subrequest_state = fork_state_for_subrequest(state);
|
|
218
207
|
|
|
219
|
-
|
|
220
|
-
respond(request, options, manifest, subrequest_state),
|
|
221
|
-
abort_promise
|
|
222
|
-
]);
|
|
223
|
-
remove_abort_listener();
|
|
224
|
-
return result;
|
|
225
|
-
} else {
|
|
208
|
+
if (!request.signal) {
|
|
226
209
|
return await respond(request, options, manifest, subrequest_state);
|
|
227
210
|
}
|
|
211
|
+
|
|
212
|
+
let remove_abort_listener = noop;
|
|
213
|
+
/** @type {Promise<never>} */
|
|
214
|
+
const abort_promise = new Promise((_, reject) => {
|
|
215
|
+
const on_abort = () => {
|
|
216
|
+
reject(new DOMException('The operation was aborted.', 'AbortError'));
|
|
217
|
+
};
|
|
218
|
+
request.signal.addEventListener('abort', on_abort, { once: true });
|
|
219
|
+
remove_abort_listener = () => request.signal.removeEventListener('abort', on_abort);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
return Promise.race([
|
|
223
|
+
respond(request, options, manifest, subrequest_state),
|
|
224
|
+
abort_promise
|
|
225
|
+
]).finally(remove_abort_listener);
|
|
228
226
|
}
|