@sveltejs/kit 1.0.0-next.425 → 1.0.0-next.428
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 +8 -3
- package/src/core/sync/create_manifest_data/index.js +3 -3
- package/src/core/sync/write_root.js +4 -1
- package/src/core/sync/write_tsconfig.js +6 -0
- package/src/core/sync/write_types.js +1 -1
- package/src/runtime/app/stores.js +25 -14
- package/src/runtime/client/client.js +30 -33
- package/src/runtime/client/singletons.js +10 -0
- package/src/runtime/server/page/load_data.js +15 -7
- package/src/utils/routing.js +5 -4
- package/types/ambient.d.ts +13 -11
package/package.json
CHANGED
|
@@ -107,9 +107,14 @@ const options = object(
|
|
|
107
107
|
return input;
|
|
108
108
|
}),
|
|
109
109
|
|
|
110
|
-
browser:
|
|
111
|
-
hydrate: boolean(true),
|
|
112
|
-
|
|
110
|
+
browser: validate({ hydrate: true, router: true }, (input, keypath) => {
|
|
111
|
+
const value = object({ hydrate: boolean(true), router: boolean(true) })(input, keypath);
|
|
112
|
+
if (!value.hydrate && value.router) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
'config.kit.browser.router cannot be true if config.kit.browser.hydrate is false'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return value;
|
|
113
118
|
}),
|
|
114
119
|
|
|
115
120
|
csp: object({
|
|
@@ -478,9 +478,9 @@ function list_files(dir, path = '', files = []) {
|
|
|
478
478
|
// sort each directory in (+layout, +error, everything else) order
|
|
479
479
|
// so that we can trace layouts/errors immediately
|
|
480
480
|
|
|
481
|
-
if (a.startsWith('+layout')) {
|
|
482
|
-
if (!b.startsWith('+layout')) return -1;
|
|
483
|
-
} else if (b.startsWith('+layout')) {
|
|
481
|
+
if (a.startsWith('+layout') || a.startsWith('+error')) {
|
|
482
|
+
if (!b.startsWith('+layout') && !b.startsWith('+error')) return -1;
|
|
483
|
+
} else if (b.startsWith('+layout') || b.startsWith('+error')) {
|
|
484
484
|
return 1;
|
|
485
485
|
} else if (a.startsWith('__')) {
|
|
486
486
|
if (!b.startsWith('__')) return -1;
|
|
@@ -43,6 +43,7 @@ export function write_root(manifest_data, output) {
|
|
|
43
43
|
<!-- This file is generated by @sveltejs/kit — do not edit it! -->
|
|
44
44
|
<script>
|
|
45
45
|
import { setContext, afterUpdate, onMount } from 'svelte';
|
|
46
|
+
import { browser } from '$app/env';
|
|
46
47
|
|
|
47
48
|
// stores
|
|
48
49
|
export let stores;
|
|
@@ -52,7 +53,9 @@ export function write_root(manifest_data, output) {
|
|
|
52
53
|
${levels.map((l) => `export let data_${l} = null;`).join('\n\t\t\t\t')}
|
|
53
54
|
export let errors;
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
if (!browser) {
|
|
57
|
+
setContext('__svelte__', stores);
|
|
58
|
+
}
|
|
56
59
|
|
|
57
60
|
$: stores.page.set(page);
|
|
58
61
|
afterUpdate(stores.page.notify);
|
|
@@ -53,6 +53,12 @@ export function write_tsconfig(config, cwd = process.cwd()) {
|
|
|
53
53
|
include.push(config_relative(`${relative}/**/*.ts`));
|
|
54
54
|
include.push(config_relative(`${relative}/**/*.svelte`));
|
|
55
55
|
}
|
|
56
|
+
// Test folder is a special case - we advocate putting tests in a top-level test folder
|
|
57
|
+
// and it's not configurable (should we make it?)
|
|
58
|
+
const test_folder = project_relative('tests');
|
|
59
|
+
include.push(config_relative(`${test_folder}/**/*.js`));
|
|
60
|
+
include.push(config_relative(`${test_folder}/**/*.ts`));
|
|
61
|
+
include.push(config_relative(`${test_folder}/**/*.svelte`));
|
|
56
62
|
|
|
57
63
|
write_if_changed(
|
|
58
64
|
out,
|
|
@@ -363,7 +363,7 @@ function write_types_for_dir(config, manifest_data, routes_dir, dir, groups, ts)
|
|
|
363
363
|
}
|
|
364
364
|
if (server_load) {
|
|
365
365
|
server_load_exports.push(
|
|
366
|
-
`export type ${name}<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${
|
|
366
|
+
`export type ${name}<OutputData extends Record<string, any> | void = Record<string, any> | void> = ${server_load};`
|
|
367
367
|
);
|
|
368
368
|
server_load_event_exports.push(
|
|
369
369
|
`export type ${name} = Parameters<LayoutServerLoad.${name}>[0];`
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getContext } from 'svelte';
|
|
2
2
|
import { browser } from './env.js';
|
|
3
|
+
import { stores as browser_stores } from '../client/singletons.js';
|
|
3
4
|
|
|
4
5
|
// TODO remove this (for 1.0? after 1.0?)
|
|
5
6
|
let warned = false;
|
|
@@ -15,29 +16,39 @@ export function stores() {
|
|
|
15
16
|
* @type {import('$app/stores').getStores}
|
|
16
17
|
*/
|
|
17
18
|
export const getStores = () => {
|
|
18
|
-
const stores = getContext('__svelte__');
|
|
19
|
+
const stores = browser ? browser_stores : getContext('__svelte__');
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
const readonly_stores = {
|
|
21
22
|
page: {
|
|
22
23
|
subscribe: stores.page.subscribe
|
|
23
24
|
},
|
|
24
25
|
navigating: {
|
|
25
26
|
subscribe: stores.navigating.subscribe
|
|
26
27
|
},
|
|
27
|
-
// TODO remove this (for 1.0? after 1.0?)
|
|
28
|
-
// @ts-expect-error - deprecated, not part of type definitions, but still callable
|
|
29
|
-
get preloading() {
|
|
30
|
-
console.error('stores.preloading is deprecated; use stores.navigating instead');
|
|
31
|
-
return {
|
|
32
|
-
subscribe: stores.navigating.subscribe
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
get session() {
|
|
36
|
-
removed_session();
|
|
37
|
-
return {};
|
|
38
|
-
},
|
|
39
28
|
updated: stores.updated
|
|
40
29
|
};
|
|
30
|
+
|
|
31
|
+
// TODO remove this for 1.0
|
|
32
|
+
Object.defineProperties(readonly_stores, {
|
|
33
|
+
preloading: {
|
|
34
|
+
get() {
|
|
35
|
+
console.error('stores.preloading is deprecated; use stores.navigating instead');
|
|
36
|
+
return {
|
|
37
|
+
subscribe: stores.navigating.subscribe
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
enumerable: false
|
|
41
|
+
},
|
|
42
|
+
session: {
|
|
43
|
+
get() {
|
|
44
|
+
removed_session();
|
|
45
|
+
return {};
|
|
46
|
+
},
|
|
47
|
+
enumerable: false
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return readonly_stores;
|
|
41
52
|
};
|
|
42
53
|
|
|
43
54
|
/** @type {typeof import('$app/stores').page} */
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { onMount, tick } from 'svelte';
|
|
2
|
-
import { writable } from 'svelte/store';
|
|
3
2
|
import { normalize_error } from '../../utils/error.js';
|
|
4
3
|
import { LoadURL, decode_params, normalize_path } from '../../utils/url.js';
|
|
5
|
-
import {
|
|
6
|
-
create_updated_store,
|
|
7
|
-
find_anchor,
|
|
8
|
-
get_base_uri,
|
|
9
|
-
get_href,
|
|
10
|
-
notifiable_store,
|
|
11
|
-
scroll_state
|
|
12
|
-
} from './utils.js';
|
|
4
|
+
import { find_anchor, get_base_uri, get_href, scroll_state } from './utils.js';
|
|
13
5
|
import { lock_fetch, unlock_fetch, initial_fetch, native_fetch } from './fetcher.js';
|
|
14
6
|
import { parse } from './parse.js';
|
|
15
7
|
import { error } from '../../index/index.js';
|
|
@@ -17,6 +9,7 @@ import { error } from '../../index/index.js';
|
|
|
17
9
|
import Root from '__GENERATED__/root.svelte';
|
|
18
10
|
import { nodes, dictionary, matchers } from '__GENERATED__/client-manifest.js';
|
|
19
11
|
import { HttpError, Redirect } from '../../index/private.js';
|
|
12
|
+
import { stores } from './singletons.js';
|
|
20
13
|
|
|
21
14
|
const SCROLL_KEY = 'sveltekit:scroll';
|
|
22
15
|
const INDEX_KEY = 'sveltekit:index';
|
|
@@ -59,13 +52,6 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
59
52
|
/** @type {Array<((href: string) => boolean)>} */
|
|
60
53
|
const invalidated = [];
|
|
61
54
|
|
|
62
|
-
const stores = {
|
|
63
|
-
url: notifiable_store({}),
|
|
64
|
-
page: notifiable_store({}),
|
|
65
|
-
navigating: writable(/** @type {import('types').Navigation | null} */ (null)),
|
|
66
|
-
updated: create_updated_store()
|
|
67
|
-
};
|
|
68
|
-
|
|
69
55
|
/** @type {{id: string | null, promise: Promise<import('./types').NavigationResult | undefined> | null}} */
|
|
70
56
|
const load_cache = {
|
|
71
57
|
id: null,
|
|
@@ -345,7 +331,7 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
345
331
|
page = navigation_result.props.page;
|
|
346
332
|
}
|
|
347
333
|
|
|
348
|
-
const leaf_node = navigation_result.state.branch.
|
|
334
|
+
const leaf_node = navigation_result.state.branch[navigation_result.state.branch.length - 1];
|
|
349
335
|
router_enabled = leaf_node?.node.shared?.router !== false;
|
|
350
336
|
|
|
351
337
|
if (callback) callback();
|
|
@@ -583,25 +569,36 @@ export function create_client({ target, base, trailing_slash }) {
|
|
|
583
569
|
// does await parent() inside an if branch which wasn't executed yet.
|
|
584
570
|
uses.parent = true;
|
|
585
571
|
return parent;
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
|
|
575
|
+
// TODO remove this for 1.0
|
|
576
|
+
Object.defineProperties(load_input, {
|
|
577
|
+
props: {
|
|
578
|
+
get() {
|
|
579
|
+
throw new Error(
|
|
580
|
+
'@migration task: Replace `props` with `data` stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
|
|
581
|
+
);
|
|
582
|
+
},
|
|
583
|
+
enumerable: false
|
|
586
584
|
},
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
// TODO remove this for 1.0
|
|
595
|
-
throw new Error(
|
|
596
|
-
'session is no longer available. See https://github.com/sveltejs/kit/discussions/5883'
|
|
597
|
-
);
|
|
585
|
+
session: {
|
|
586
|
+
get() {
|
|
587
|
+
throw new Error(
|
|
588
|
+
'session is no longer available. See https://github.com/sveltejs/kit/discussions/5883'
|
|
589
|
+
);
|
|
590
|
+
},
|
|
591
|
+
enumerable: false
|
|
598
592
|
},
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
593
|
+
stuff: {
|
|
594
|
+
get() {
|
|
595
|
+
throw new Error(
|
|
596
|
+
'@migration task: Remove stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
|
|
597
|
+
);
|
|
598
|
+
},
|
|
599
|
+
enumerable: false
|
|
603
600
|
}
|
|
604
|
-
};
|
|
601
|
+
});
|
|
605
602
|
|
|
606
603
|
if (import.meta.env.DEV) {
|
|
607
604
|
try {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { writable } from 'svelte/store';
|
|
2
|
+
import { create_updated_store, notifiable_store } from './utils.js';
|
|
3
|
+
|
|
1
4
|
/** @type {import('./types').Client} */
|
|
2
5
|
export let client;
|
|
3
6
|
|
|
@@ -9,3 +12,10 @@ export let client;
|
|
|
9
12
|
export function init(opts) {
|
|
10
13
|
client = opts.client;
|
|
11
14
|
}
|
|
15
|
+
|
|
16
|
+
export const stores = {
|
|
17
|
+
url: notifiable_store({}),
|
|
18
|
+
page: notifiable_store({}),
|
|
19
|
+
navigating: writable(/** @type {import('types').Navigation | null} */ (null)),
|
|
20
|
+
updated: create_updated_store()
|
|
21
|
+
};
|
|
@@ -55,23 +55,31 @@ export async function load_data({ event, fetcher, node, parent, server_data_prom
|
|
|
55
55
|
return server_data;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const
|
|
58
|
+
const load_input = {
|
|
59
59
|
url: state.prerendering ? new PrerenderingURL(event.url) : new LoadURL(event.url),
|
|
60
60
|
params: event.params,
|
|
61
61
|
data: server_data,
|
|
62
62
|
routeId: event.routeId,
|
|
63
|
-
get session() {
|
|
64
|
-
// TODO remove for 1.0
|
|
65
|
-
throw new Error(
|
|
66
|
-
'session is no longer available. See https://github.com/sveltejs/kit/discussions/5883'
|
|
67
|
-
);
|
|
68
|
-
},
|
|
69
63
|
fetch: fetcher,
|
|
70
64
|
setHeaders: event.setHeaders,
|
|
71
65
|
depends: () => {},
|
|
72
66
|
parent
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// TODO remove this for 1.0
|
|
70
|
+
Object.defineProperties(load_input, {
|
|
71
|
+
session: {
|
|
72
|
+
get() {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'session is no longer available. See https://github.com/sveltejs/kit/discussions/5883'
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
enumerable: false
|
|
78
|
+
}
|
|
73
79
|
});
|
|
74
80
|
|
|
81
|
+
const data = await node.shared.load.call(null, load_input);
|
|
82
|
+
|
|
75
83
|
return data ? unwrap_promises(data) : null;
|
|
76
84
|
}
|
|
77
85
|
|
package/src/utils/routing.js
CHANGED
|
@@ -16,11 +16,12 @@ export function parse_route_id(id) {
|
|
|
16
16
|
id === ''
|
|
17
17
|
? /^\/$/
|
|
18
18
|
: new RegExp(
|
|
19
|
-
`^${
|
|
19
|
+
`^${id
|
|
20
20
|
.split(/(?:@[a-zA-Z0-9_-]+)?(?:\/|$)/)
|
|
21
21
|
.map((segment, i, segments) => {
|
|
22
|
+
const decoded_segment = decodeURIComponent(segment);
|
|
22
23
|
// special case — /[...rest]/ could contain zero segments
|
|
23
|
-
const match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(
|
|
24
|
+
const match = /^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(decoded_segment);
|
|
24
25
|
if (match) {
|
|
25
26
|
names.push(match[1]);
|
|
26
27
|
types.push(match[2]);
|
|
@@ -30,9 +31,9 @@ export function parse_route_id(id) {
|
|
|
30
31
|
const is_last = i === segments.length - 1;
|
|
31
32
|
|
|
32
33
|
return (
|
|
33
|
-
|
|
34
|
+
decoded_segment &&
|
|
34
35
|
'/' +
|
|
35
|
-
|
|
36
|
+
decoded_segment
|
|
36
37
|
.split(/\[(.+?)\]/)
|
|
37
38
|
.map((content, i) => {
|
|
38
39
|
if (i % 2) {
|
package/types/ambient.d.ts
CHANGED
|
@@ -216,24 +216,16 @@ declare module '$app/paths' {
|
|
|
216
216
|
* import { getStores, navigating, page, updated } from '$app/stores';
|
|
217
217
|
* ```
|
|
218
218
|
*
|
|
219
|
-
* Stores are _contextual_ — they are added to the [context](https://svelte.dev/tutorial/context-api) of your root component. This means that `page` is unique to each request
|
|
219
|
+
* Stores on the server are _contextual_ — they are added to the [context](https://svelte.dev/tutorial/context-api) of your root component. This means that `page` is unique to each request, rather than shared between multiple requests handled by the same server simultaneously.
|
|
220
220
|
*
|
|
221
221
|
* Because of that, you must subscribe to the stores during component initialization (which happens automatically if you reference the store value, e.g. as `$page`, in a component) before you can use them.
|
|
222
|
+
*
|
|
223
|
+
* In the browser, we don't need to worry about this, and stores can be accessed from anywhere. Code that will only ever run on the browser can refer to (or subscribe to) any of these stores at any time.
|
|
222
224
|
*/
|
|
223
225
|
declare module '$app/stores' {
|
|
224
226
|
import { Readable } from 'svelte/store';
|
|
225
227
|
import { Navigation, Page } from '@sveltejs/kit';
|
|
226
228
|
|
|
227
|
-
/**
|
|
228
|
-
* A convenience function around `getContext`. Must be called during component initialization.
|
|
229
|
-
* Only use this if you need to defer store subscription until after the component has mounted, for some reason.
|
|
230
|
-
*/
|
|
231
|
-
export function getStores(): {
|
|
232
|
-
navigating: typeof navigating;
|
|
233
|
-
page: typeof page;
|
|
234
|
-
updated: typeof updated;
|
|
235
|
-
};
|
|
236
|
-
|
|
237
229
|
/**
|
|
238
230
|
* A readable store whose value contains page data.
|
|
239
231
|
*/
|
|
@@ -248,6 +240,16 @@ declare module '$app/stores' {
|
|
|
248
240
|
* A readable store whose initial value is `false`. If [`version.pollInterval`](https://kit.svelte.dev/docs/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling.
|
|
249
241
|
*/
|
|
250
242
|
export const updated: Readable<boolean> & { check: () => boolean };
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* A function that returns all of the contextual stores. On the server, this must be called during component initialization.
|
|
246
|
+
* Only use this if you need to defer store subscription until after the component has mounted, for some reason.
|
|
247
|
+
*/
|
|
248
|
+
export function getStores(): {
|
|
249
|
+
navigating: typeof navigating;
|
|
250
|
+
page: typeof page;
|
|
251
|
+
updated: typeof updated;
|
|
252
|
+
};
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
/**
|