@sveltejs/kit 1.0.0-next.224 → 1.0.0-next.229
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 +116 -114
- package/assets/runtime/app/navigation.js +17 -1
- package/assets/runtime/internal/start.js +167 -35
- package/dist/chunks/index.js +4 -3
- package/dist/chunks/index2.js +1 -15
- package/dist/chunks/index3.js +40 -18
- package/dist/chunks/index5.js +15 -2
- package/dist/cli.js +4 -2
- package/dist/ssr.js +116 -114
- package/package.json +1 -1
- package/types/ambient-modules.d.ts +13 -0
- package/types/config.d.ts +1 -0
- package/types/helper.d.ts +1 -1
- package/types/internal.d.ts +1 -1
package/assets/kit.js
CHANGED
|
@@ -537,12 +537,25 @@ function escape(str, dict, unicode_encoder) {
|
|
|
537
537
|
|
|
538
538
|
const s = JSON.stringify;
|
|
539
539
|
|
|
540
|
+
/** @param {URL} url */
|
|
541
|
+
function create_prerendering_url_proxy(url) {
|
|
542
|
+
return new Proxy(url, {
|
|
543
|
+
get: (target, prop, receiver) => {
|
|
544
|
+
if (prop === 'search' || prop === 'searchParams') {
|
|
545
|
+
throw new Error(`Cannot access url.${prop} on a page with prerendering enabled`);
|
|
546
|
+
}
|
|
547
|
+
return Reflect.get(target, prop, receiver);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
540
552
|
// TODO rename this function/module
|
|
541
553
|
|
|
542
554
|
/**
|
|
543
555
|
* @param {{
|
|
544
556
|
* branch: Array<import('./types').Loaded>;
|
|
545
557
|
* options: import('types/internal').SSRRenderOptions;
|
|
558
|
+
* state: import('types/internal').SSRRenderState;
|
|
546
559
|
* $session: any;
|
|
547
560
|
* page_config: { hydrate: boolean, router: boolean };
|
|
548
561
|
* status: number;
|
|
@@ -556,6 +569,7 @@ const s = JSON.stringify;
|
|
|
556
569
|
async function render_response({
|
|
557
570
|
branch,
|
|
558
571
|
options,
|
|
572
|
+
state,
|
|
559
573
|
$session,
|
|
560
574
|
page_config,
|
|
561
575
|
status,
|
|
@@ -567,7 +581,8 @@ async function render_response({
|
|
|
567
581
|
}) {
|
|
568
582
|
const css = new Set(options.manifest._.entry.css);
|
|
569
583
|
const js = new Set(options.manifest._.entry.js);
|
|
570
|
-
|
|
584
|
+
/** @type {Map<string, string>} */
|
|
585
|
+
const styles = new Map();
|
|
571
586
|
|
|
572
587
|
/** @type {Array<{ url: string, body: string, json: string }>} */
|
|
573
588
|
const serialized_data = [];
|
|
@@ -585,7 +600,7 @@ async function render_response({
|
|
|
585
600
|
branch.forEach(({ node, loaded, fetched, uses_credentials }) => {
|
|
586
601
|
if (node.css) node.css.forEach((url) => css.add(url));
|
|
587
602
|
if (node.js) node.js.forEach((url) => js.add(url));
|
|
588
|
-
if (node.styles) node.styles.forEach((
|
|
603
|
+
if (node.styles) Object.entries(node.styles).forEach(([k, v]) => styles.set(k, v));
|
|
589
604
|
|
|
590
605
|
// TODO probably better if `fetched` wasn't populated unless `hydrate`
|
|
591
606
|
if (fetched && page_config.hydrate) serialized_data.push(...fetched);
|
|
@@ -604,7 +619,13 @@ async function render_response({
|
|
|
604
619
|
navigating: writable(null),
|
|
605
620
|
session
|
|
606
621
|
},
|
|
607
|
-
page: {
|
|
622
|
+
page: {
|
|
623
|
+
url: state.prerender ? create_prerendering_url_proxy(url) : url,
|
|
624
|
+
params,
|
|
625
|
+
status,
|
|
626
|
+
error,
|
|
627
|
+
stuff
|
|
628
|
+
},
|
|
608
629
|
components: branch.map(({ node }) => node.module.default)
|
|
609
630
|
};
|
|
610
631
|
|
|
@@ -646,94 +667,80 @@ async function render_response({
|
|
|
646
667
|
rendered = { head: '', html: '', css: { code: '', map: null } };
|
|
647
668
|
}
|
|
648
669
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
// TODO strip the AMP stuff out of the build if not relevant
|
|
653
|
-
const links = options.amp
|
|
654
|
-
? styles.size > 0 || rendered.css.code.length > 0
|
|
655
|
-
? `<style amp-custom>${Array.from(styles).concat(rendered.css.code).join('\n')}</style>`
|
|
656
|
-
: ''
|
|
657
|
-
: [
|
|
658
|
-
// From https://web.dev/priority-hints/:
|
|
659
|
-
// Generally, preloads will load in the order the parser gets to them for anything above "Medium" priority
|
|
660
|
-
// Thus, we should list CSS first
|
|
661
|
-
...Array.from(css).map((dep) => `<link rel="stylesheet" href="${options.prefix}${dep}">`),
|
|
662
|
-
...Array.from(js).map((dep) => `<link rel="modulepreload" href="${options.prefix}${dep}">`)
|
|
663
|
-
].join('\n\t\t');
|
|
664
|
-
|
|
665
|
-
/** @type {string} */
|
|
666
|
-
let init = '';
|
|
670
|
+
let { head, html: body } = rendered;
|
|
671
|
+
|
|
672
|
+
const inlined_style = Array.from(styles.values()).join('\n');
|
|
667
673
|
|
|
668
674
|
if (options.amp) {
|
|
669
|
-
|
|
675
|
+
head += `
|
|
670
676
|
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
|
|
671
677
|
<noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
|
|
672
|
-
<script async src="https://cdn.ampproject.org/v0.js"></script
|
|
673
|
-
init += options.service_worker
|
|
674
|
-
? '<script async custom-element="amp-install-serviceworker" src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js"></script>'
|
|
675
|
-
: '';
|
|
676
|
-
} else if (include_js) {
|
|
677
|
-
// prettier-ignore
|
|
678
|
-
init = `<script type="module">
|
|
679
|
-
import { start } from ${s(options.prefix + options.manifest._.entry.file)};
|
|
680
|
-
start({
|
|
681
|
-
target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
|
|
682
|
-
paths: ${s(options.paths)},
|
|
683
|
-
session: ${try_serialize($session, (error) => {
|
|
684
|
-
throw new Error(`Failed to serialize session data: ${error.message}`);
|
|
685
|
-
})},
|
|
686
|
-
route: ${!!page_config.router},
|
|
687
|
-
spa: ${!ssr},
|
|
688
|
-
trailing_slash: ${s(options.trailing_slash)},
|
|
689
|
-
hydrate: ${ssr && page_config.hydrate ? `{
|
|
690
|
-
status: ${status},
|
|
691
|
-
error: ${serialize_error(error)},
|
|
692
|
-
nodes: [
|
|
693
|
-
${(branch || [])
|
|
694
|
-
.map(({ node }) => `import(${s(options.prefix + node.entry)})`)
|
|
695
|
-
.join(',\n\t\t\t\t\t\t')}
|
|
696
|
-
],
|
|
697
|
-
url: new URL(${s(url.href)}),
|
|
698
|
-
params: ${devalue(params)}
|
|
699
|
-
}` : 'null'}
|
|
700
|
-
});
|
|
701
|
-
</script>`;
|
|
702
|
-
}
|
|
678
|
+
<script async src="https://cdn.ampproject.org/v0.js"></script>
|
|
703
679
|
|
|
704
|
-
|
|
705
|
-
init += `<script>
|
|
706
|
-
if ('serviceWorker' in navigator) {
|
|
707
|
-
navigator.serviceWorker.register('${options.service_worker}');
|
|
708
|
-
}
|
|
709
|
-
</script>`;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
const head = [
|
|
713
|
-
rendered.head,
|
|
714
|
-
styles.size && !options.amp
|
|
715
|
-
? `<style data-svelte>${Array.from(styles).join('\n')}</style>`
|
|
716
|
-
: '',
|
|
717
|
-
links,
|
|
718
|
-
init
|
|
719
|
-
].join('\n\n\t\t');
|
|
680
|
+
<style amp-custom>${inlined_style}\n${rendered.css.code}</style>`;
|
|
720
681
|
|
|
721
|
-
let body = rendered.html;
|
|
722
|
-
if (options.amp) {
|
|
723
682
|
if (options.service_worker) {
|
|
683
|
+
head +=
|
|
684
|
+
'<script async custom-element="amp-install-serviceworker" src="https://cdn.ampproject.org/v0/amp-install-serviceworker-0.1.js"></script>';
|
|
685
|
+
|
|
724
686
|
body += `<amp-install-serviceworker src="${options.service_worker}" layout="nodisplay"></amp-install-serviceworker>`;
|
|
725
687
|
}
|
|
726
688
|
} else {
|
|
727
|
-
|
|
728
|
-
.
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
.
|
|
689
|
+
if (inlined_style) {
|
|
690
|
+
head += `\n\t<style${options.dev ? ' data-svelte' : ''}>${inlined_style}</style>`;
|
|
691
|
+
}
|
|
692
|
+
// prettier-ignore
|
|
693
|
+
head += Array.from(css)
|
|
694
|
+
.map((dep) => `\n\t<link${styles.has(dep) ? ' disabled' : ''} rel="stylesheet" href="${options.prefix + dep}">`)
|
|
695
|
+
.join('');
|
|
696
|
+
|
|
697
|
+
if (page_config.router || page_config.hydrate) {
|
|
698
|
+
head += Array.from(js)
|
|
699
|
+
.map((dep) => `\n\t<link rel="modulepreload" href="${options.prefix + dep}">`)
|
|
700
|
+
.join('');
|
|
701
|
+
// prettier-ignore
|
|
702
|
+
head += `
|
|
703
|
+
<script type="module">
|
|
704
|
+
import { start } from ${s(options.prefix + options.manifest._.entry.file)};
|
|
705
|
+
start({
|
|
706
|
+
target: ${options.target ? `document.querySelector(${s(options.target)})` : 'document.body'},
|
|
707
|
+
paths: ${s(options.paths)},
|
|
708
|
+
session: ${try_serialize($session, (error) => {
|
|
709
|
+
throw new Error(`Failed to serialize session data: ${error.message}`);
|
|
710
|
+
})},
|
|
711
|
+
route: ${!!page_config.router},
|
|
712
|
+
spa: ${!ssr},
|
|
713
|
+
trailing_slash: ${s(options.trailing_slash)},
|
|
714
|
+
hydrate: ${ssr && page_config.hydrate ? `{
|
|
715
|
+
status: ${status},
|
|
716
|
+
error: ${serialize_error(error)},
|
|
717
|
+
nodes: [
|
|
718
|
+
${(branch || [])
|
|
719
|
+
.map(({ node }) => `import(${s(options.prefix + node.entry)})`)
|
|
720
|
+
.join(',\n\t\t\t\t\t\t')}
|
|
721
|
+
],
|
|
722
|
+
url: new URL(${s(url.href)}),
|
|
723
|
+
params: ${devalue(params)}
|
|
724
|
+
}` : 'null'}
|
|
725
|
+
});
|
|
726
|
+
</script>${options.service_worker ? `
|
|
727
|
+
<script>
|
|
728
|
+
if ('serviceWorker' in navigator) {
|
|
729
|
+
navigator.serviceWorker.register('${options.service_worker}');
|
|
730
|
+
}
|
|
731
|
+
</script>` : ''}`;
|
|
732
|
+
|
|
733
|
+
body += serialized_data
|
|
734
|
+
.map(({ url, body, json }) => {
|
|
735
|
+
let attributes = `type="application/json" data-type="svelte-data" data-url=${escape_html_attr(
|
|
736
|
+
url
|
|
737
|
+
)}`;
|
|
738
|
+
if (body) attributes += ` data-body="${hash(body)}"`;
|
|
739
|
+
|
|
740
|
+
return `<script ${attributes}>${json}</script>`;
|
|
741
|
+
})
|
|
742
|
+
.join('\n\n\t');
|
|
743
|
+
}
|
|
737
744
|
}
|
|
738
745
|
|
|
739
746
|
/** @type {import('types/helper').ResponseHeaders} */
|
|
@@ -908,7 +915,6 @@ function is_root_relative(path) {
|
|
|
908
915
|
* node: import('types/internal').SSRNode;
|
|
909
916
|
* $session: any;
|
|
910
917
|
* stuff: Record<string, any>;
|
|
911
|
-
* prerender_enabled: boolean;
|
|
912
918
|
* is_error: boolean;
|
|
913
919
|
* status?: number;
|
|
914
920
|
* error?: Error;
|
|
@@ -925,7 +931,6 @@ async function load_node({
|
|
|
925
931
|
node,
|
|
926
932
|
$session,
|
|
927
933
|
stuff,
|
|
928
|
-
prerender_enabled,
|
|
929
934
|
is_error,
|
|
930
935
|
status,
|
|
931
936
|
error
|
|
@@ -950,19 +955,10 @@ async function load_node({
|
|
|
950
955
|
|
|
951
956
|
let loaded;
|
|
952
957
|
|
|
953
|
-
const url_proxy = new Proxy(url, {
|
|
954
|
-
get: (target, prop, receiver) => {
|
|
955
|
-
if (prerender_enabled && (prop === 'search' || prop === 'searchParams')) {
|
|
956
|
-
throw new Error('Cannot access query on a page with prerendering enabled');
|
|
957
|
-
}
|
|
958
|
-
return Reflect.get(target, prop, receiver);
|
|
959
|
-
}
|
|
960
|
-
});
|
|
961
|
-
|
|
962
958
|
if (module.load) {
|
|
963
959
|
/** @type {import('types/page').LoadInput | import('types/page').ErrorLoadInput} */
|
|
964
960
|
const load_input = {
|
|
965
|
-
url:
|
|
961
|
+
url: state.prerender ? create_prerendering_url_proxy(url) : url,
|
|
966
962
|
params,
|
|
967
963
|
get session() {
|
|
968
964
|
uses_credentials = true;
|
|
@@ -1209,7 +1205,6 @@ async function load_node({
|
|
|
1209
1205
|
|
|
1210
1206
|
/**
|
|
1211
1207
|
* @typedef {import('./types.js').Loaded} Loaded
|
|
1212
|
-
* @typedef {import('types/internal').SSRNode} SSRNode
|
|
1213
1208
|
* @typedef {import('types/internal').SSRRenderOptions} SSRRenderOptions
|
|
1214
1209
|
* @typedef {import('types/internal').SSRRenderState} SSRRenderState
|
|
1215
1210
|
*/
|
|
@@ -1252,7 +1247,6 @@ async function respond_with_error({
|
|
|
1252
1247
|
node: default_layout,
|
|
1253
1248
|
$session,
|
|
1254
1249
|
stuff: {},
|
|
1255
|
-
prerender_enabled: is_prerender_enabled(options, default_error, state),
|
|
1256
1250
|
is_error: false
|
|
1257
1251
|
})
|
|
1258
1252
|
);
|
|
@@ -1268,7 +1262,6 @@ async function respond_with_error({
|
|
|
1268
1262
|
node: default_error,
|
|
1269
1263
|
$session,
|
|
1270
1264
|
stuff: layout_loaded ? layout_loaded.stuff : {},
|
|
1271
|
-
prerender_enabled: is_prerender_enabled(options, default_error, state),
|
|
1272
1265
|
is_error: true,
|
|
1273
1266
|
status,
|
|
1274
1267
|
error
|
|
@@ -1277,6 +1270,7 @@ async function respond_with_error({
|
|
|
1277
1270
|
|
|
1278
1271
|
return await render_response({
|
|
1279
1272
|
options,
|
|
1273
|
+
state,
|
|
1280
1274
|
$session,
|
|
1281
1275
|
page_config: {
|
|
1282
1276
|
hydrate: options.hydrate,
|
|
@@ -1303,17 +1297,6 @@ async function respond_with_error({
|
|
|
1303
1297
|
}
|
|
1304
1298
|
}
|
|
1305
1299
|
|
|
1306
|
-
/**
|
|
1307
|
-
* @param {SSRRenderOptions} options
|
|
1308
|
-
* @param {SSRNode} node
|
|
1309
|
-
* @param {SSRRenderState} state
|
|
1310
|
-
*/
|
|
1311
|
-
function is_prerender_enabled(options, node, state) {
|
|
1312
|
-
return (
|
|
1313
|
-
options.prerender && (!!node.module.prerender || (!!state.prerender && state.prerender.all))
|
|
1314
|
-
);
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
1300
|
/**
|
|
1318
1301
|
* @typedef {import('./types.js').Loaded} Loaded
|
|
1319
1302
|
* @typedef {import('types/hooks').ServerResponse} ServerResponse
|
|
@@ -1416,7 +1399,6 @@ async function respond$1(opts) {
|
|
|
1416
1399
|
url: request.url,
|
|
1417
1400
|
node,
|
|
1418
1401
|
stuff,
|
|
1419
|
-
prerender_enabled: is_prerender_enabled(options, node, state),
|
|
1420
1402
|
is_error: false
|
|
1421
1403
|
});
|
|
1422
1404
|
|
|
@@ -1471,7 +1453,6 @@ async function respond$1(opts) {
|
|
|
1471
1453
|
url: request.url,
|
|
1472
1454
|
node: error_node,
|
|
1473
1455
|
stuff: node_loaded.stuff,
|
|
1474
|
-
prerender_enabled: is_prerender_enabled(options, error_node, state),
|
|
1475
1456
|
is_error: true,
|
|
1476
1457
|
status,
|
|
1477
1458
|
error
|
|
@@ -1641,8 +1622,9 @@ function read_only_form_data() {
|
|
|
1641
1622
|
* @param {string} value
|
|
1642
1623
|
*/
|
|
1643
1624
|
append(key, value) {
|
|
1644
|
-
|
|
1645
|
-
|
|
1625
|
+
const existing_values = map.get(key);
|
|
1626
|
+
if (existing_values) {
|
|
1627
|
+
existing_values.push(value);
|
|
1646
1628
|
} else {
|
|
1647
1629
|
map.set(key, [value]);
|
|
1648
1630
|
}
|
|
@@ -1664,12 +1646,15 @@ class ReadOnlyFormData {
|
|
|
1664
1646
|
/** @param {string} key */
|
|
1665
1647
|
get(key) {
|
|
1666
1648
|
const value = this.#map.get(key);
|
|
1667
|
-
|
|
1649
|
+
if (!value) {
|
|
1650
|
+
return null;
|
|
1651
|
+
}
|
|
1652
|
+
return value[0];
|
|
1668
1653
|
}
|
|
1669
1654
|
|
|
1670
1655
|
/** @param {string} key */
|
|
1671
1656
|
getAll(key) {
|
|
1672
|
-
return this.#map.get(key);
|
|
1657
|
+
return this.#map.get(key) || [];
|
|
1673
1658
|
}
|
|
1674
1659
|
|
|
1675
1660
|
/** @param {string} key */
|
|
@@ -1901,6 +1886,7 @@ async function respond(incoming, options, state = {}) {
|
|
|
1901
1886
|
url: request.url,
|
|
1902
1887
|
params: request.params,
|
|
1903
1888
|
options,
|
|
1889
|
+
state,
|
|
1904
1890
|
$session: await options.hooks.getSession(request),
|
|
1905
1891
|
page_config: { router: true, hydrate: true },
|
|
1906
1892
|
stuff: {},
|
|
@@ -1935,9 +1921,25 @@ async function respond(incoming, options, state = {}) {
|
|
|
1935
1921
|
const etag = `"${hash(response.body || '')}"`;
|
|
1936
1922
|
|
|
1937
1923
|
if (if_none_match_value === etag) {
|
|
1924
|
+
/** @type {import('types/helper').ResponseHeaders} */
|
|
1925
|
+
const headers = { etag };
|
|
1926
|
+
|
|
1927
|
+
// https://datatracker.ietf.org/doc/html/rfc7232#section-4.1
|
|
1928
|
+
for (const key of [
|
|
1929
|
+
'cache-control',
|
|
1930
|
+
'content-location',
|
|
1931
|
+
'date',
|
|
1932
|
+
'expires',
|
|
1933
|
+
'vary'
|
|
1934
|
+
]) {
|
|
1935
|
+
if (key in response.headers) {
|
|
1936
|
+
headers[key] = /** @type {string} */ (response.headers[key]);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1938
1940
|
return {
|
|
1939
1941
|
status: 304,
|
|
1940
|
-
headers
|
|
1942
|
+
headers
|
|
1941
1943
|
};
|
|
1942
1944
|
}
|
|
1943
1945
|
|
|
@@ -19,6 +19,8 @@ const goto = import.meta.env.SSR ? guard('goto') : goto_;
|
|
|
19
19
|
const invalidate = import.meta.env.SSR ? guard('invalidate') : invalidate_;
|
|
20
20
|
const prefetch = import.meta.env.SSR ? guard('prefetch') : prefetch_;
|
|
21
21
|
const prefetchRoutes = import.meta.env.SSR ? guard('prefetchRoutes') : prefetchRoutes_;
|
|
22
|
+
const beforeNavigate = import.meta.env.SSR ? () => {} : beforeNavigate_;
|
|
23
|
+
const afterNavigate = import.meta.env.SSR ? () => {} : afterNavigate_;
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* @type {import('$app/navigation').goto}
|
|
@@ -62,4 +64,18 @@ async function prefetchRoutes_(pathnames) {
|
|
|
62
64
|
await Promise.all(promises);
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
/**
|
|
68
|
+
* @type {import('$app/navigation').beforeNavigate}
|
|
69
|
+
*/
|
|
70
|
+
function beforeNavigate_(fn) {
|
|
71
|
+
if (router) router.before_navigate(fn);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @type {import('$app/navigation').afterNavigate}
|
|
76
|
+
*/
|
|
77
|
+
function afterNavigate_(fn) {
|
|
78
|
+
if (router) router.after_navigate(fn);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { afterNavigate, beforeNavigate, disableScrollHandling, goto, invalidate, prefetch, prefetchRoutes };
|