@sveltejs/kit 1.0.0-next.219 → 1.0.0-next.222
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 +104 -65
- package/assets/runtime/app/stores.js +4 -6
- package/assets/runtime/internal/start.js +57 -24
- package/dist/chunks/index.js +33 -4206
- package/dist/chunks/index2.js +31 -29
- package/dist/chunks/index3.js +0 -1
- package/dist/chunks/index5.js +6 -1
- package/dist/chunks/index6.js +6 -6
- package/dist/chunks/index8.js +4207 -0
- package/dist/cli.js +10 -3
- package/dist/ssr.js +104 -65
- package/package.json +1 -1
- package/types/ambient-modules.d.ts +1 -0
- package/types/config.d.ts +0 -1
- package/types/endpoint.d.ts +4 -2
- package/types/helper.d.ts +12 -0
- package/types/hooks.d.ts +9 -2
- package/types/index.d.ts +2 -1
- package/types/internal.d.ts +12 -11
- package/types/page.d.ts +7 -5
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);
|
|
@@ -543,11 +544,13 @@ const s = JSON.stringify;
|
|
|
543
544
|
* branch: Array<import('./types').Loaded>;
|
|
544
545
|
* options: import('types/internal').SSRRenderOptions;
|
|
545
546
|
* $session: any;
|
|
546
|
-
* page_config: { hydrate: boolean, router: boolean
|
|
547
|
+
* page_config: { hydrate: boolean, router: boolean };
|
|
547
548
|
* status: number;
|
|
548
|
-
* error?: Error
|
|
549
|
+
* error?: Error;
|
|
549
550
|
* url: URL;
|
|
550
|
-
* params: Record<string, string
|
|
551
|
+
* params: Record<string, string>;
|
|
552
|
+
* ssr: boolean;
|
|
553
|
+
* stuff: Record<string, any>;
|
|
551
554
|
* }} opts
|
|
552
555
|
*/
|
|
553
556
|
async function render_response({
|
|
@@ -558,7 +561,9 @@ async function render_response({
|
|
|
558
561
|
status,
|
|
559
562
|
error,
|
|
560
563
|
url,
|
|
561
|
-
params
|
|
564
|
+
params,
|
|
565
|
+
ssr,
|
|
566
|
+
stuff
|
|
562
567
|
}) {
|
|
563
568
|
const css = new Set(options.manifest._.entry.css);
|
|
564
569
|
const js = new Set(options.manifest._.entry.js);
|
|
@@ -576,7 +581,7 @@ async function render_response({
|
|
|
576
581
|
error.stack = options.get_stack(error);
|
|
577
582
|
}
|
|
578
583
|
|
|
579
|
-
if (
|
|
584
|
+
if (ssr) {
|
|
580
585
|
branch.forEach(({ node, loaded, fetched, uses_credentials }) => {
|
|
581
586
|
if (node.css) node.css.forEach((url) => css.add(url));
|
|
582
587
|
if (node.js) node.js.forEach((url) => js.add(url));
|
|
@@ -599,7 +604,7 @@ async function render_response({
|
|
|
599
604
|
navigating: writable(null),
|
|
600
605
|
session
|
|
601
606
|
},
|
|
602
|
-
page: { url, params, status, error },
|
|
607
|
+
page: { url, params, status, error, stuff },
|
|
603
608
|
components: branch.map(({ node }) => node.module.default)
|
|
604
609
|
};
|
|
605
610
|
|
|
@@ -679,9 +684,9 @@ async function render_response({
|
|
|
679
684
|
throw new Error(`Failed to serialize session data: ${error.message}`);
|
|
680
685
|
})},
|
|
681
686
|
route: ${!!page_config.router},
|
|
682
|
-
spa: ${!
|
|
687
|
+
spa: ${!ssr},
|
|
683
688
|
trailing_slash: ${s(options.trailing_slash)},
|
|
684
|
-
hydrate: ${
|
|
689
|
+
hydrate: ${ssr && page_config.hydrate ? `{
|
|
685
690
|
status: ${status},
|
|
686
691
|
error: ${serialize_error(error)},
|
|
687
692
|
nodes: [
|
|
@@ -904,7 +909,6 @@ function is_root_relative(path) {
|
|
|
904
909
|
* $session: any;
|
|
905
910
|
* stuff: Record<string, any>;
|
|
906
911
|
* prerender_enabled: boolean;
|
|
907
|
-
* is_leaf: boolean;
|
|
908
912
|
* is_error: boolean;
|
|
909
913
|
* status?: number;
|
|
910
914
|
* error?: Error;
|
|
@@ -922,7 +926,6 @@ async function load_node({
|
|
|
922
926
|
$session,
|
|
923
927
|
stuff,
|
|
924
928
|
prerender_enabled,
|
|
925
|
-
is_leaf,
|
|
926
929
|
is_error,
|
|
927
930
|
status,
|
|
928
931
|
error
|
|
@@ -1182,16 +1185,16 @@ async function load_node({
|
|
|
1182
1185
|
}
|
|
1183
1186
|
|
|
1184
1187
|
loaded = await module.load.call(null, load_input);
|
|
1188
|
+
|
|
1189
|
+
if (!loaded) {
|
|
1190
|
+
throw new Error(`load function must return a value${options.dev ? ` (${node.entry})` : ''}`);
|
|
1191
|
+
}
|
|
1185
1192
|
} else {
|
|
1186
1193
|
loaded = {};
|
|
1187
1194
|
}
|
|
1188
1195
|
|
|
1189
|
-
|
|
1190
|
-
|
|
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`);
|
|
1196
|
+
if (loaded.fallthrough && !is_error) {
|
|
1197
|
+
return;
|
|
1195
1198
|
}
|
|
1196
1199
|
|
|
1197
1200
|
return {
|
|
@@ -1219,9 +1222,18 @@ async function load_node({
|
|
|
1219
1222
|
* $session: any;
|
|
1220
1223
|
* status: number;
|
|
1221
1224
|
* error: Error;
|
|
1225
|
+
* ssr: boolean;
|
|
1222
1226
|
* }} opts
|
|
1223
1227
|
*/
|
|
1224
|
-
async function respond_with_error({
|
|
1228
|
+
async function respond_with_error({
|
|
1229
|
+
request,
|
|
1230
|
+
options,
|
|
1231
|
+
state,
|
|
1232
|
+
$session,
|
|
1233
|
+
status,
|
|
1234
|
+
error,
|
|
1235
|
+
ssr
|
|
1236
|
+
}) {
|
|
1225
1237
|
try {
|
|
1226
1238
|
const default_layout = await options.manifest._.nodes[0](); // 0 is always the root layout
|
|
1227
1239
|
const default_error = await options.manifest._.nodes[1](); // 1 is always the root error
|
|
@@ -1229,8 +1241,7 @@ async function respond_with_error({ request, options, state, $session, status, e
|
|
|
1229
1241
|
/** @type {Record<string, string>} */
|
|
1230
1242
|
const params = {}; // error page has no params
|
|
1231
1243
|
|
|
1232
|
-
|
|
1233
|
-
const loaded = /** @type {Loaded} */ (
|
|
1244
|
+
const layout_loaded = /** @type {Loaded} */ (
|
|
1234
1245
|
await load_node({
|
|
1235
1246
|
request,
|
|
1236
1247
|
options,
|
|
@@ -1242,46 +1253,42 @@ async function respond_with_error({ request, options, state, $session, status, e
|
|
|
1242
1253
|
$session,
|
|
1243
1254
|
stuff: {},
|
|
1244
1255
|
prerender_enabled: is_prerender_enabled(options, default_error, state),
|
|
1245
|
-
is_leaf: false,
|
|
1246
1256
|
is_error: false
|
|
1247
1257
|
})
|
|
1248
1258
|
);
|
|
1249
1259
|
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
error
|
|
1268
|
-
})
|
|
1269
|
-
)
|
|
1270
|
-
];
|
|
1260
|
+
const error_loaded = /** @type {Loaded} */ (
|
|
1261
|
+
await load_node({
|
|
1262
|
+
request,
|
|
1263
|
+
options,
|
|
1264
|
+
state,
|
|
1265
|
+
route: null,
|
|
1266
|
+
url: request.url,
|
|
1267
|
+
params,
|
|
1268
|
+
node: default_error,
|
|
1269
|
+
$session,
|
|
1270
|
+
stuff: layout_loaded ? layout_loaded.stuff : {},
|
|
1271
|
+
prerender_enabled: is_prerender_enabled(options, default_error, state),
|
|
1272
|
+
is_error: true,
|
|
1273
|
+
status,
|
|
1274
|
+
error
|
|
1275
|
+
})
|
|
1276
|
+
);
|
|
1271
1277
|
|
|
1272
1278
|
return await render_response({
|
|
1273
1279
|
options,
|
|
1274
1280
|
$session,
|
|
1275
1281
|
page_config: {
|
|
1276
1282
|
hydrate: options.hydrate,
|
|
1277
|
-
router: options.router
|
|
1278
|
-
ssr: options.ssr
|
|
1283
|
+
router: options.router
|
|
1279
1284
|
},
|
|
1285
|
+
stuff: error_loaded.stuff,
|
|
1280
1286
|
status,
|
|
1281
1287
|
error,
|
|
1282
|
-
branch,
|
|
1288
|
+
branch: [layout_loaded, error_loaded],
|
|
1283
1289
|
url: request.url,
|
|
1284
|
-
params
|
|
1290
|
+
params,
|
|
1291
|
+
ssr
|
|
1285
1292
|
});
|
|
1286
1293
|
} catch (err) {
|
|
1287
1294
|
const error = coalesce_to_error(err);
|
|
@@ -1323,15 +1330,30 @@ function is_prerender_enabled(options, node, state) {
|
|
|
1323
1330
|
* $session: any;
|
|
1324
1331
|
* route: import('types/internal').SSRPage;
|
|
1325
1332
|
* params: Record<string, string>;
|
|
1333
|
+
* ssr: boolean;
|
|
1326
1334
|
* }} opts
|
|
1327
1335
|
* @returns {Promise<ServerResponse | undefined>}
|
|
1328
1336
|
*/
|
|
1329
1337
|
async function respond$1(opts) {
|
|
1330
|
-
const { request, options, state, $session, route } = opts;
|
|
1338
|
+
const { request, options, state, $session, route, ssr } = opts;
|
|
1331
1339
|
|
|
1332
1340
|
/** @type {Array<SSRNode | undefined>} */
|
|
1333
1341
|
let nodes;
|
|
1334
1342
|
|
|
1343
|
+
if (!ssr) {
|
|
1344
|
+
return await render_response({
|
|
1345
|
+
...opts,
|
|
1346
|
+
branch: [],
|
|
1347
|
+
page_config: {
|
|
1348
|
+
hydrate: true,
|
|
1349
|
+
router: true
|
|
1350
|
+
},
|
|
1351
|
+
status: 200,
|
|
1352
|
+
url: request.url,
|
|
1353
|
+
stuff: {}
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1335
1357
|
try {
|
|
1336
1358
|
nodes = await Promise.all(
|
|
1337
1359
|
route.a.map((n) => options.manifest._.nodes[n] && options.manifest._.nodes[n]())
|
|
@@ -1347,7 +1369,8 @@ async function respond$1(opts) {
|
|
|
1347
1369
|
state,
|
|
1348
1370
|
$session,
|
|
1349
1371
|
status: 500,
|
|
1350
|
-
error
|
|
1372
|
+
error,
|
|
1373
|
+
ssr
|
|
1351
1374
|
});
|
|
1352
1375
|
}
|
|
1353
1376
|
|
|
@@ -1377,9 +1400,9 @@ async function respond$1(opts) {
|
|
|
1377
1400
|
/** @type {string[]} */
|
|
1378
1401
|
let set_cookie_headers = [];
|
|
1379
1402
|
|
|
1380
|
-
|
|
1381
|
-
let stuff = {};
|
|
1403
|
+
let stuff = {};
|
|
1382
1404
|
|
|
1405
|
+
ssr: if (ssr) {
|
|
1383
1406
|
for (let i = 0; i < nodes.length; i += 1) {
|
|
1384
1407
|
const node = nodes[i];
|
|
1385
1408
|
|
|
@@ -1394,7 +1417,6 @@ async function respond$1(opts) {
|
|
|
1394
1417
|
node,
|
|
1395
1418
|
stuff,
|
|
1396
1419
|
prerender_enabled: is_prerender_enabled(options, node, state),
|
|
1397
|
-
is_leaf: i === nodes.length - 1,
|
|
1398
1420
|
is_error: false
|
|
1399
1421
|
});
|
|
1400
1422
|
|
|
@@ -1443,7 +1465,6 @@ async function respond$1(opts) {
|
|
|
1443
1465
|
}
|
|
1444
1466
|
|
|
1445
1467
|
try {
|
|
1446
|
-
// there's no fallthough on an error page, so we know it's not undefined
|
|
1447
1468
|
const error_loaded = /** @type {import('./types').Loaded} */ (
|
|
1448
1469
|
await load_node({
|
|
1449
1470
|
...opts,
|
|
@@ -1451,7 +1472,6 @@ async function respond$1(opts) {
|
|
|
1451
1472
|
node: error_node,
|
|
1452
1473
|
stuff: node_loaded.stuff,
|
|
1453
1474
|
prerender_enabled: is_prerender_enabled(options, error_node, state),
|
|
1454
|
-
is_leaf: false,
|
|
1455
1475
|
is_error: true,
|
|
1456
1476
|
status,
|
|
1457
1477
|
error
|
|
@@ -1464,6 +1484,7 @@ async function respond$1(opts) {
|
|
|
1464
1484
|
|
|
1465
1485
|
page_config = get_page_config(error_node.module, options);
|
|
1466
1486
|
branch = branch.slice(0, j + 1).concat(error_loaded);
|
|
1487
|
+
stuff = { ...node_loaded.stuff, ...error_loaded.stuff };
|
|
1467
1488
|
break ssr;
|
|
1468
1489
|
} catch (err) {
|
|
1469
1490
|
const e = coalesce_to_error(err);
|
|
@@ -1485,7 +1506,8 @@ async function respond$1(opts) {
|
|
|
1485
1506
|
state,
|
|
1486
1507
|
$session,
|
|
1487
1508
|
status,
|
|
1488
|
-
error
|
|
1509
|
+
error,
|
|
1510
|
+
ssr
|
|
1489
1511
|
}),
|
|
1490
1512
|
set_cookie_headers
|
|
1491
1513
|
);
|
|
@@ -1505,6 +1527,7 @@ async function respond$1(opts) {
|
|
|
1505
1527
|
return with_cookies(
|
|
1506
1528
|
await render_response({
|
|
1507
1529
|
...opts,
|
|
1530
|
+
stuff,
|
|
1508
1531
|
url: request.url,
|
|
1509
1532
|
page_config,
|
|
1510
1533
|
status,
|
|
@@ -1534,8 +1557,14 @@ async function respond$1(opts) {
|
|
|
1534
1557
|
* @param {SSRRenderOptions} options
|
|
1535
1558
|
*/
|
|
1536
1559
|
function get_page_config(leaf, options) {
|
|
1560
|
+
// TODO remove for 1.0
|
|
1561
|
+
if ('ssr' in leaf) {
|
|
1562
|
+
throw new Error(
|
|
1563
|
+
'`export const ssr` has been removed — use the handle hook instead: https://kit.svelte.dev/docs#hooks-handle'
|
|
1564
|
+
);
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1537
1567
|
return {
|
|
1538
|
-
ssr: 'ssr' in leaf ? !!leaf.ssr : options.ssr,
|
|
1539
1568
|
router: 'router' in leaf ? !!leaf.router : options.router,
|
|
1540
1569
|
hydrate: 'hydrate' in leaf ? !!leaf.hydrate : options.hydrate
|
|
1541
1570
|
};
|
|
@@ -1558,9 +1587,10 @@ function with_cookies(response, set_cookie_headers) {
|
|
|
1558
1587
|
* @param {RegExpExecArray} match
|
|
1559
1588
|
* @param {import('types/internal').SSRRenderOptions} options
|
|
1560
1589
|
* @param {import('types/internal').SSRRenderState} state
|
|
1590
|
+
* @param {boolean} ssr
|
|
1561
1591
|
* @returns {Promise<import('types/hooks').ServerResponse | undefined>}
|
|
1562
1592
|
*/
|
|
1563
|
-
async function render_page(request, route, match, options, state) {
|
|
1593
|
+
async function render_page(request, route, match, options, state, ssr) {
|
|
1564
1594
|
if (state.initiator === route) {
|
|
1565
1595
|
// infinite request cycle detected
|
|
1566
1596
|
return {
|
|
@@ -1580,7 +1610,8 @@ async function render_page(request, route, match, options, state) {
|
|
|
1580
1610
|
state,
|
|
1581
1611
|
$session,
|
|
1582
1612
|
route,
|
|
1583
|
-
params
|
|
1613
|
+
params,
|
|
1614
|
+
ssr
|
|
1584
1615
|
});
|
|
1585
1616
|
|
|
1586
1617
|
if (response) {
|
|
@@ -1835,19 +1866,25 @@ async function respond(incoming, options, state = {}) {
|
|
|
1835
1866
|
print_error('path', 'pathname');
|
|
1836
1867
|
print_error('query', 'searchParams');
|
|
1837
1868
|
|
|
1869
|
+
let ssr = true;
|
|
1870
|
+
|
|
1838
1871
|
try {
|
|
1839
1872
|
return await options.hooks.handle({
|
|
1840
1873
|
request,
|
|
1841
|
-
resolve: async (request) => {
|
|
1874
|
+
resolve: async (request, opts) => {
|
|
1875
|
+
if (opts && 'ssr' in opts) ssr = /** @type {boolean} */ (opts.ssr);
|
|
1876
|
+
|
|
1842
1877
|
if (state.prerender && state.prerender.fallback) {
|
|
1843
1878
|
return await render_response({
|
|
1844
1879
|
url: request.url,
|
|
1845
1880
|
params: request.params,
|
|
1846
1881
|
options,
|
|
1847
1882
|
$session: await options.hooks.getSession(request),
|
|
1848
|
-
page_config: {
|
|
1883
|
+
page_config: { router: true, hydrate: true },
|
|
1884
|
+
stuff: {},
|
|
1849
1885
|
status: 200,
|
|
1850
|
-
branch: []
|
|
1886
|
+
branch: [],
|
|
1887
|
+
ssr: false
|
|
1851
1888
|
});
|
|
1852
1889
|
}
|
|
1853
1890
|
|
|
@@ -1860,7 +1897,7 @@ async function respond(incoming, options, state = {}) {
|
|
|
1860
1897
|
const response =
|
|
1861
1898
|
route.type === 'endpoint'
|
|
1862
1899
|
? await render_endpoint(request, route, match)
|
|
1863
|
-
: await render_page(request, route, match, options, state);
|
|
1900
|
+
: await render_page(request, route, match, options, state, ssr);
|
|
1864
1901
|
|
|
1865
1902
|
if (response) {
|
|
1866
1903
|
// inject ETags for 200 responses
|
|
@@ -1900,7 +1937,8 @@ async function respond(incoming, options, state = {}) {
|
|
|
1900
1937
|
state,
|
|
1901
1938
|
$session,
|
|
1902
1939
|
status: 404,
|
|
1903
|
-
error: new Error(`Not found: ${request.url.pathname}`)
|
|
1940
|
+
error: new Error(`Not found: ${request.url.pathname}`),
|
|
1941
|
+
ssr
|
|
1904
1942
|
});
|
|
1905
1943
|
}
|
|
1906
1944
|
}
|
|
@@ -1918,7 +1956,8 @@ async function respond(incoming, options, state = {}) {
|
|
|
1918
1956
|
state,
|
|
1919
1957
|
$session,
|
|
1920
1958
|
status: 500,
|
|
1921
|
-
error
|
|
1959
|
+
error,
|
|
1960
|
+
ssr
|
|
1922
1961
|
});
|
|
1923
1962
|
} catch (/** @type {unknown} */ e) {
|
|
1924
1963
|
const error = coalesce_to_error(e);
|
|
@@ -2,8 +2,6 @@ import { getContext } from 'svelte';
|
|
|
2
2
|
import { browser } from './env.js';
|
|
3
3
|
import '../env.js';
|
|
4
4
|
|
|
5
|
-
const ssr = !browser;
|
|
6
|
-
|
|
7
5
|
// TODO remove this (for 1.0? after 1.0?)
|
|
8
6
|
let warned = false;
|
|
9
7
|
function stores() {
|
|
@@ -59,9 +57,9 @@ const navigating = {
|
|
|
59
57
|
/** @param {string} verb */
|
|
60
58
|
const throw_error = (verb) => {
|
|
61
59
|
throw new Error(
|
|
62
|
-
|
|
63
|
-
? `
|
|
64
|
-
: `
|
|
60
|
+
browser
|
|
61
|
+
? `Cannot ${verb} session store before subscribing`
|
|
62
|
+
: `Can only ${verb} session store in browser`
|
|
65
63
|
);
|
|
66
64
|
};
|
|
67
65
|
|
|
@@ -70,7 +68,7 @@ const session = {
|
|
|
70
68
|
subscribe(fn) {
|
|
71
69
|
const store = getStores().session;
|
|
72
70
|
|
|
73
|
-
if (
|
|
71
|
+
if (browser) {
|
|
74
72
|
session.set = store.set;
|
|
75
73
|
session.update = store.update;
|
|
76
74
|
}
|
|
@@ -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({
|
|
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
|
-
|
|
967
|
-
|
|
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({
|
|
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
|
-
|
|
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({
|
|
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
|
|