@sveltejs/kit 1.0.0-next.252 → 1.0.0-next.256

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.
@@ -33,7 +33,8 @@ const getStores = () => {
33
33
  subscribe: stores.navigating.subscribe
34
34
  };
35
35
  },
36
- session: stores.session
36
+ session: stores.session,
37
+ updated: stores.updated
37
38
  };
38
39
  };
39
40
 
@@ -79,4 +80,18 @@ const session = {
79
80
  update: () => throw_error('update')
80
81
  };
81
82
 
82
- export { getStores, navigating, page, session, stores };
83
+ /** @type {typeof import('$app/stores').updated} */
84
+ const updated = {
85
+ subscribe(fn) {
86
+ const store = getStores().updated;
87
+
88
+ if (browser) {
89
+ updated.check = store.check;
90
+ }
91
+
92
+ return store.subscribe(fn);
93
+ },
94
+ check: () => throw_error('check')
95
+ };
96
+
97
+ export { getStores, navigating, page, session, stores, updated };
@@ -3,8 +3,8 @@ import { fallback, routes } from '__GENERATED__/manifest.js';
3
3
  import { onMount, tick } from 'svelte';
4
4
  import { g as get_base_uri } from '../chunks/utils.js';
5
5
  import { writable } from 'svelte/store';
6
+ import { base, set_paths } from '../paths.js';
6
7
  import { init } from './singletons.js';
7
- import { set_paths } from '../paths.js';
8
8
 
9
9
  function scroll_state() {
10
10
  return {
@@ -553,6 +553,56 @@ function notifiable_store(value) {
553
553
  return { notify, set, subscribe };
554
554
  }
555
555
 
556
+ function create_updated_store() {
557
+ const { set, subscribe } = writable(false);
558
+
559
+ const interval = +(
560
+ /** @type {string} */ (import.meta.env.VITE_SVELTEKIT_APP_VERSION_POLL_INTERVAL)
561
+ );
562
+ const initial = import.meta.env.VITE_SVELTEKIT_APP_VERSION;
563
+
564
+ /** @type {NodeJS.Timeout} */
565
+ let timeout;
566
+
567
+ async function check() {
568
+ if (import.meta.env.DEV || import.meta.env.SSR) return false;
569
+
570
+ clearTimeout(timeout);
571
+
572
+ if (interval) timeout = setTimeout(check, interval);
573
+
574
+ const file = import.meta.env.VITE_SVELTEKIT_APP_VERSION_FILE;
575
+
576
+ const res = await fetch(`${base}/${file}`, {
577
+ headers: {
578
+ pragma: 'no-cache',
579
+ 'cache-control': 'no-cache'
580
+ }
581
+ });
582
+
583
+ if (res.ok) {
584
+ const { version } = await res.json();
585
+ const updated = version !== initial;
586
+
587
+ if (updated) {
588
+ set(true);
589
+ clearTimeout(timeout);
590
+ }
591
+
592
+ return updated;
593
+ } else {
594
+ throw new Error(`Version check failed: ${res.status}`);
595
+ }
596
+ }
597
+
598
+ if (interval) timeout = setTimeout(check, interval);
599
+
600
+ return {
601
+ subscribe,
602
+ check
603
+ };
604
+ }
605
+
556
606
  /**
557
607
  * @param {RequestInfo} resource
558
608
  * @param {RequestInit} [opts]
@@ -622,7 +672,8 @@ class Renderer {
622
672
  url: notifiable_store({}),
623
673
  page: notifiable_store({}),
624
674
  navigating: writable(/** @type {Navigating | null} */ (null)),
625
- session: writable(session)
675
+ session: writable(session),
676
+ updated: create_updated_store()
626
677
  };
627
678
 
628
679
  this.$session = null;
@@ -788,6 +839,12 @@ class Renderer {
788
839
  location.href = new URL(navigation_result.redirect, location.href).href;
789
840
  }
790
841
 
842
+ return;
843
+ }
844
+ } else if (navigation_result.props?.page?.status >= 400) {
845
+ const updated = await this.stores.updated.check();
846
+ if (updated) {
847
+ location.href = info.url.href;
791
848
  return;
792
849
  }
793
850
  }
@@ -413,6 +413,16 @@ function safe_not_equal(a, b) {
413
413
  Promise.resolve();
414
414
 
415
415
  const subscriber_queue = [];
416
+ /**
417
+ * Creates a `Readable` store that allows reading by subscription.
418
+ * @param value initial value
419
+ * @param {StartStopNotifier}start start and stop notifications for subscriptions
420
+ */
421
+ function readable(value, start) {
422
+ return {
423
+ subscribe: writable(value, start).subscribe
424
+ };
425
+ }
416
426
  /**
417
427
  * Create a `Writable` store that allows both updating and reading by subscription.
418
428
  * @param {*=}value initial value
@@ -1015,6 +1025,11 @@ class Csp {
1015
1025
 
1016
1026
  // TODO rename this function/module
1017
1027
 
1028
+ const updated = {
1029
+ ...readable(false),
1030
+ check: () => false
1031
+ };
1032
+
1018
1033
  /**
1019
1034
  * @param {{
1020
1035
  * branch: Array<import('./types').Loaded>;
@@ -1091,7 +1106,8 @@ async function render_response({
1091
1106
  stores: {
1092
1107
  page: writable(null),
1093
1108
  navigating: writable(null),
1094
- session
1109
+ session,
1110
+ updated
1095
1111
  },
1096
1112
  page: {
1097
1113
  url: state.prerender ? create_prerendering_url_proxy(url) : url,
@@ -1535,6 +1551,15 @@ async function load_node({
1535
1551
 
1536
1552
  opts.headers = new Headers(opts.headers);
1537
1553
 
1554
+ // merge headers from request
1555
+ for (const [key, value] of event.request.headers) {
1556
+ if (opts.headers.has(key)) continue;
1557
+ if (key === 'cookie' || key === 'authorization' || key === 'if-none-match') continue;
1558
+ opts.headers.set(key, value);
1559
+ }
1560
+
1561
+ opts.headers.set('referer', event.url.href);
1562
+
1538
1563
  const resolved = resolve(event.url.pathname, requested.split('?')[0]);
1539
1564
 
1540
1565
  /** @type {Response} */
@@ -1650,10 +1675,10 @@ async function load_node({
1650
1675
  if (!opts.body || typeof opts.body === 'string') {
1651
1676
  // prettier-ignore
1652
1677
  fetched.push({
1653
- url: requested,
1654
- body: /** @type {string} */ (opts.body),
1655
- json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
1656
- });
1678
+ url: requested,
1679
+ body: /** @type {string} */ (opts.body),
1680
+ json: `{"status":${response.status},"statusText":${s(response.statusText)},"headers":${s(headers)},"body":"${escape_json_string_in_html(body)}"}`
1681
+ });
1657
1682
  }
1658
1683
 
1659
1684
  if (dependency) {
@@ -37,6 +37,8 @@ async function create_plugin(config, cwd) {
37
37
  amp = (await import('./amp_hook.js')).handle;
38
38
  }
39
39
 
40
+ process.env.VITE_SVELTEKIT_APP_VERSION_POLL_INTERVAL = '0';
41
+
40
42
  /** @type {import('types/internal').Respond} */
41
43
  const respond = (await import(`${runtime}/server/index.js`)).respond;
42
44
 
@@ -394,7 +396,7 @@ async function dev({ cwd, port, host, https, config }) {
394
396
  strictPort: true
395
397
  }
396
398
  },
397
- config.kit.vite()
399
+ await config.kit.vite()
398
400
  );
399
401
 
400
402
  /** @type {[any, string[]]} */
@@ -63,7 +63,7 @@ async function build_service_worker(
63
63
  );
64
64
 
65
65
  /** @type {[any, string[]]} */
66
- const [merged_config, conflicts] = deep_merge(config.kit.vite(), {
66
+ const [merged_config, conflicts] = deep_merge(await config.kit.vite(), {
67
67
  configFile: false,
68
68
  root: cwd,
69
69
  base: assets_base,
@@ -151,6 +151,10 @@ async function build_client({
151
151
  output_dir,
152
152
  client_entry_file
153
153
  }) {
154
+ process.env.VITE_SVELTEKIT_APP_VERSION = config.kit.version.name;
155
+ process.env.VITE_SVELTEKIT_APP_VERSION_FILE = `${config.kit.appDir}/version.json`;
156
+ process.env.VITE_SVELTEKIT_APP_VERSION_POLL_INTERVAL = `${config.kit.version.pollInterval}`;
157
+
154
158
  create_app({
155
159
  manifest_data,
156
160
  output: `${SVELTE_KIT}/generated`,
@@ -182,7 +186,7 @@ async function build_client({
182
186
  });
183
187
 
184
188
  /** @type {[any, string[]]} */
185
- const [merged_config, conflicts] = deep_merge(config.kit.vite(), {
189
+ const [merged_config, conflicts] = deep_merge(await config.kit.vite(), {
186
190
  configFile: false,
187
191
  root: cwd,
188
192
  base: assets_base,
@@ -227,6 +231,11 @@ async function build_client({
227
231
  const entry_css = new Set();
228
232
  find_deps(entry, vite_manifest, entry_js, entry_css);
229
233
 
234
+ fs__default.writeFileSync(
235
+ `${client_out_dir}/version.json`,
236
+ JSON.stringify({ version: process.env.VITE_SVELTEKIT_APP_VERSION })
237
+ );
238
+
230
239
  return {
231
240
  assets,
232
241
  chunks,
@@ -411,7 +420,7 @@ async function build_server(
411
420
  );
412
421
 
413
422
  /** @type {import('vite').UserConfig} */
414
- const vite_config = config.kit.vite();
423
+ const vite_config = await config.kit.vite();
415
424
 
416
425
  const default_config = {
417
426
  build: {
@@ -626,7 +635,7 @@ async function build(config) {
626
635
  const build_data = {
627
636
  app_dir: config.kit.appDir,
628
637
  manifest_data: options.manifest_data,
629
- service_worker: options.service_worker_entry_file ? 'service_worker.js' : null, // TODO make file configurable?
638
+ service_worker: options.service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable?
630
639
  client,
631
640
  server,
632
641
  static: options.manifest_data.assets.map((asset) => posixify(asset.file)),
@@ -311,6 +311,8 @@ function crawl(html) {
311
311
  hrefs.push(src);
312
312
  }
313
313
  }
314
+ } else {
315
+ i -= 1;
314
316
  }
315
317
  }
316
318
 
@@ -81,7 +81,7 @@ async function preview({
81
81
  const app = new App(manifest);
82
82
 
83
83
  /** @type {import('vite').UserConfig} */
84
- const vite_config = (config.kit.vite && config.kit.vite()) || {};
84
+ const vite_config = (config.kit.vite && (await config.kit.vite())) || {};
85
85
 
86
86
  const server = await get_server(use_https, vite_config, (req, res) => {
87
87
  if (req.url == null) {
package/dist/cli.js CHANGED
@@ -688,6 +688,11 @@ const options = object(
688
688
 
689
689
  trailingSlash: list(['never', 'always', 'ignore']),
690
690
 
691
+ version: object({
692
+ name: string(Date.now().toString()),
693
+ pollInterval: number(0)
694
+ }),
695
+
691
696
  vite: validate(
692
697
  () => ({}),
693
698
  (input, keypath) => {
@@ -989,7 +994,7 @@ async function launch(port, https) {
989
994
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
990
995
  }
991
996
 
992
- const prog = sade('svelte-kit').version('1.0.0-next.252');
997
+ const prog = sade('svelte-kit').version('1.0.0-next.256');
993
998
 
994
999
  prog
995
1000
  .command('dev')
@@ -1147,7 +1152,7 @@ async function check_port(port) {
1147
1152
  function welcome({ port, host, https, open, loose, allow, cwd }) {
1148
1153
  if (open) launch(port, https);
1149
1154
 
1150
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.252'}\n`));
1155
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.256'}\n`));
1151
1156
 
1152
1157
  const protocol = https ? 'https:' : 'http:';
1153
1158
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.252",
3
+ "version": "1.0.0-next.256",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -110,6 +110,7 @@ declare module '$app/stores' {
110
110
  navigating: typeof navigating;
111
111
  page: typeof page;
112
112
  session: Writable<Session>;
113
+ updated: typeof updated;
113
114
  };
114
115
  /**
115
116
  * A readable store whose value contains page data.
@@ -132,6 +133,11 @@ declare module '$app/stores' {
132
133
  * It can be written to, but this will not cause changes to persist on the server — this is something you must implement yourself.
133
134
  */
134
135
  export const session: Writable<any>;
136
+ /**
137
+ * A writable store indicating if the site was updated since the store was created.
138
+ * It can be written to when custom logic is required to detect updates.
139
+ */
140
+ export const updated: Readable<boolean> & { check: () => boolean };
135
141
  }
136
142
 
137
143
  declare module '$service-worker' {
package/types/config.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CompileOptions } from 'svelte/types/compiler/interfaces';
2
2
  import { UserConfig as ViteConfig } from 'vite';
3
3
  import { CspDirectives } from './csp';
4
- import { RecursiveRequired } from './helper';
4
+ import { MaybePromise, RecursiveRequired } from './helper';
5
5
  import { HttpMethod, Logger, RouteSegment, TrailingSlash } from './internal';
6
6
 
7
7
  export interface RouteDefinition {
@@ -165,7 +165,11 @@ export interface Config {
165
165
  };
166
166
  target?: string;
167
167
  trailingSlash?: TrailingSlash;
168
- vite?: ViteConfig | (() => ViteConfig);
168
+ version?: {
169
+ name?: string;
170
+ pollInterval?: number;
171
+ };
172
+ vite?: ViteConfig | (() => MaybePromise<ViteConfig>);
169
173
  };
170
174
  preprocess?: any;
171
175
  }