@sveltejs/kit 1.0.0-next.212 → 1.0.0-next.216

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/assets/kit.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @param {Record<string, string | string[]>} headers
2
+ * @param {Record<string, string | string[] | undefined>} headers
3
3
  * @param {string} key
4
4
  * @returns {string | undefined}
5
5
  * @throws {Error}
@@ -1,4 +1,4 @@
1
- import { router as router$1 } from '../internal/singletons.js';
1
+ import { renderer, router as router$1 } from '../internal/singletons.js';
2
2
  import { g as get_base_uri } from '../chunks/utils.js';
3
3
 
4
4
  const router = /** @type {import('../client/router').Router} */ (router$1);
@@ -12,11 +12,21 @@ function guard(name) {
12
12
  };
13
13
  }
14
14
 
15
+ const disableScrollHandling = import.meta.env.SSR
16
+ ? guard('disableScrollHandling')
17
+ : disableScrollHandling_;
15
18
  const goto = import.meta.env.SSR ? guard('goto') : goto_;
16
19
  const invalidate = import.meta.env.SSR ? guard('invalidate') : invalidate_;
17
20
  const prefetch = import.meta.env.SSR ? guard('prefetch') : prefetch_;
18
21
  const prefetchRoutes = import.meta.env.SSR ? guard('prefetchRoutes') : prefetchRoutes_;
19
22
 
23
+ /**
24
+ * @type {import('$app/navigation').goto}
25
+ */
26
+ async function disableScrollHandling_() {
27
+ renderer.disable_scroll_handling();
28
+ }
29
+
20
30
  /**
21
31
  * @type {import('$app/navigation').goto}
22
32
  */
@@ -52,4 +62,4 @@ async function prefetchRoutes_(pathnames) {
52
62
  await Promise.all(promises);
53
63
  }
54
64
 
55
- export { goto, invalidate, prefetch, prefetchRoutes };
65
+ export { disableScrollHandling, goto, invalidate, prefetch, prefetchRoutes };
@@ -1,9 +1,18 @@
1
1
  /** @type {import('./router').Router?} */
2
2
  let router;
3
3
 
4
- /** @param {import('./router').Router?} _ */
5
- function init(_) {
6
- router = _;
4
+ /** @type {import('./renderer').Renderer} */
5
+ let renderer;
6
+
7
+ /**
8
+ * @param {{
9
+ * router: import('./router').Router?;
10
+ * renderer: import('./renderer').Renderer;
11
+ * }} opts
12
+ */
13
+ function init(opts) {
14
+ router = opts.router;
15
+ renderer = opts.renderer;
7
16
  }
8
17
 
9
- export { init, router };
18
+ export { init, renderer, router };
@@ -162,16 +162,17 @@ class Router {
162
162
 
163
163
  if (!this.owns(url)) return;
164
164
 
165
- const noscroll = a.hasAttribute('sveltekit:noscroll');
165
+ // Check if new url only differs by hash
166
+ if (url.href.split('#')[0] === location.href.split('#')[0]) {
167
+ // Call `pushState` to add url to history so going back works.
168
+ // Also make a delay, otherwise the browser default behaviour would not kick in
169
+ setTimeout(() => history.pushState({}, '', url.href));
170
+ return;
171
+ }
166
172
 
167
- const i1 = url_string.indexOf('#');
168
- const i2 = location.href.indexOf('#');
169
- const u1 = i1 >= 0 ? url_string.substring(0, i1) : url_string;
170
- const u2 = i2 >= 0 ? location.href.substring(0, i2) : location.href;
171
173
  history.pushState({}, '', url.href);
172
- if (u1 === u2) {
173
- window.dispatchEvent(new HashChangeEvent('hashchange'));
174
- }
174
+
175
+ const noscroll = a.hasAttribute('sveltekit:noscroll');
175
176
  this._navigate(url, noscroll ? scroll_state() : null, false, [], url.hash);
176
177
  event.preventDefault();
177
178
  });
@@ -466,6 +467,8 @@ class Renderer {
466
467
  this.session_id = 1;
467
468
  this.invalid = new Set();
468
469
  this.invalidating = null;
470
+ this.autoscroll = true;
471
+ this.updating = false;
469
472
 
470
473
  /** @type {import('./types').NavigationState} */
471
474
  this.current = {
@@ -508,6 +511,16 @@ class Renderer {
508
511
  ready = true;
509
512
  }
510
513
 
514
+ disable_scroll_handling() {
515
+ if (import.meta.env.DEV && this.started && !this.updating) {
516
+ throw new Error('Can only disable scroll handling during navigation');
517
+ }
518
+
519
+ if (this.updating || !this.started) {
520
+ this.autoscroll = false;
521
+ }
522
+ }
523
+
511
524
  /**
512
525
  * @param {{
513
526
  * status: number;
@@ -637,6 +650,8 @@ class Renderer {
637
650
  }
638
651
  }
639
652
 
653
+ this.updating = true;
654
+
640
655
  if (this.started) {
641
656
  this.current = navigation_result.state;
642
657
 
@@ -655,26 +670,9 @@ class Renderer {
655
670
  document.body.focus();
656
671
  }
657
672
 
658
- const old_page_y_offset = Math.round(pageYOffset);
659
- const old_max_page_y_offset = document.documentElement.scrollHeight - innerHeight;
660
-
661
673
  await 0;
662
674
 
663
- const new_page_y_offset = Math.round(pageYOffset);
664
- const new_max_page_y_offset = document.documentElement.scrollHeight - innerHeight;
665
-
666
- // After `await 0`, the `onMount()` function in the component executed.
667
- // Check if no scrolling happened on mount.
668
- const no_scroll_happened =
669
- // In most cases, we can compare whether `pageYOffset` changed between navigation
670
- new_page_y_offset === Math.min(old_page_y_offset, new_max_page_y_offset) ||
671
- // But if the page is scrolled to/near the bottom, the browser would also scroll
672
- // to/near the bottom of the new page on navigation. Since we can't detect when this
673
- // behaviour happens, we naively compare by the y offset from the bottom of the page.
674
- old_max_page_y_offset - old_page_y_offset === new_max_page_y_offset - new_page_y_offset;
675
-
676
- // If there was no scrolling, we run on our custom scroll handling
677
- if (no_scroll_happened) {
675
+ if (this.autoscroll) {
678
676
  const deep_linked = hash && document.getElementById(hash.slice(1));
679
677
  if (scroll) {
680
678
  scrollTo(scroll.x, scroll.y);
@@ -694,6 +692,8 @@ class Renderer {
694
692
 
695
693
  this.loading.promise = null;
696
694
  this.loading.id = null;
695
+ this.autoscroll = true;
696
+ this.updating = false;
697
697
 
698
698
  if (!this.router) return;
699
699
 
@@ -1202,7 +1202,7 @@ async function start({ paths, target, session, route, spa, trailing_slash, hydra
1202
1202
  })
1203
1203
  : null;
1204
1204
 
1205
- init(router);
1205
+ init({ router, renderer });
1206
1206
  set_paths(paths);
1207
1207
 
1208
1208
  if (hydrate) await renderer.start(hydrate);
@@ -12,7 +12,7 @@ import 'querystring';
12
12
  import { URL } from 'url';
13
13
  import require$$10 from 'vm';
14
14
  import vite from 'vite';
15
- import { r as resolve_entry, $, g as get_mime_lookup, a as rimraf, c as copy_assets, p as print_config_conflicts } from '../cli.js';
15
+ import { r as resolve_entry, $, l as load_template, g as get_mime_lookup, a as rimraf, c as copy_assets, p as print_config_conflicts } from '../cli.js';
16
16
  import { c as create_manifest_data, a as create_app, d as deep_merge } from './index2.js';
17
17
  import { S as SVELTE_KIT, a as SVELTE_KIT_ASSETS } from './constants.js';
18
18
  import { respond } from '../ssr.js';
@@ -4407,8 +4407,7 @@ function create_plugin(config, output, cwd, amp) {
4407
4407
  ssr: config.kit.ssr,
4408
4408
  target: config.kit.target,
4409
4409
  template: ({ head, body }) => {
4410
- let rendered = fs__default
4411
- .readFileSync(config.kit.files.template, 'utf8')
4410
+ let rendered = load_template(cwd, config)
4412
4411
  .replace('%svelte.head%', () => head)
4413
4412
  .replace('%svelte.body%', () => body);
4414
4413
 
@@ -1,6 +1,6 @@
1
1
  import fs__default from 'fs';
2
2
  import path__default from 'path';
3
- import { p as print_config_conflicts, c as copy_assets, b as posixify, r as resolve_entry, m as mkdirp, a as rimraf } from '../cli.js';
3
+ import { p as print_config_conflicts, c as copy_assets, b as posixify, r as resolve_entry, l as load_template, m as mkdirp, a as rimraf } from '../cli.js';
4
4
  import { d as deep_merge, a as create_app, c as create_manifest_data } from './index2.js';
5
5
  import { S as SVELTE_KIT } from './constants.js';
6
6
  import { g as generate_manifest } from './index4.js';
@@ -247,20 +247,22 @@ async function build_client({
247
247
 
248
248
  /**
249
249
  * @param {{
250
- * runtime: string,
251
- * hooks: string,
252
- * config: import('types/config').ValidatedConfig
250
+ * cwd: string;
251
+ * runtime: string;
252
+ * hooks: string;
253
+ * config: import('types/config').ValidatedConfig;
254
+ * has_service_worker: boolean;
253
255
  * }} opts
254
256
  * @returns
255
257
  */
256
- const template = ({ config, hooks, runtime }) => `
258
+ const template = ({ cwd, config, hooks, runtime, has_service_worker }) => `
257
259
  import { respond } from '${runtime}';
258
260
  import root from './generated/root.svelte';
259
261
  import { set_paths, assets, base } from './runtime/paths.js';
260
262
  import { set_prerendering } from './runtime/env.js';
261
263
  import * as user_hooks from ${s(hooks)};
262
264
 
263
- const template = ({ head, body }) => ${s(fs__default.readFileSync(config.kit.files.template, 'utf-8'))
265
+ const template = ({ head, body }) => ${s(load_template(cwd, config))
264
266
  .replace('%svelte.head%', '" + head + "')
265
267
  .replace('%svelte.body%', '" + body + "')};
266
268
 
@@ -309,11 +311,7 @@ export class App {
309
311
  prerender: ${config.kit.prerender.enabled},
310
312
  read,
311
313
  root,
312
- service_worker: ${
313
- config.kit.files.serviceWorker && config.kit.serviceWorker.register
314
- ? "'/service-worker.js'"
315
- : 'null'
316
- },
314
+ service_worker: ${has_service_worker ? "'/service-worker.js'" : 'null'},
317
315
  router: ${s(config.kit.router)},
318
316
  ssr: ${s(config.kit.ssr)},
319
317
  target: ${s(config.kit.target)},
@@ -356,12 +354,23 @@ export class App {
356
354
  * manifest_data: import('types/internal').ManifestData
357
355
  * build_dir: string;
358
356
  * output_dir: string;
357
+ * service_worker_entry_file: string | null;
358
+ * service_worker_register: boolean;
359
359
  * }} options
360
360
  * @param {string} runtime
361
361
  * @param {{ vite_manifest: import('vite').Manifest, assets: import('rollup').OutputAsset[] }} client
362
362
  */
363
363
  async function build_server(
364
- { cwd, assets_base, config, manifest_data, build_dir, output_dir },
364
+ {
365
+ cwd,
366
+ assets_base,
367
+ config,
368
+ manifest_data,
369
+ build_dir,
370
+ output_dir,
371
+ service_worker_entry_file,
372
+ service_worker_register
373
+ },
365
374
  runtime,
366
375
  client
367
376
  ) {
@@ -407,9 +416,11 @@ async function build_server(
407
416
  fs__default.writeFileSync(
408
417
  input.app,
409
418
  template({
419
+ cwd,
410
420
  config,
411
421
  hooks: app_relative(hooks_file),
412
- runtime
422
+ runtime,
423
+ has_service_worker: service_worker_register && !!service_worker_entry_file
413
424
  })
414
425
  );
415
426
 
@@ -1,4 +1,4 @@
1
- import { m as mkdirp, a as rimraf, d as copy, $, l as logger } from '../cli.js';
1
+ import { m as mkdirp, a as rimraf, d as copy, $, e as logger } from '../cli.js';
2
2
  import { S as SVELTE_KIT } from './constants.js';
3
3
  import { readFileSync, writeFileSync } from 'fs';
4
4
  import { resolve, join, dirname } from 'path';
@@ -270,7 +270,7 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
270
270
 
271
271
  const rendered = await app.render(
272
272
  {
273
- url: `${config.kit.protocol || 'sveltekit'}://${config.kit.host || 'prerender'}${path}`,
273
+ url: `${config.kit.protocol || 'http'}://${config.kit.host || 'prerender'}${path}`,
274
274
  method: 'GET',
275
275
  headers: {},
276
276
  rawBody: null
@@ -417,7 +417,7 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
417
417
  if (fallback) {
418
418
  const rendered = await app.render(
419
419
  {
420
- url: `${config.kit.host || 'sveltekit'}://${config.kit.host || 'prerender'}/[fallback]`,
420
+ url: `${config.kit.protocol || 'http'}://${config.kit.host || 'prerender'}/[fallback]`,
421
421
  method: 'GET',
422
422
  headers: {},
423
423
  rawBody: null
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @param {Record<string, string | string[]>} headers
2
+ * @param {Record<string, string | string[] | undefined>} headers
3
3
  * @param {string} key
4
4
  * @returns {string | undefined}
5
5
  * @throws {Error}
package/dist/cli.js CHANGED
@@ -740,10 +740,10 @@ function assert_string(input, keypath) {
740
740
 
741
741
  /**
742
742
  * @param {string} cwd
743
- * @param {import('types/config').ValidatedConfig} validated
743
+ * @param {import('types/config').ValidatedConfig} config
744
744
  */
745
- function validate_template(cwd, validated) {
746
- const { template } = validated.kit.files;
745
+ function load_template(cwd, config) {
746
+ const { template } = config.kit.files;
747
747
  const relative = path__default.relative(cwd, template);
748
748
 
749
749
  if (fs__default.existsSync(template)) {
@@ -757,6 +757,8 @@ function validate_template(cwd, validated) {
757
757
  } else {
758
758
  throw new Error(`${relative} does not exist`);
759
759
  }
760
+
761
+ return fs__default.readFileSync(template, 'utf-8');
760
762
  }
761
763
 
762
764
  async function load_config({ cwd = process.cwd() } = {}) {
@@ -775,10 +777,6 @@ async function load_config({ cwd = process.cwd() } = {}) {
775
777
  validated.kit.files.serviceWorker = path__default.resolve(cwd, validated.kit.files.serviceWorker);
776
778
  validated.kit.files.template = path__default.resolve(cwd, validated.kit.files.template);
777
779
 
778
- validate_template(cwd, validated);
779
-
780
- // TODO check all the `files` exist when the config is loaded?
781
-
782
780
  return validated;
783
781
  }
784
782
 
@@ -887,7 +885,7 @@ async function launch(port, https) {
887
885
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
888
886
  }
889
887
 
890
- const prog = sade('svelte-kit').version('1.0.0-next.212');
888
+ const prog = sade('svelte-kit').version('1.0.0-next.216');
891
889
 
892
890
  prog
893
891
  .command('dev')
@@ -1039,7 +1037,7 @@ async function check_port(port) {
1039
1037
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1040
1038
  if (open) launch(port, https);
1041
1039
 
1042
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.212'}\n`));
1040
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.216'}\n`));
1043
1041
 
1044
1042
  const protocol = https ? 'https:' : 'http:';
1045
1043
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
@@ -1076,4 +1074,4 @@ function welcome({ port, host, https, open, loose, allow, cwd }) {
1076
1074
  console.log('\n');
1077
1075
  }
1078
1076
 
1079
- export { $, rimraf as a, posixify as b, copy_assets as c, copy as d, get_mime_lookup as g, logger as l, mkdirp as m, print_config_conflicts as p, resolve_entry as r, walk as w };
1077
+ export { $, rimraf as a, posixify as b, copy_assets as c, copy as d, logger as e, get_mime_lookup as g, load_template as l, mkdirp as m, print_config_conflicts as p, resolve_entry as r, walk as w };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.212",
3
+ "version": "1.0.0-next.216",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -15,6 +15,7 @@
15
15
  "vite": "^2.7.2"
16
16
  },
17
17
  "devDependencies": {
18
+ "@playwright/test": "^1.17.1",
18
19
  "@rollup/plugin-replace": "^3.0.0",
19
20
  "@types/amphtml-validator": "^1.0.1",
20
21
  "@types/cookie": "^0.4.1",
@@ -24,6 +25,7 @@
24
25
  "@types/sade": "^1.7.3",
25
26
  "amphtml-validator": "^1.0.35",
26
27
  "cookie": "^0.4.1",
28
+ "cross-env": "^7.0.3",
27
29
  "devalue": "^2.0.1",
28
30
  "eslint": "^8.3.0",
29
31
  "kleur": "^4.1.4",
@@ -85,6 +87,10 @@
85
87
  "test": "npm run test:unit && npm run test:packaging && npm run test:integration",
86
88
  "test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
87
89
  "test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
88
- "test:integration": "uvu test test.js"
90
+ "test:integration": "pnpm test:integration:amp && pnpm test:integration:basics && pnpm test:integration:options && pnpm test:integration:options-2",
91
+ "test:integration:amp": "cd test/apps/amp && pnpm test",
92
+ "test:integration:basics": "cd test/apps/basics && pnpm test",
93
+ "test:integration:options": "cd test/apps/options && pnpm test",
94
+ "test:integration:options-2": "cd test/apps/options-2 && pnpm test"
89
95
  }
90
96
  }
@@ -26,6 +26,11 @@ declare module '$app/env' {
26
26
  }
27
27
 
28
28
  declare module '$app/navigation' {
29
+ /**
30
+ * Disable SvelteKit's built-in scroll handling for the current navigation, in case you need to manually control the scroll position.
31
+ * This is generally discouraged, since it breaks user expectations.
32
+ */
33
+ export function disableScrollHandling(): void;
29
34
  /**
30
35
  * Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) to the specified href.
31
36
  *
@@ -5,7 +5,7 @@ type DefaultBody = JSONString | Uint8Array;
5
5
 
6
6
  export interface EndpointOutput<Body extends DefaultBody = DefaultBody> {
7
7
  status?: number;
8
- headers?: ResponseHeaders;
8
+ headers?: Partial<ResponseHeaders>;
9
9
  body?: Body;
10
10
  }
11
11
 
package/types/hooks.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface ServerRequest<Locals = Record<string, any>, Body = unknown> {
15
15
 
16
16
  export interface ServerResponse {
17
17
  status: number;
18
- headers: ResponseHeaders;
18
+ headers: Partial<ResponseHeaders>;
19
19
  body?: StrictBody;
20
20
  }
21
21