@sveltejs/kit 1.8.8 → 1.9.1
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 +1 -1
- package/src/core/config/options.js +7 -0
- package/src/core/sync/write_server.js +2 -1
- package/src/exports/vite/dev/index.js +5 -6
- package/src/exports/vite/index.js +21 -4
- package/src/internal.d.ts +5 -2
- package/src/runtime/app/stores.js +2 -1
- package/src/runtime/client/client.js +3 -0
- package/src/runtime/server/page/load_data.js +9 -4
- package/src/runtime/server/page/render.js +55 -36
- package/src/runtime/shared-server.js +0 -2
- package/src/runtime/shared.js +12 -0
- package/types/ambient.d.ts +1 -1
- package/types/index.d.ts +10 -2
package/package.json
CHANGED
|
@@ -171,6 +171,13 @@ const options = object(
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
+
return input;
|
|
175
|
+
}),
|
|
176
|
+
relative: validate(undefined, (input, keypath) => {
|
|
177
|
+
if (typeof input !== 'boolean') {
|
|
178
|
+
throw new Error(`${keypath} option must be a boolean or undefined`);
|
|
179
|
+
}
|
|
180
|
+
|
|
174
181
|
return input;
|
|
175
182
|
})
|
|
176
183
|
}),
|
|
@@ -27,7 +27,8 @@ const server_template = ({
|
|
|
27
27
|
}) => `
|
|
28
28
|
import root from '../root.svelte';
|
|
29
29
|
import { set_building } from '__sveltekit/environment';
|
|
30
|
-
import { set_assets
|
|
30
|
+
import { set_assets } from '__sveltekit/paths';
|
|
31
|
+
import { set_private_env, set_public_env } from '${runtime_directory}/shared-server.js';
|
|
31
32
|
|
|
32
33
|
export const options = {
|
|
33
34
|
app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')},
|
|
@@ -451,15 +451,14 @@ export async function dev(vite, vite_config, svelte_config) {
|
|
|
451
451
|
await vite.ssrLoadModule(`${runtime_base}/server/index.js`)
|
|
452
452
|
);
|
|
453
453
|
|
|
454
|
-
const {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
454
|
+
const { set_fix_stack_trace } = await vite.ssrLoadModule(
|
|
455
|
+
`${runtime_base}/shared-server.js`
|
|
456
|
+
);
|
|
457
|
+
set_fix_stack_trace(fix_stack_trace);
|
|
458
458
|
|
|
459
|
+
const { set_assets } = await vite.ssrLoadModule('__sveltekit/paths');
|
|
459
460
|
set_assets(assets);
|
|
460
461
|
|
|
461
|
-
set_fix_stack_trace(fix_stack_trace);
|
|
462
|
-
|
|
463
462
|
const server = new Server(manifest);
|
|
464
463
|
|
|
465
464
|
await server.init({ env });
|
|
@@ -379,17 +379,34 @@ function kit({ svelte_config }) {
|
|
|
379
379
|
case '\0__sveltekit/paths':
|
|
380
380
|
const { assets, base } = svelte_config.kit.paths;
|
|
381
381
|
|
|
382
|
+
// use the values defined in `global`, but fall back to hard-coded values
|
|
383
|
+
// for the sake of things like Vitest which may import this module
|
|
384
|
+
// outside the context of a page
|
|
382
385
|
if (browser) {
|
|
383
|
-
return `export const base = ${s(base)};
|
|
384
|
-
export const assets = ${global}
|
|
386
|
+
return `export const base = ${global}?.base ?? ${s(base)};
|
|
387
|
+
export const assets = ${global}?.assets ?? ${assets ? s(assets) : 'base'};`;
|
|
385
388
|
}
|
|
386
389
|
|
|
387
|
-
return `export
|
|
390
|
+
return `export let base = ${s(base)};
|
|
388
391
|
export let assets = ${assets ? s(assets) : 'base'};
|
|
389
392
|
|
|
393
|
+
export const relative = ${svelte_config.kit.paths.relative};
|
|
394
|
+
|
|
395
|
+
const initial = { base, assets };
|
|
396
|
+
|
|
397
|
+
export function override(paths) {
|
|
398
|
+
base = paths.base;
|
|
399
|
+
assets = paths.assets;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export function reset() {
|
|
403
|
+
base = initial.base;
|
|
404
|
+
assets = initial.assets;
|
|
405
|
+
}
|
|
406
|
+
|
|
390
407
|
/** @param {string} path */
|
|
391
408
|
export function set_assets(path) {
|
|
392
|
-
assets = path;
|
|
409
|
+
assets = initial.assets = path;
|
|
393
410
|
}`;
|
|
394
411
|
|
|
395
412
|
case '\0__sveltekit/environment':
|
package/src/internal.d.ts
CHANGED
|
@@ -7,7 +7,10 @@ declare module '__sveltekit/environment' {
|
|
|
7
7
|
|
|
8
8
|
/** Internal version of $app/paths */
|
|
9
9
|
declare module '__sveltekit/paths' {
|
|
10
|
-
export
|
|
11
|
-
export let assets: `https://${string}` | `http://${string}
|
|
10
|
+
export let base: '' | `/${string}`;
|
|
11
|
+
export let assets: '' | `https://${string}` | `http://${string}` | '/_svelte_kit_assets';
|
|
12
|
+
export let relative: boolean | undefined; // TODO in 2.0, make this a `boolean` that defaults to `true`
|
|
13
|
+
export function reset(): void;
|
|
14
|
+
export function override(paths: { base: string; assets: string }): void;
|
|
12
15
|
export function set_assets(path: string): void;
|
|
13
16
|
}
|
|
@@ -66,7 +66,8 @@ function get_store(name) {
|
|
|
66
66
|
return getStores()[name];
|
|
67
67
|
} catch (e) {
|
|
68
68
|
throw new Error(
|
|
69
|
-
`Cannot subscribe to '${name}' store on the server outside of a Svelte component, as it is bound to the current request via component context. This prevents state from leaking between users.`
|
|
69
|
+
`Cannot subscribe to '${name}' store on the server outside of a Svelte component, as it is bound to the current request via component context. This prevents state from leaking between users.` +
|
|
70
|
+
'For more information, see https://kit.svelte.dev/docs/state-management#avoid-shared-state-on-the-server'
|
|
70
71
|
);
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -33,6 +33,7 @@ import * as devalue from 'devalue';
|
|
|
33
33
|
import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY, SNAPSHOT_KEY } from './constants.js';
|
|
34
34
|
import { validate_common_exports } from '../../utils/exports.js';
|
|
35
35
|
import { compact } from '../../utils/array.js';
|
|
36
|
+
import { validate_depends } from '../shared.js';
|
|
36
37
|
|
|
37
38
|
// We track the scroll position associated with each history entry in sessionStorage,
|
|
38
39
|
// rather than on history.state itself, because when navigation is driven by
|
|
@@ -586,6 +587,8 @@ export function create_client(app, target) {
|
|
|
586
587
|
/** @param {string[]} deps */
|
|
587
588
|
function depends(...deps) {
|
|
588
589
|
for (const dep of deps) {
|
|
590
|
+
if (DEV) validate_depends(/** @type {string} */ (route.id), dep);
|
|
591
|
+
|
|
589
592
|
const { href } = new URL(dep, url);
|
|
590
593
|
uses.dependencies.add(href);
|
|
591
594
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { disable_search, make_trackable } from '../../../utils/url.js';
|
|
2
2
|
import { unwrap_promises } from '../../../utils/promises.js';
|
|
3
3
|
import { DEV } from 'esm-env';
|
|
4
|
+
import { validate_depends } from '../../shared.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Calls the user's server `load` function.
|
|
@@ -59,10 +60,14 @@ export async function load_server_data({ event, state, node, parent }) {
|
|
|
59
60
|
for (const dep of deps) {
|
|
60
61
|
const { href } = new URL(dep, event.url);
|
|
61
62
|
|
|
62
|
-
if (DEV
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
63
|
+
if (DEV) {
|
|
64
|
+
validate_depends(node.server_id, dep);
|
|
65
|
+
|
|
66
|
+
if (done && !uses.dependencies.has(href)) {
|
|
67
|
+
console.warn(
|
|
68
|
+
`${node.server_id}: Calling \`depends(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the dependency is invalidated`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
uses.dependencies.add(href);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as devalue from 'devalue';
|
|
2
2
|
import { readable, writable } from 'svelte/store';
|
|
3
3
|
import { DEV } from 'esm-env';
|
|
4
|
-
import
|
|
4
|
+
import * as paths from '__sveltekit/paths';
|
|
5
5
|
import { hash } from '../../hash.js';
|
|
6
6
|
import { serialize_data } from './serialize_data.js';
|
|
7
7
|
import { s } from '../../../utils/misc.js';
|
|
@@ -11,6 +11,7 @@ import { clarify_devalue_error, stringify_uses, handle_error_and_jsonify } from
|
|
|
11
11
|
import { public_env } from '../../shared-server.js';
|
|
12
12
|
import { text } from '../../../exports/index.js';
|
|
13
13
|
import { create_async_iterator } from '../../../utils/streaming.js';
|
|
14
|
+
import { SVELTE_KIT_ASSETS } from '../../../constants.js';
|
|
14
15
|
|
|
15
16
|
// TODO rename this function/module
|
|
16
17
|
|
|
@@ -80,6 +81,43 @@ export async function render_response({
|
|
|
80
81
|
? action_result.data ?? null
|
|
81
82
|
: null;
|
|
82
83
|
|
|
84
|
+
/** @type {string} */
|
|
85
|
+
let base = paths.base;
|
|
86
|
+
|
|
87
|
+
/** @type {string} */
|
|
88
|
+
let assets = paths.assets;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* An expression that will evaluate in the client to determine the resolved base path.
|
|
92
|
+
* We use a relative path when possible to support IPFS, the internet archive, etc.
|
|
93
|
+
*/
|
|
94
|
+
let base_expression = s(paths.base);
|
|
95
|
+
|
|
96
|
+
// if appropriate, use relative paths for greater portability
|
|
97
|
+
if (paths.relative !== false && !state.prerendering?.fallback) {
|
|
98
|
+
const segments = event.url.pathname.slice(paths.base.length).split('/');
|
|
99
|
+
|
|
100
|
+
if (segments.length === 1 && paths.base !== '') {
|
|
101
|
+
// if we're on `/my-base-path`, relative links need to start `./my-base-path` rather than `.`
|
|
102
|
+
base = `./${paths.base.split('/').at(-1)}`;
|
|
103
|
+
|
|
104
|
+
base_expression = `new URL(${s(base)}, location).pathname`;
|
|
105
|
+
} else {
|
|
106
|
+
base =
|
|
107
|
+
segments
|
|
108
|
+
.slice(2)
|
|
109
|
+
.map(() => '..')
|
|
110
|
+
.join('/') || '.';
|
|
111
|
+
|
|
112
|
+
// resolve e.g. '../..' against current location, then remove trailing slash
|
|
113
|
+
base_expression = `new URL(${s(base)}, location).pathname.slice(0, -1)`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!paths.assets || (paths.assets[0] === '/' && paths.assets !== SVELTE_KIT_ASSETS)) {
|
|
117
|
+
assets = base;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
83
121
|
if (page_config.ssr) {
|
|
84
122
|
if (__SVELTEKIT_DEV__ && !branch.at(-1)?.node.component) {
|
|
85
123
|
// Can only be the leaf, layouts have a fallback component generated
|
|
@@ -116,6 +154,10 @@ export async function render_response({
|
|
|
116
154
|
form: form_value
|
|
117
155
|
};
|
|
118
156
|
|
|
157
|
+
// use relative paths during rendering, so that the resulting HTML is as
|
|
158
|
+
// portable as possible, but reset afterwards
|
|
159
|
+
if (paths.relative) paths.override({ base, assets });
|
|
160
|
+
|
|
119
161
|
if (__SVELTEKIT_DEV__) {
|
|
120
162
|
const fetch = globalThis.fetch;
|
|
121
163
|
let warned = false;
|
|
@@ -138,9 +180,14 @@ export async function render_response({
|
|
|
138
180
|
rendered = options.root.render(props);
|
|
139
181
|
} finally {
|
|
140
182
|
globalThis.fetch = fetch;
|
|
183
|
+
paths.reset();
|
|
141
184
|
}
|
|
142
185
|
} else {
|
|
143
|
-
|
|
186
|
+
try {
|
|
187
|
+
rendered = options.root.render(props);
|
|
188
|
+
} finally {
|
|
189
|
+
paths.reset();
|
|
190
|
+
}
|
|
144
191
|
}
|
|
145
192
|
|
|
146
193
|
for (const { node } of branch) {
|
|
@@ -156,35 +203,6 @@ export async function render_response({
|
|
|
156
203
|
rendered = { head: '', html: '', css: { code: '', map: null } };
|
|
157
204
|
}
|
|
158
205
|
|
|
159
|
-
/**
|
|
160
|
-
* The prefix to use for static assets. Replaces `%sveltekit.assets%` in the template
|
|
161
|
-
* @type {string}
|
|
162
|
-
*/
|
|
163
|
-
let resolved_assets;
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* An expression that will evaluate in the client to determine the resolved asset path
|
|
167
|
-
*/
|
|
168
|
-
let asset_expression;
|
|
169
|
-
|
|
170
|
-
if (assets) {
|
|
171
|
-
// if an asset path is specified, use it
|
|
172
|
-
resolved_assets = assets;
|
|
173
|
-
asset_expression = s(assets);
|
|
174
|
-
} else if (state.prerendering?.fallback) {
|
|
175
|
-
// if we're creating a fallback page, asset paths need to be root-relative
|
|
176
|
-
resolved_assets = base;
|
|
177
|
-
asset_expression = s(base);
|
|
178
|
-
} else {
|
|
179
|
-
// otherwise we want asset paths to be relative to the page, so that they
|
|
180
|
-
// will work in odd contexts like IPFS, the internet archive, and so on
|
|
181
|
-
const segments = event.url.pathname.slice(base.length).split('/').slice(2);
|
|
182
|
-
resolved_assets = segments.length > 0 ? segments.map(() => '..').join('/') : '.';
|
|
183
|
-
asset_expression = `new URL(${s(
|
|
184
|
-
resolved_assets
|
|
185
|
-
)}, location.href).pathname.replace(/^\\\/$/, '')`;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
206
|
let head = '';
|
|
189
207
|
let body = rendered.html;
|
|
190
208
|
|
|
@@ -198,9 +216,9 @@ export async function render_response({
|
|
|
198
216
|
// Vite makes the start script available through the base path and without it.
|
|
199
217
|
// We load it via the base path in order to support remote IDE environments which proxy
|
|
200
218
|
// all URLs under the base path during development.
|
|
201
|
-
return base + path;
|
|
219
|
+
return paths.base + path;
|
|
202
220
|
}
|
|
203
|
-
return `${
|
|
221
|
+
return `${assets}/${path}`;
|
|
204
222
|
};
|
|
205
223
|
|
|
206
224
|
if (inline_styles.size > 0) {
|
|
@@ -286,9 +304,10 @@ export async function render_response({
|
|
|
286
304
|
|
|
287
305
|
const properties = [
|
|
288
306
|
`env: ${s(public_env)}`,
|
|
289
|
-
`assets: ${
|
|
307
|
+
paths.assets && `assets: ${s(paths.assets)}`,
|
|
308
|
+
`base: ${base_expression}`,
|
|
290
309
|
`element: document.currentScript.parentElement`
|
|
291
|
-
];
|
|
310
|
+
].filter(Boolean);
|
|
292
311
|
|
|
293
312
|
if (chunks) {
|
|
294
313
|
blocks.push(`const deferred = new Map();`);
|
|
@@ -419,7 +438,7 @@ export async function render_response({
|
|
|
419
438
|
const html = options.templates.app({
|
|
420
439
|
head,
|
|
421
440
|
body,
|
|
422
|
-
assets
|
|
441
|
+
assets,
|
|
423
442
|
nonce: /** @type {string} */ (csp.nonce),
|
|
424
443
|
env: public_env
|
|
425
444
|
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} route_id
|
|
3
|
+
* @param {string} dep
|
|
4
|
+
*/
|
|
5
|
+
export function validate_depends(route_id, dep) {
|
|
6
|
+
const match = /^(moz-icon|view-source|jar):/.exec(dep);
|
|
7
|
+
if (match) {
|
|
8
|
+
console.warn(
|
|
9
|
+
`${route_id}: Calling \`depends('${dep}')\` will throw an error in Firefox because \`${match[1]}\` is a special URI scheme`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
}
|
package/types/ambient.d.ts
CHANGED
|
@@ -195,7 +195,7 @@ declare module '$app/navigation' {
|
|
|
195
195
|
*/
|
|
196
196
|
state?: any;
|
|
197
197
|
/**
|
|
198
|
-
* If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#
|
|
198
|
+
* If `true`, all `load` functions of the page will be rerun. See https://kit.svelte.dev/docs/load#rerunning-load-functions for more info on invalidation.
|
|
199
199
|
*/
|
|
200
200
|
invalidateAll?: boolean;
|
|
201
201
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -441,12 +441,20 @@ export interface KitConfig {
|
|
|
441
441
|
* An absolute path that your app's files are served from. This is useful if your files are served from a storage bucket of some kind.
|
|
442
442
|
* @default ""
|
|
443
443
|
*/
|
|
444
|
-
assets?: string
|
|
444
|
+
assets?: '' | `http://${string}` | `https://${string}`;
|
|
445
445
|
/**
|
|
446
446
|
* A root-relative path that must start, but not end with `/` (e.g. `/base-path`), unless it is the empty string. This specifies where your app is served from and allows the app to live on a non-root path. Note that you need to prepend all your root-relative links with the base value or they will point to the root of your domain, not your `base` (this is how the browser works). You can use [`base` from `$app/paths`](/docs/modules#$app-paths-base) for that: `<a href="{base}/your-page">Link</a>`. If you find yourself writing this often, it may make sense to extract this into a reusable component.
|
|
447
447
|
* @default ""
|
|
448
448
|
*/
|
|
449
|
-
base?: string
|
|
449
|
+
base?: '' | `/${string}`;
|
|
450
|
+
/**
|
|
451
|
+
* Whether to use relative asset paths. By default, if `paths.assets` is not external, SvelteKit will replace `%sveltekit.assets%` with a relative path and use relative paths to reference build artifacts, but `base` and `assets` imported from `$app/paths` will be as specified in your config.
|
|
452
|
+
*
|
|
453
|
+
* If `true`, `base` and `assets` imported from `$app/paths` will be replaced with relative asset paths during server-side rendering, resulting in portable HTML.
|
|
454
|
+
* If `false`, `%sveltekit.assets%` and references to build artifacts will always be root-relative paths, unless `paths.assets` is an external URL
|
|
455
|
+
* @default undefined
|
|
456
|
+
*/
|
|
457
|
+
relative?: boolean | undefined;
|
|
450
458
|
};
|
|
451
459
|
/**
|
|
452
460
|
* See [Prerendering](https://kit.svelte.dev/docs/page-options#prerender).
|