@sveltejs/kit 1.0.0-next.218 → 1.0.0-next.221

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
@@ -112,13 +112,14 @@ async function render_endpoint(request, route, match) {
112
112
  const response = await handler(request);
113
113
  const preface = `Invalid response from route ${request.url.pathname}`;
114
114
 
115
- if (!response) {
116
- return;
117
- }
118
115
  if (typeof response !== 'object') {
119
116
  return error(`${preface}: expected an object, got ${typeof response}`);
120
117
  }
121
118
 
119
+ if (response.fallthrough) {
120
+ return;
121
+ }
122
+
122
123
  let { status = 200, body, headers = {} } = response;
123
124
 
124
125
  headers = lowercase_keys(headers);
@@ -548,6 +549,7 @@ const s = JSON.stringify;
548
549
  * error?: Error,
549
550
  * url: URL;
550
551
  * params: Record<string, string>
552
+ * stuff: Record<string, any>;
551
553
  * }} opts
552
554
  */
553
555
  async function render_response({
@@ -558,7 +560,8 @@ async function render_response({
558
560
  status,
559
561
  error,
560
562
  url,
561
- params
563
+ params,
564
+ stuff
562
565
  }) {
563
566
  const css = new Set(options.manifest._.entry.css);
564
567
  const js = new Set(options.manifest._.entry.js);
@@ -599,7 +602,7 @@ async function render_response({
599
602
  navigating: writable(null),
600
603
  session
601
604
  },
602
- page: { url, params, status, error },
605
+ page: { url, params, status, error, stuff },
603
606
  components: branch.map(({ node }) => node.module.default)
604
607
  };
605
608
 
@@ -904,7 +907,6 @@ function is_root_relative(path) {
904
907
  * $session: any;
905
908
  * stuff: Record<string, any>;
906
909
  * prerender_enabled: boolean;
907
- * is_leaf: boolean;
908
910
  * is_error: boolean;
909
911
  * status?: number;
910
912
  * error?: Error;
@@ -922,7 +924,6 @@ async function load_node({
922
924
  $session,
923
925
  stuff,
924
926
  prerender_enabled,
925
- is_leaf,
926
927
  is_error,
927
928
  status,
928
929
  error
@@ -1182,16 +1183,16 @@ async function load_node({
1182
1183
  }
1183
1184
 
1184
1185
  loaded = await module.load.call(null, load_input);
1186
+
1187
+ if (!loaded) {
1188
+ throw new Error(`load function must return a value${options.dev ? ` (${node.entry})` : ''}`);
1189
+ }
1185
1190
  } else {
1186
1191
  loaded = {};
1187
1192
  }
1188
1193
 
1189
- // if leaf node (i.e. page component) has a load function
1190
- // that returns nothing, we fall through to the next one
1191
- if (!loaded && is_leaf && !is_error) return;
1192
-
1193
- if (!loaded) {
1194
- throw new Error(`${node.entry} - load must return a value except for page fall through`);
1194
+ if (loaded.fallthrough && !is_error) {
1195
+ return;
1195
1196
  }
1196
1197
 
1197
1198
  return {
@@ -1222,33 +1223,30 @@ async function load_node({
1222
1223
  * }} opts
1223
1224
  */
1224
1225
  async function respond_with_error({ request, options, state, $session, status, error }) {
1225
- const default_layout = await options.manifest._.nodes[0](); // 0 is always the root layout
1226
- const default_error = await options.manifest._.nodes[1](); // 1 is always the root error
1226
+ try {
1227
+ const default_layout = await options.manifest._.nodes[0](); // 0 is always the root layout
1228
+ const default_error = await options.manifest._.nodes[1](); // 1 is always the root error
1227
1229
 
1228
- /** @type {Record<string, string>} */
1229
- const params = {}; // error page has no params
1230
+ /** @type {Record<string, string>} */
1231
+ const params = {}; // error page has no params
1230
1232
 
1231
- // error pages don't fall through, so we know it's not undefined
1232
- const loaded = /** @type {Loaded} */ (
1233
- await load_node({
1234
- request,
1235
- options,
1236
- state,
1237
- route: null,
1238
- url: request.url, // TODO this is redundant, no?
1239
- params,
1240
- node: default_layout,
1241
- $session,
1242
- stuff: {},
1243
- prerender_enabled: is_prerender_enabled(options, default_error, state),
1244
- is_leaf: false,
1245
- is_error: false
1246
- })
1247
- );
1233
+ const layout_loaded = /** @type {Loaded} */ (
1234
+ await load_node({
1235
+ request,
1236
+ options,
1237
+ state,
1238
+ route: null,
1239
+ url: request.url, // TODO this is redundant, no?
1240
+ params,
1241
+ node: default_layout,
1242
+ $session,
1243
+ stuff: {},
1244
+ prerender_enabled: is_prerender_enabled(options, default_error, state),
1245
+ is_error: false
1246
+ })
1247
+ );
1248
1248
 
1249
- const branch = [
1250
- loaded,
1251
- /** @type {Loaded} */ (
1249
+ const error_loaded = /** @type {Loaded} */ (
1252
1250
  await load_node({
1253
1251
  request,
1254
1252
  options,
@@ -1258,17 +1256,14 @@ async function respond_with_error({ request, options, state, $session, status, e
1258
1256
  params,
1259
1257
  node: default_error,
1260
1258
  $session,
1261
- stuff: loaded ? loaded.stuff : {},
1259
+ stuff: layout_loaded ? layout_loaded.stuff : {},
1262
1260
  prerender_enabled: is_prerender_enabled(options, default_error, state),
1263
- is_leaf: false,
1264
1261
  is_error: true,
1265
1262
  status,
1266
1263
  error
1267
1264
  })
1268
- )
1269
- ];
1265
+ );
1270
1266
 
1271
- try {
1272
1267
  return await render_response({
1273
1268
  options,
1274
1269
  $session,
@@ -1277,9 +1272,10 @@ async function respond_with_error({ request, options, state, $session, status, e
1277
1272
  router: options.router,
1278
1273
  ssr: options.ssr
1279
1274
  },
1275
+ stuff: error_loaded.stuff,
1280
1276
  status,
1281
1277
  error,
1282
- branch,
1278
+ branch: [layout_loaded, error_loaded],
1283
1279
  url: request.url,
1284
1280
  params
1285
1281
  });
@@ -1377,9 +1373,9 @@ async function respond$1(opts) {
1377
1373
  /** @type {string[]} */
1378
1374
  let set_cookie_headers = [];
1379
1375
 
1380
- ssr: if (page_config.ssr) {
1381
- let stuff = {};
1376
+ let stuff = {};
1382
1377
 
1378
+ ssr: if (page_config.ssr) {
1383
1379
  for (let i = 0; i < nodes.length; i += 1) {
1384
1380
  const node = nodes[i];
1385
1381
 
@@ -1394,7 +1390,6 @@ async function respond$1(opts) {
1394
1390
  node,
1395
1391
  stuff,
1396
1392
  prerender_enabled: is_prerender_enabled(options, node, state),
1397
- is_leaf: i === nodes.length - 1,
1398
1393
  is_error: false
1399
1394
  });
1400
1395
 
@@ -1451,7 +1446,6 @@ async function respond$1(opts) {
1451
1446
  node: error_node,
1452
1447
  stuff: node_loaded.stuff,
1453
1448
  prerender_enabled: is_prerender_enabled(options, error_node, state),
1454
- is_leaf: false,
1455
1449
  is_error: true,
1456
1450
  status,
1457
1451
  error
@@ -1464,6 +1458,7 @@ async function respond$1(opts) {
1464
1458
 
1465
1459
  page_config = get_page_config(error_node.module, options);
1466
1460
  branch = branch.slice(0, j + 1).concat(error_loaded);
1461
+ stuff = { ...node_loaded.stuff, ...error_loaded.stuff };
1467
1462
  break ssr;
1468
1463
  } catch (err) {
1469
1464
  const e = coalesce_to_error(err);
@@ -1505,6 +1500,7 @@ async function respond$1(opts) {
1505
1500
  return with_cookies(
1506
1501
  await render_response({
1507
1502
  ...opts,
1503
+ stuff,
1508
1504
  url: request.url,
1509
1505
  page_config,
1510
1506
  status,
@@ -1845,6 +1841,7 @@ async function respond(incoming, options, state = {}) {
1845
1841
  params: request.params,
1846
1842
  options,
1847
1843
  $session: await options.hooks.getSession(request),
1844
+ stuff: {},
1848
1845
  page_config: { ssr: false, router: true, hydrate: true },
1849
1846
  status: 200,
1850
1847
  branch: []
@@ -1905,16 +1902,30 @@ async function respond(incoming, options, state = {}) {
1905
1902
  }
1906
1903
  }
1907
1904
  });
1908
- } catch (/** @type {unknown} */ err) {
1909
- const e = coalesce_to_error(err);
1905
+ } catch (/** @type {unknown} */ e) {
1906
+ const error = coalesce_to_error(e);
1910
1907
 
1911
- options.handle_error(e, request);
1908
+ options.handle_error(error, request);
1912
1909
 
1913
- return {
1914
- status: 500,
1915
- headers: {},
1916
- body: options.dev ? e.stack : e.message
1917
- };
1910
+ try {
1911
+ const $session = await options.hooks.getSession(request);
1912
+ return await respond_with_error({
1913
+ request,
1914
+ options,
1915
+ state,
1916
+ $session,
1917
+ status: 500,
1918
+ error
1919
+ });
1920
+ } catch (/** @type {unknown} */ e) {
1921
+ const error = coalesce_to_error(e);
1922
+
1923
+ return {
1924
+ status: 500,
1925
+ headers: {},
1926
+ body: options.dev ? error.stack : error.message
1927
+ };
1928
+ }
1918
1929
  }
1919
1930
  }
1920
1931
 
@@ -168,6 +168,10 @@ class Router {
168
168
  // Call `pushState` to add url to history so going back works.
169
169
  // Also make a delay, otherwise the browser default behaviour would not kick in
170
170
  setTimeout(() => history.pushState({}, '', url.href));
171
+ const info = this.parse(url);
172
+ if (info) {
173
+ return this.renderer.update(info, [], false);
174
+ }
171
175
  return;
172
176
  }
173
177
 
@@ -543,6 +547,9 @@ class Renderer {
543
547
 
544
548
  let error_args;
545
549
 
550
+ // url.hash is empty when coming from the server
551
+ url.hash = window.location.hash;
552
+
546
553
  try {
547
554
  for (let i = 0; i < nodes.length; i += 1) {
548
555
  const is_leaf = i === nodes.length - 1;
@@ -577,7 +584,14 @@ class Renderer {
577
584
 
578
585
  result = error_args
579
586
  ? await this._load_error(error_args)
580
- : await this._get_navigation_result_from_branch({ url, params, branch, status, error });
587
+ : await this._get_navigation_result_from_branch({
588
+ url,
589
+ params,
590
+ stuff,
591
+ branch,
592
+ status,
593
+ error
594
+ });
581
595
  } catch (e) {
582
596
  if (error) throw e;
583
597
 
@@ -801,12 +815,13 @@ class Renderer {
801
815
  * @param {{
802
816
  * url: URL;
803
817
  * params: Record<string, string>;
818
+ * stuff: Record<string, any>;
804
819
  * branch: Array<import('./types').BranchNode | undefined>;
805
820
  * status: number;
806
821
  * error?: Error;
807
822
  * }} opts
808
823
  */
809
- async _get_navigation_result_from_branch({ url, params, branch, status, error }) {
824
+ async _get_navigation_result_from_branch({ url, params, stuff, branch, status, error }) {
810
825
  const filtered = /** @type {import('./types').BranchNode[] } */ (branch.filter(Boolean));
811
826
  const redirect = filtered.find((f) => f.loaded && f.loaded.redirect);
812
827
 
@@ -830,7 +845,7 @@ class Renderer {
830
845
  }
831
846
 
832
847
  if (!this.current.url || url.href !== this.current.url.href) {
833
- result.props.page = { url, params, status, error };
848
+ result.props.page = { url, params, status, error, stuff };
834
849
 
835
850
  // TODO remove this for 1.0
836
851
  /**
@@ -963,8 +978,9 @@ class Renderer {
963
978
 
964
979
  const loaded = await module.load.call(null, load_input);
965
980
 
966
- // if the page component returns nothing from load, fall through
967
- if (!loaded) return;
981
+ if (!loaded) {
982
+ throw new Error('load function must return a value');
983
+ }
968
984
 
969
985
  node.loaded = normalize(loaded);
970
986
  if (node.loaded.stuff) node.stuff = node.loaded.stuff;
@@ -1041,9 +1057,10 @@ class Renderer {
1041
1057
  stuff
1042
1058
  });
1043
1059
 
1044
- const is_leaf = i === a.length - 1;
1045
-
1046
1060
  if (node && node.loaded) {
1061
+ if (node.loaded.fallthrough) {
1062
+ return;
1063
+ }
1047
1064
  if (node.loaded.error) {
1048
1065
  status = node.loaded.status;
1049
1066
  error = node.loaded.error;
@@ -1060,10 +1077,6 @@ class Renderer {
1060
1077
  if (node.loaded.stuff) {
1061
1078
  stuff_changed = true;
1062
1079
  }
1063
- } else if (is_leaf && module.load) {
1064
- // if the leaf node has a `load` function
1065
- // that returns nothing, fall through
1066
- return;
1067
1080
  }
1068
1081
  } else {
1069
1082
  node = previous;
@@ -1099,6 +1112,13 @@ class Renderer {
1099
1112
  continue;
1100
1113
  }
1101
1114
 
1115
+ if (error_loaded && error_loaded.loaded && error_loaded.loaded.stuff) {
1116
+ stuff = {
1117
+ ...stuff,
1118
+ ...error_loaded.loaded.stuff
1119
+ };
1120
+ }
1121
+
1102
1122
  branch = branch.slice(0, j + 1).concat(error_loaded);
1103
1123
  break load;
1104
1124
  } catch (e) {
@@ -1124,7 +1144,14 @@ class Renderer {
1124
1144
  }
1125
1145
  }
1126
1146
 
1127
- return await this._get_navigation_result_from_branch({ url, params, branch, status, error });
1147
+ return await this._get_navigation_result_from_branch({
1148
+ url,
1149
+ params,
1150
+ stuff,
1151
+ branch,
1152
+ status,
1153
+ error
1154
+ });
1128
1155
  }
1129
1156
 
1130
1157
  /**
@@ -1144,20 +1171,26 @@ class Renderer {
1144
1171
  params,
1145
1172
  stuff: {}
1146
1173
  });
1174
+ const error_node = await this._load_node({
1175
+ status,
1176
+ error,
1177
+ module: await this.fallback[1],
1178
+ url,
1179
+ params,
1180
+ stuff: (node && node.loaded && node.loaded.stuff) || {}
1181
+ });
1147
1182
 
1148
- const branch = [
1149
- node,
1150
- await this._load_node({
1151
- status,
1152
- error,
1153
- module: await this.fallback[1],
1154
- url,
1155
- params,
1156
- stuff: (node && node.loaded && node.loaded.stuff) || {}
1157
- })
1158
- ];
1183
+ const branch = [node, error_node];
1184
+ const stuff = { ...node?.loaded?.stuff, ...error_node?.loaded?.stuff };
1159
1185
 
1160
- return await this._get_navigation_result_from_branch({ url, params, branch, status, error });
1186
+ return await this._get_navigation_result_from_branch({
1187
+ url,
1188
+ params,
1189
+ stuff,
1190
+ branch,
1191
+ status,
1192
+ error
1193
+ });
1161
1194
  }
1162
1195
  }
1163
1196