@sveltejs/kit 1.0.0-next.202 → 1.0.0-next.206

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.
@@ -99,7 +99,7 @@ class Router {
99
99
  }, 200);
100
100
  });
101
101
 
102
- /** @param {MouseEvent|TouchEvent} event */
102
+ /** @param {Event} event */
103
103
  const trigger_prefetch = (event) => {
104
104
  const a = find_anchor(event);
105
105
  if (a && a.href && a.hasAttribute('sveltekit:prefetch')) {
@@ -114,12 +114,17 @@ class Router {
114
114
  const handle_mousemove = (event) => {
115
115
  clearTimeout(mousemove_timeout);
116
116
  mousemove_timeout = setTimeout(() => {
117
- trigger_prefetch(event);
117
+ // event.composedPath(), which is used in find_anchor, will be empty if the event is read in a timeout
118
+ // add a layer of indirection to address that
119
+ event.target?.dispatchEvent(
120
+ new CustomEvent('sveltekit:trigger_prefetch', { bubbles: true })
121
+ );
118
122
  }, 20);
119
123
  };
120
124
 
121
125
  addEventListener('touchstart', trigger_prefetch);
122
126
  addEventListener('mousemove', handle_mousemove);
127
+ addEventListener('sveltekit:trigger_prefetch', trigger_prefetch);
123
128
 
124
129
  /** @param {MouseEvent} event */
125
130
  addEventListener('click', (event) => {
@@ -4358,7 +4358,6 @@ class Watcher extends EventEmitter {
4358
4358
  }
4359
4359
 
4360
4360
  this.vite = await vite.createServer(merged_config);
4361
- remove_html_middlewares(this.vite.middlewares);
4362
4361
  await this.vite.listen(this.port);
4363
4362
  }
4364
4363
 
@@ -4714,6 +4713,7 @@ async function create_plugin(config, dir, cwd, get_manifest) {
4714
4713
  */
4715
4714
  configureServer(vite) {
4716
4715
  return () => {
4716
+ remove_html_middlewares(vite.middlewares);
4717
4717
  vite.middlewares.use(create_kit_middleware(vite));
4718
4718
  };
4719
4719
  }
@@ -212,11 +212,13 @@ function generate_app(manifest_data) {
212
212
 
213
213
  while (l--) {
214
214
  pyramid = `
215
- <svelte:component this={components[${l}]} {...(props_${l} || {})}>
216
- {#if components[${l + 1}]}
215
+ {#if components[${l + 1}]}
216
+ <svelte:component this={components[${l}]} {...(props_${l} || {})}>
217
217
  ${pyramid.replace(/\n/g, '\n\t\t\t\t\t')}
218
- {/if}
219
- </svelte:component>
218
+ </svelte:component>
219
+ {:else}
220
+ <svelte:component this={components[${l}]} {...(props_${l} || {})} />
221
+ {/if}
220
222
  `
221
223
  .replace(/^\t\t\t/gm, '')
222
224
  .trim();
@@ -498,7 +500,7 @@ function create_manifest_data({ config, output, cwd = process.cwd() }) {
498
500
  basename,
499
501
  ext,
500
502
  parts,
501
- file: posixify(file),
503
+ file,
502
504
  is_dir,
503
505
  is_index,
504
506
  is_page,
@@ -670,9 +672,10 @@ function comparator(a, b) {
670
672
  if (!a_sub_part) return 1; // b is more specific, so goes first
671
673
  if (!b_sub_part) return -1;
672
674
 
673
- // if spread && index, order later
675
+ // if spread, order later
674
676
  if (a_sub_part.spread && b_sub_part.spread) {
675
- return a.is_index ? 1 : -1;
677
+ // sort alphabetically
678
+ return a_sub_part.content < b_sub_part.content ? -1 : 1;
676
679
  }
677
680
 
678
681
  // If one is ...spread order it later
@@ -17,6 +17,85 @@ import 'node:stream';
17
17
  import 'node:util';
18
18
  import 'node:url';
19
19
 
20
+ /** @typedef {{
21
+ * fn: () => Promise<any>,
22
+ * fulfil: (value: any) => void,
23
+ * reject: (error: Error) => void
24
+ * }} Task */
25
+
26
+ /** @param {number} concurrency */
27
+ function queue(concurrency) {
28
+ /** @type {Task[]} */
29
+ const tasks = [];
30
+
31
+ let current = 0;
32
+
33
+ /** @type {(value?: any) => void} */
34
+ let fulfil;
35
+
36
+ /** @type {(error: Error) => void} */
37
+ let reject;
38
+
39
+ let closed = false;
40
+
41
+ const done = new Promise((f, r) => {
42
+ fulfil = f;
43
+ reject = r;
44
+ });
45
+
46
+ done.catch(() => {
47
+ // this is necessary in case a catch handler is never added
48
+ // to the done promise by the user
49
+ });
50
+
51
+ function dequeue() {
52
+ if (current < concurrency) {
53
+ const task = tasks.shift();
54
+
55
+ if (task) {
56
+ current += 1;
57
+ const promise = Promise.resolve(task.fn());
58
+
59
+ promise
60
+ .then(task.fulfil, (err) => {
61
+ task.reject(err);
62
+ reject(err);
63
+ })
64
+ .then(() => {
65
+ current -= 1;
66
+ dequeue();
67
+ });
68
+ } else if (current === 0) {
69
+ closed = true;
70
+ fulfil();
71
+ }
72
+ }
73
+ }
74
+
75
+ return {
76
+ /** @param {() => any} fn */
77
+ add: (fn) => {
78
+ if (closed) throw new Error('Cannot add tasks to a queue that has ended');
79
+
80
+ const promise = new Promise((fulfil, reject) => {
81
+ tasks.push({ fn, fulfil, reject });
82
+ });
83
+
84
+ dequeue();
85
+ return promise;
86
+ },
87
+
88
+ done: () => {
89
+ if (current === 0) {
90
+ closed = true;
91
+ fulfil();
92
+ }
93
+
94
+ return done;
95
+ }
96
+ };
97
+ }
98
+
20
99
  /**
21
100
  * @typedef {import('types/config').PrerenderErrorHandler} PrerenderErrorHandler
22
101
  * @typedef {import('types/config').PrerenderOnErrorValue} OnError
@@ -151,16 +230,27 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
151
230
  return path;
152
231
  }
153
232
 
233
+ const q = queue(config.kit.prerender.concurrency);
234
+
154
235
  /**
155
236
  * @param {string} decoded_path
156
237
  * @param {string?} referrer
157
238
  */
158
- async function visit(decoded_path, referrer) {
239
+ function enqueue(decoded_path, referrer) {
159
240
  const path = encodeURI(normalize(decoded_path));
160
241
 
161
242
  if (seen.has(path)) return;
162
243
  seen.add(path);
163
244
 
245
+ return q.add(() => visit(path, decoded_path, referrer));
246
+ }
247
+
248
+ /**
249
+ * @param {string} path
250
+ * @param {string} decoded_path
251
+ * @param {string?} referrer
252
+ */
253
+ async function visit(path, decoded_path, referrer) {
164
254
  /** @type {Map<string, import('types/hooks').ServerResponse>} */
165
255
  const dependencies = new Map();
166
256
 
@@ -205,7 +295,7 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
205
295
 
206
296
  const resolved = resolve$1(path, location);
207
297
  if (is_root_relative(resolved)) {
208
- await visit(resolved, path);
298
+ enqueue(resolved, path);
209
299
  }
210
300
  } else {
211
301
  log.warn(`location header missing on redirect received from ${decoded_path}`);
@@ -290,7 +380,7 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
290
380
 
291
381
  if (parsed.search) ;
292
382
 
293
- await visit(pathname, path);
383
+ enqueue(pathname, path);
294
384
  }
295
385
  }
296
386
  }
@@ -300,12 +390,14 @@ async function prerender({ cwd, out, log, config, build_data, fallback, all }) {
300
390
  for (const entry of config.kit.prerender.entries) {
301
391
  if (entry === '*') {
302
392
  for (const entry of build_data.entries) {
303
- await visit(entry, null);
393
+ enqueue(entry, null);
304
394
  }
305
395
  } else {
306
- await visit(entry, null);
396
+ enqueue(entry, null);
307
397
  }
308
398
  }
399
+
400
+ await q.done();
309
401
  }
310
402
 
311
403
  if (fallback) {
package/dist/cli.js CHANGED
@@ -471,6 +471,7 @@ const options = object(
471
471
  }),
472
472
 
473
473
  prerender: object({
474
+ concurrency: number(1),
474
475
  crawl: boolean(true),
475
476
  enabled: boolean(true),
476
477
  entries: validate(['*'], (input, keypath) => {
@@ -617,6 +618,19 @@ function string(fallback, allow_empty = true) {
617
618
  });
618
619
  }
619
620
 
621
+ /**
622
+ * @param {number} fallback
623
+ * @returns {Validator}
624
+ */
625
+ function number(fallback) {
626
+ return validate(fallback, (input, keypath) => {
627
+ if (typeof input !== 'number') {
628
+ throw new Error(`${keypath} should be a number, if specified`);
629
+ }
630
+ return input;
631
+ });
632
+ }
633
+
620
634
  /**
621
635
  * @param {boolean} fallback
622
636
  * @returns {Validator}
@@ -822,7 +836,7 @@ async function launch(port, https) {
822
836
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
823
837
  }
824
838
 
825
- const prog = sade('svelte-kit').version('1.0.0-next.202');
839
+ const prog = sade('svelte-kit').version('1.0.0-next.206');
826
840
 
827
841
  prog
828
842
  .command('dev')
@@ -987,7 +1001,7 @@ async function check_port(port) {
987
1001
  function welcome({ port, host, https, open, loose, allow, cwd }) {
988
1002
  if (open) launch(port, https);
989
1003
 
990
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.202'}\n`));
1004
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.206'}\n`));
991
1005
 
992
1006
  const protocol = https ? 'https:' : 'http:';
993
1007
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
package/dist/ssr.js CHANGED
@@ -627,10 +627,8 @@ async function render_response({
627
627
  </script>`;
628
628
  }
629
629
 
630
- if (options.service_worker) {
631
- init += options.amp
632
- ? `<amp-install-serviceworker src="${options.service_worker}" layout="nodisplay"></amp-install-serviceworker>`
633
- : `<script>
630
+ if (options.service_worker && !options.amp) {
631
+ init += `<script>
634
632
  if ('serviceWorker' in navigator) {
635
633
  navigator.serviceWorker.register('${options.service_worker}');
636
634
  }
@@ -646,21 +644,23 @@ async function render_response({
646
644
  init
647
645
  ].join('\n\n\t\t');
648
646
 
649
- const body = options.amp
650
- ? rendered.html
651
- : `${rendered.html}
652
-
653
- ${serialized_data
654
- .map(({ url, body, json }) => {
655
- let attributes = `type="application/json" data-type="svelte-data" data-url=${escape_html_attr(
656
- url
657
- )}`;
658
- if (body) attributes += ` data-body="${hash(body)}"`;
659
-
660
- return `<script ${attributes}>${json}</script>`;
661
- })
662
- .join('\n\n\t')}
663
- `;
647
+ let body = rendered.html;
648
+ if (options.amp) {
649
+ if (options.service_worker) {
650
+ body += `<amp-install-serviceworker src="${options.service_worker}" layout="nodisplay"></amp-install-serviceworker>`;
651
+ }
652
+ } else {
653
+ body += serialized_data
654
+ .map(({ url, body, json }) => {
655
+ let attributes = `type="application/json" data-type="svelte-data" data-url=${escape_html_attr(
656
+ url
657
+ )}`;
658
+ if (body) attributes += ` data-body="${hash(body)}"`;
659
+
660
+ return `<script ${attributes}>${json}</script>`;
661
+ })
662
+ .join('\n\n\t');
663
+ }
664
664
 
665
665
  /** @type {import('types/helper').ResponseHeaders} */
666
666
  const headers = {
@@ -875,6 +875,8 @@ async function load_node({
875
875
  };
876
876
  }
877
877
 
878
+ opts.headers = new Headers(opts.headers);
879
+
878
880
  const resolved = resolve(request.path, url.split('?')[0]);
879
881
 
880
882
  let response;
@@ -903,18 +905,16 @@ async function load_node({
903
905
  } else if (is_root_relative(resolved)) {
904
906
  const relative = resolved;
905
907
 
906
- const headers = /** @type {import('types/helper').RequestHeaders} */ ({
907
- ...opts.headers
908
- });
909
-
910
908
  // TODO: fix type https://github.com/node-fetch/node-fetch/issues/1113
911
909
  if (opts.credentials !== 'omit') {
912
910
  uses_credentials = true;
913
911
 
914
- headers.cookie = request.headers.cookie;
912
+ if (request.headers.cookie) {
913
+ opts.headers.set('cookie', request.headers.cookie);
914
+ }
915
915
 
916
- if (!headers.authorization) {
917
- headers.authorization = request.headers.authorization;
916
+ if (request.headers.authorization && !opts.headers.has('authorization')) {
917
+ opts.headers.set('authorization', request.headers.authorization);
918
918
  }
919
919
  }
920
920
 
@@ -932,7 +932,7 @@ async function load_node({
932
932
  {
933
933
  host: request.host,
934
934
  method: opts.method || 'GET',
935
- headers,
935
+ headers: Object.fromEntries(opts.headers),
936
936
  path: relative,
937
937
  rawBody: opts.body == null ? null : new TextEncoder().encode(opts.body),
938
938
  query: new URLSearchParams(search)
@@ -981,11 +981,7 @@ async function load_node({
981
981
  opts.credentials !== 'omit'
982
982
  ) {
983
983
  uses_credentials = true;
984
-
985
- opts.headers = {
986
- ...opts.headers,
987
- cookie: request.headers.cookie
988
- };
984
+ opts.headers.set('cookie', request.headers.cookie);
989
985
  }
990
986
  }
991
987
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.202",
3
+ "version": "1.0.0-next.206",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -10,7 +10,7 @@
10
10
  "homepage": "https://kit.svelte.dev",
11
11
  "type": "module",
12
12
  "dependencies": {
13
- "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
13
+ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.32",
14
14
  "cheap-watch": "^1.0.4",
15
15
  "sade": "^1.7.4",
16
16
  "vite": "^2.7.2"
@@ -87,5 +87,6 @@
87
87
  "test:unit": "uvu src \"(spec\\.js|test[\\\\/]index\\.js)\" -i packaging",
88
88
  "test:packaging": "uvu src/packaging \"(spec\\.js|test[\\\\/]index\\.js)\"",
89
89
  "test:integration": "uvu test test.js"
90
- }
90
+ },
91
+ "readme": "# The fastest way to build Svelte apps\n\nThis is the [SvelteKit](https://kit.svelte.dev) framework and CLI.\n\nThe quickest way to get started is via the [create-svelte](https://github.com/sveltejs/kit/tree/master/packages/create-svelte) package:\n\n```bash\nnpm init svelte@next my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\nSee the [documentation](https://kit.svelte.dev/docs) to learn more.\n\n## Changelog\n\n[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/master/packages/kit/CHANGELOG.md).\n"
91
92
  }
package/types/config.d.ts CHANGED
@@ -76,6 +76,7 @@ export interface Config {
76
76
  base?: string;
77
77
  };
78
78
  prerender?: {
79
+ concurrency?: number;
79
80
  crawl?: boolean;
80
81
  enabled?: boolean;
81
82
  entries?: string[];