@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.425",
3
+ "version": "1.0.0-next.428",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -107,9 +107,14 @@ const options = object(
107
107
  return input;
108
108
  }),
109
109
 
110
- browser: object({
111
- hydrate: boolean(true),
112
- router: boolean(true)
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
- setContext('__svelte__', stores);
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> = ${load};`
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
- return {
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.at(-1);
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
- // @ts-expect-error
588
- get props() {
589
- throw new Error(
590
- '@migration task: Replace `props` with `data` stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
591
- );
592
- },
593
- get session() {
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
- get stuff() {
600
- throw new Error(
601
- '@migration task: Remove stuff https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693'
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 data = await node.shared.load.call(null, {
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
 
@@ -16,11 +16,12 @@ export function parse_route_id(id) {
16
16
  id === ''
17
17
  ? /^\/$/
18
18
  : new RegExp(
19
- `^${decodeURIComponent(id)
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(segment);
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
- segment &&
34
+ decoded_segment &&
34
35
  '/' +
35
- segment
36
+ decoded_segment
36
37
  .split(/\[(.+?)\]/)
37
38
  .map((content, i) => {
38
39
  if (i % 2) {
@@ -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 on the server, rather than shared between multiple requests handled by the same server simultaneously.
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
  /**