@sveltejs/kit 1.0.0-next.334 → 1.0.0-next.337

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.
@@ -432,6 +432,33 @@ function update_scroll_positions(index) {
432
432
  scroll_positions[index] = scroll_state();
433
433
  }
434
434
 
435
+ const fetch$1 = window.fetch;
436
+ let loading = 0;
437
+
438
+ if (import.meta.env.DEV) {
439
+ let can_inspect_stack_trace = false;
440
+
441
+ const check_stack_trace = async () => {
442
+ const stack = /** @type {string} */ (new Error().stack);
443
+ can_inspect_stack_trace = stack.includes('check_stack_trace');
444
+ };
445
+
446
+ check_stack_trace();
447
+
448
+ window.fetch = (input, init) => {
449
+ const url = input instanceof Request ? input.url : input.toString();
450
+ const stack = /** @type {string} */ (new Error().stack);
451
+
452
+ const heuristic = can_inspect_stack_trace ? stack.includes('load_node') : loading;
453
+ if (heuristic) {
454
+ console.warn(
455
+ `Loading ${url} using \`window.fetch\`. For best results, use the \`fetch\` that is passed to your \`load\` function: https://kit.svelte.dev/docs/loading#input-fetch`
456
+ );
457
+ }
458
+ return fetch$1(input, init);
459
+ };
460
+ }
461
+
435
462
  /**
436
463
  * @param {{
437
464
  * target: Element;
@@ -928,7 +955,7 @@ function create_client({ target, session, base, trailing_slash }) {
928
955
  const requested = typeof resource === 'string' ? resource : resource.url;
929
956
  add_dependency(requested);
930
957
 
931
- return started ? fetch(resource, info) : initial_fetch(resource, info);
958
+ return started ? fetch$1(resource, info) : initial_fetch(resource, info);
932
959
  },
933
960
  status: status ?? null,
934
961
  error: error ?? null
@@ -943,7 +970,18 @@ function create_client({ target, session, base, trailing_slash }) {
943
970
  });
944
971
  }
945
972
 
946
- const loaded = await module.load.call(null, load_input);
973
+ let loaded;
974
+
975
+ if (import.meta.env.DEV) {
976
+ try {
977
+ loading += 1;
978
+ loaded = await module.load.call(null, load_input);
979
+ } finally {
980
+ loading -= 1;
981
+ }
982
+ } else {
983
+ loaded = await module.load.call(null, load_input);
984
+ }
947
985
 
948
986
  if (!loaded) {
949
987
  throw new Error('load function must return a value');
@@ -1027,7 +1065,7 @@ function create_client({ target, session, base, trailing_slash }) {
1027
1065
  const is_shadow_page = has_shadow && i === a.length - 1;
1028
1066
 
1029
1067
  if (is_shadow_page) {
1030
- const res = await fetch(
1068
+ const res = await fetch$1(
1031
1069
  `${url.pathname}${url.pathname.endsWith('/') ? '' : '/'}__data.json${url.search}`,
1032
1070
  {
1033
1071
  headers: {
@@ -1242,7 +1242,7 @@ async function render_response({
1242
1242
  const init_app = `
1243
1243
  import { start } from ${s(options.prefix + options.manifest._.entry.file)};
1244
1244
  start({
1245
- target: document.querySelector('[data-hydrate="${target}"]').parentNode,
1245
+ target: document.querySelector('[data-sveltekit-hydrate="${target}"]').parentNode,
1246
1246
  paths: ${s(options.paths)},
1247
1247
  session: ${try_serialize($session, (error) => {
1248
1248
  throw new Error(`Failed to serialize session data: ${error.message}`);
@@ -1327,7 +1327,7 @@ async function render_response({
1327
1327
  .map((dep) => `\n\t<link rel="modulepreload" href="${options.prefix + dep}">`)
1328
1328
  .join('');
1329
1329
 
1330
- const attributes = ['type="module"', `data-hydrate="${target}"`];
1330
+ const attributes = ['type="module"', `data-sveltekit-hydrate="${target}"`];
1331
1331
 
1332
1332
  csp.add_script(init_app);
1333
1333
 
@@ -15,6 +15,7 @@ import { p as parse_route_id } from './misc.js';
15
15
  import 'sade';
16
16
  import 'child_process';
17
17
  import 'net';
18
+ import 'chokidar';
18
19
  import 'os';
19
20
  import 'querystring';
20
21
  import 'node:http';
@@ -193,6 +194,11 @@ async function create_plugin(config, cwd) {
193
194
  });
194
195
 
195
196
  return () => {
197
+ const serve_static_middleware = vite.middlewares.stack.find(
198
+ (middleware) =>
199
+ /** @type {function} */ (middleware.handle).name === 'viteServeStaticMiddleware'
200
+ );
201
+
196
202
  remove_html_middlewares(vite.middlewares);
197
203
 
198
204
  vite.middlewares.use(async (req, res) => {
@@ -358,10 +364,13 @@ async function create_plugin(config, cwd) {
358
364
  }
359
365
  );
360
366
 
361
- if (rendered) {
362
- setResponse(res, rendered);
367
+ if (rendered.status === 404) {
368
+ // @ts-expect-error
369
+ serve_static_middleware.handle(req, res, () => {
370
+ setResponse(res, rendered);
371
+ });
363
372
  } else {
364
- not_found(res);
373
+ setResponse(res, rendered);
365
374
  }
366
375
  } catch (e) {
367
376
  const error = coalesce_to_error(e);
@@ -388,7 +397,8 @@ function remove_html_middlewares(server) {
388
397
  const html_middlewares = [
389
398
  'viteIndexHtmlMiddleware',
390
399
  'vite404Middleware',
391
- 'viteSpaFallbackMiddleware'
400
+ 'viteSpaFallbackMiddleware',
401
+ 'viteServeStaticMiddleware'
392
402
  ];
393
403
  for (let i = server.stack.length - 1; i > 0; i--) {
394
404
  // @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged
@@ -403,34 +413,38 @@ function remove_html_middlewares(server) {
403
413
  * @param {import('vite').ModuleNode} node
404
414
  * @param {Set<import('vite').ModuleNode>} deps
405
415
  */
406
- function find_deps(vite, node, deps) {
416
+ async function find_deps(vite, node, deps) {
407
417
  // since `ssrTransformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
408
418
  // instead of using `await`, we resolve all branches in parallel.
409
419
  /** @type {Promise<void>[]} */
410
420
  const branches = [];
411
421
 
412
422
  /** @param {import('vite').ModuleNode} node */
413
- function add(node) {
423
+ async function add(node) {
414
424
  if (!deps.has(node)) {
415
425
  deps.add(node);
416
- branches.push(find_deps(vite, node, deps));
426
+ await find_deps(vite, node, deps);
417
427
  }
418
428
  }
419
429
 
420
430
  /** @param {string} url */
421
431
  async function add_by_url(url) {
422
- branches.push(vite.moduleGraph.getModuleByUrl(url).then((node) => node && add(node)));
432
+ const node = await vite.moduleGraph.getModuleByUrl(url);
433
+
434
+ if (node) {
435
+ await add(node);
436
+ }
423
437
  }
424
438
 
425
439
  if (node.ssrTransformResult) {
426
440
  if (node.ssrTransformResult.deps) {
427
- node.ssrTransformResult.deps.forEach(add_by_url);
441
+ node.ssrTransformResult.deps.forEach((url) => branches.push(add_by_url(url)));
428
442
  }
429
443
  } else {
430
- node.importedModules.forEach(add);
444
+ node.importedModules.forEach((node) => branches.push(add(node)));
431
445
  }
432
446
 
433
- return Promise.all(branches).then(() => {});
447
+ await Promise.all(branches);
434
448
  }
435
449
 
436
450
  /**
@@ -461,10 +475,13 @@ async function dev({ cwd, port, host, https, config }) {
461
475
  path__default.resolve(cwd, 'node_modules'),
462
476
  path__default.resolve(vite.searchForWorkspaceRoot(cwd), 'node_modules')
463
477
  ])
464
- ],
465
- port: 3000
478
+ ]
466
479
  },
467
- strictPort: true
480
+ port: 3000,
481
+ strictPort: true,
482
+ watch: {
483
+ ignored: [`${config.kit.outDir}/**`, `!${config.kit.outDir}/generated/**`]
484
+ }
468
485
  }
469
486
  },
470
487
  await config.kit.vite()
@@ -486,7 +503,7 @@ async function dev({ cwd, port, host, https, config }) {
486
503
  },
487
504
  plugins: [
488
505
  svelte({
489
- extensions: config.extensions,
506
+ ...config,
490
507
  // In AMP mode, we know that there are no conditional component imports. In that case, we
491
508
  // don't need to include CSS for components that are imported but unused, so we can just
492
509
  // include rendered CSS.
@@ -494,8 +511,10 @@ async function dev({ cwd, port, host, https, config }) {
494
511
  // has been enabled at the page level, so we don't do anything there.
495
512
  emitCss: !config.kit.amp,
496
513
  compilerOptions: {
514
+ ...config.compilerOptions,
497
515
  hydratable: !!config.kit.browser.hydrate
498
- }
516
+ },
517
+ configFile: false
499
518
  }),
500
519
  await create_plugin(config, cwd)
501
520
  ],
@@ -14,6 +14,7 @@ import './write_tsconfig.js';
14
14
  import 'sade';
15
15
  import 'child_process';
16
16
  import 'net';
17
+ import 'chokidar';
17
18
  import 'os';
18
19
  import 'node:http';
19
20
  import 'node:https';
@@ -284,7 +285,7 @@ async function build_client({
284
285
  },
285
286
  plugins: [
286
287
  svelte({
287
- extensions: config.extensions,
288
+ ...config,
288
289
  // In AMP mode, we know that there are no conditional component imports. In that case, we
289
290
  // don't need to include CSS for components that are imported but unused, so we can just
290
291
  // include rendered CSS.
@@ -292,8 +293,10 @@ async function build_client({
292
293
  // has been enabled at the page level, so we don't do anything there.
293
294
  emitCss: !config.kit.amp,
294
295
  compilerOptions: {
296
+ ...config.compilerOptions,
295
297
  hydratable: !!config.kit.browser.hydrate
296
- }
298
+ },
299
+ configFile: false
297
300
  })
298
301
  ],
299
302
  // prevent Vite copying the contents of `config.kit.files.assets`,
@@ -549,10 +552,12 @@ async function build_server(
549
552
  },
550
553
  plugins: [
551
554
  svelte({
552
- extensions: config.extensions,
555
+ ...config,
553
556
  compilerOptions: {
557
+ ...config.compilerOptions,
554
558
  hydratable: !!config.kit.browser.hydrate
555
- }
559
+ },
560
+ configFile: false
556
561
  })
557
562
  ],
558
563
  resolve: {
@@ -6,6 +6,7 @@ import 'fs';
6
6
  import 'path';
7
7
  import 'child_process';
8
8
  import 'net';
9
+ import 'chokidar';
9
10
  import 'url';
10
11
  import 'os';
11
12
  import './misc.js';
@@ -1,13 +1,14 @@
1
1
  import path__default from 'path';
2
2
  import fs__default from 'fs';
3
3
  import { g as get_runtime_path } from '../cli.js';
4
- import { p as posixify, c as copy } from './filesystem.js';
4
+ import { p as posixify, c as copy, r as rimraf } from './filesystem.js';
5
5
  import { p as parse_route_id, s } from './misc.js';
6
6
  import { fileURLToPath } from 'url';
7
7
  import { w as write_if_changed, t as trim, a as write_tsconfig } from './write_tsconfig.js';
8
8
  import 'sade';
9
9
  import 'child_process';
10
10
  import 'net';
11
+ import 'chokidar';
11
12
  import 'os';
12
13
 
13
14
  /**
@@ -763,6 +764,8 @@ export type Load<
763
764
  * @param {import('types').ManifestData} manifest_data
764
765
  */
765
766
  function write_types(config, manifest_data) {
767
+ rimraf(`${config.kit.outDir}/types`);
768
+
766
769
  /** @type {Map<string, { params: string[], type: 'page' | 'endpoint' | 'both' }>} */
767
770
  const shadow_types = new Map();
768
771
 
@@ -811,8 +814,11 @@ function write_types(config, manifest_data) {
811
814
 
812
815
  content.unshift(header(imports.join(', ')));
813
816
 
817
+ const parts = (key || 'index').split('/');
818
+ parts.push('__types', /** @type {string} */ (parts.pop()));
819
+
814
820
  write_if_changed(
815
- `${config.kit.outDir}/types/${key || 'index'}.d.ts`,
821
+ `${config.kit.outDir}/types/${parts.join('/')}.d.ts`,
816
822
  content.join('\n').trim()
817
823
  );
818
824
  });
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@ import fs__default from 'fs';
3
3
  import path__default, { join, relative } from 'path';
4
4
  import { exec as exec$1 } from 'child_process';
5
5
  import { createConnection, createServer } from 'net';
6
+ import chokidar from 'chokidar';
6
7
  import * as url from 'url';
7
8
  import { networkInterfaces, release } from 'os';
8
9
 
@@ -782,7 +783,7 @@ async function load_config({ cwd = process.cwd() } = {}) {
782
783
  );
783
784
  }
784
785
 
785
- const config = await import(url.pathToFileURL(config_file).href);
786
+ const config = await import(`${url.pathToFileURL(config_file).href}?ts=${Date.now()}`);
786
787
 
787
788
  const validated = validate_config(config.default);
788
789
 
@@ -870,7 +871,7 @@ async function launch(port, https, base) {
870
871
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}${base}`);
871
872
  }
872
873
 
873
- const prog = sade('svelte-kit').version('1.0.0-next.334');
874
+ const prog = sade('svelte-kit').version('1.0.0-next.337');
874
875
 
875
876
  prog
876
877
  .command('dev')
@@ -881,17 +882,20 @@ prog
881
882
  .option('--https', 'Use self-signed HTTPS certificate')
882
883
  .option('-H', 'no longer supported, use --https instead') // TODO remove for 1.0
883
884
  .action(async ({ port, host, https, open, H }) => {
884
- try {
885
- if (H) throw new Error('-H is no longer supported — use --https instead');
885
+ let first = true;
886
+ let relaunching = false;
887
+ let uid = 1;
886
888
 
887
- process.env.NODE_ENV = process.env.NODE_ENV || 'development';
888
- const config = await load_config();
889
+ /** @type {() => Promise<void>} */
890
+ let close;
889
891
 
892
+ /** @param {import('types').ValidatedConfig} config */
893
+ async function start(config) {
890
894
  const { dev } = await import('./chunks/index.js');
891
895
 
892
896
  const cwd = process.cwd();
893
897
 
894
- const { address_info, server_config } = await dev({
898
+ const { address_info, server_config, close } = await dev({
895
899
  cwd,
896
900
  port,
897
901
  host,
@@ -903,12 +907,52 @@ prog
903
907
  port: address_info.port,
904
908
  host: address_info.address,
905
909
  https: !!(https || server_config.https),
906
- open: open || !!server_config.open,
910
+ open: first && (open || !!server_config.open),
907
911
  base: config.kit.paths.base,
908
912
  loose: server_config.fs.strict === false,
909
913
  allow: server_config.fs.allow,
910
914
  cwd
911
915
  });
916
+
917
+ first = false;
918
+
919
+ return close;
920
+ }
921
+
922
+ async function relaunch() {
923
+ const id = uid;
924
+ relaunching = true;
925
+
926
+ try {
927
+ const updated_config = await load_config();
928
+ await close();
929
+ close = await start(updated_config);
930
+
931
+ if (id !== uid) relaunch();
932
+ } catch (e) {
933
+ const error = /** @type {Error} */ (e);
934
+
935
+ console.error($.bold().red(`> ${error.message}`));
936
+ if (error.stack) {
937
+ console.error($.gray(error.stack.split('\n').slice(1).join('\n')));
938
+ }
939
+ }
940
+
941
+ relaunching = false;
942
+ }
943
+
944
+ try {
945
+ if (H) throw new Error('-H is no longer supported — use --https instead');
946
+
947
+ process.env.NODE_ENV = process.env.NODE_ENV || 'development';
948
+
949
+ const config = await load_config();
950
+ close = await start(config);
951
+
952
+ chokidar.watch('svelte.config.js', { ignoreInitial: true }).on('change', () => {
953
+ if (relaunching) uid += 1;
954
+ else relaunch();
955
+ });
912
956
  } catch (error) {
913
957
  handle_error(error);
914
958
  }
@@ -1049,7 +1093,7 @@ async function check_port(port) {
1049
1093
  function welcome({ port, host, https, open, base, loose, allow, cwd }) {
1050
1094
  if (open) launch(port, https, base);
1051
1095
 
1052
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.334'}\n`));
1096
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.337'}\n`));
1053
1097
 
1054
1098
  const protocol = https ? 'https:' : 'http:';
1055
1099
  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.334",
3
+ "version": "1.0.0-next.337",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -10,10 +10,10 @@
10
10
  "homepage": "https://kit.svelte.dev",
11
11
  "type": "module",
12
12
  "dependencies": {
13
- "@sveltejs/vite-plugin-svelte": "^1.0.0-next.32",
13
+ "@sveltejs/vite-plugin-svelte": "^1.0.0-next.44",
14
14
  "chokidar": "^3.5.3",
15
15
  "sade": "^1.7.4",
16
- "vite": "^2.9.0"
16
+ "vite": "^2.9.9"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@playwright/test": "^1.21.0",
@@ -46,6 +46,7 @@
46
46
  "svelte-preprocess": "^4.9.8",
47
47
  "svelte2tsx": "~0.5.0",
48
48
  "tiny-glob": "^0.2.9",
49
+ "typescript": "^4.6.4",
49
50
  "uvu": "^0.5.2"
50
51
  },
51
52
  "peerDependencies": {
@@ -15,7 +15,15 @@
15
15
  * }
16
16
  * ```
17
17
  *
18
- * By populating these interfaces, you will gain type safety when using `event.locals`, `event.platform`, `session` and `stuff`:
18
+ * By populating these interfaces, you will gain type safety when using `event.locals`, `event.platform`, `session` and `stuff`.
19
+ *
20
+ * Note that since it's an ambient declaration file, you can't use `import` statements — instead, use the `import(...)` function:
21
+ *
22
+ * ```ts
23
+ * interface Locals {
24
+ * user: import('$lib/types').User;
25
+ * }
26
+ * ```
19
27
  */
20
28
  declare namespace App {
21
29
  /**
package/types/index.d.ts CHANGED
@@ -13,9 +13,7 @@ import {
13
13
  MaybePromise,
14
14
  Prerendered,
15
15
  PrerenderOnErrorValue,
16
- RequestEvent,
17
16
  RequestOptions,
18
- ResolveOptions,
19
17
  ResponseHeaders,
20
18
  RouteDefinition,
21
19
  TrailingSlash
@@ -235,6 +233,16 @@ export interface ParamMatcher {
235
233
  (param: string): boolean;
236
234
  }
237
235
 
236
+ export interface RequestEvent<Params extends Record<string, string> = Record<string, string>> {
237
+ clientAddress: string;
238
+ locals: App.Locals;
239
+ params: Params;
240
+ platform: Readonly<App.Platform>;
241
+ request: Request;
242
+ routeId: string | null;
243
+ url: URL;
244
+ }
245
+
238
246
  /**
239
247
  * A `(event: RequestEvent) => RequestHandlerOutput` function exported from an endpoint that corresponds to an HTTP verb (`get`, `put`, `patch`, etc) and handles requests with that method. Note that since 'delete' is a reserved word in JavaScript, delete handles are called `del` instead.
240
248
  *
@@ -253,6 +261,11 @@ export interface RequestHandlerOutput<Output = ResponseBody> {
253
261
  body?: Output extends ResponseBody ? Output : BodyValidator<Output>;
254
262
  }
255
263
 
264
+ export interface ResolveOptions {
265
+ ssr?: boolean;
266
+ transformPage?: ({ html }: { html: string }) => MaybePromise<string>;
267
+ }
268
+
256
269
  export type ResponseBody = JSONValue | Uint8Array | ReadableStream | import('stream').Readable;
257
270
 
258
271
  export class Server {
@@ -6,7 +6,9 @@ import {
6
6
  Handle,
7
7
  HandleError,
8
8
  Load,
9
+ RequestEvent,
9
10
  RequestHandler,
11
+ ResolveOptions,
10
12
  Server,
11
13
  SSRManifest
12
14
  } from './index';
@@ -14,9 +16,7 @@ import {
14
16
  HttpMethod,
15
17
  JSONObject,
16
18
  MaybePromise,
17
- RequestEvent,
18
19
  RequestOptions,
19
- ResolveOptions,
20
20
  ResponseHeaders,
21
21
  TrailingSlash
22
22
  } from './private';
@@ -206,26 +206,11 @@ export interface PrerenderErrorHandler {
206
206
 
207
207
  export type PrerenderOnErrorValue = 'fail' | 'continue' | PrerenderErrorHandler;
208
208
 
209
- export interface RequestEvent<Params extends Record<string, string> = Record<string, string>> {
210
- clientAddress: string;
211
- locals: App.Locals;
212
- params: Params;
213
- platform: Readonly<App.Platform>;
214
- request: Request;
215
- routeId: string | null;
216
- url: URL;
217
- }
218
-
219
209
  export interface RequestOptions {
220
210
  getClientAddress: () => string;
221
211
  platform?: App.Platform;
222
212
  }
223
213
 
224
- export interface ResolveOptions {
225
- ssr?: boolean;
226
- transformPage?: ({ html }: { html: string }) => MaybePromise<string>;
227
- }
228
-
229
214
  /** `string[]` is only for set-cookie, everything else must be type of `string` */
230
215
  export type ResponseHeaders = Record<string, string | number | string[]>;
231
216