@sveltejs/kit 1.3.0 → 1.3.2
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/package.json +1 -1
- package/src/core/adapt/builder.js +6 -14
- package/src/core/adapt/index.js +4 -2
- package/src/core/generate_manifest/index.js +2 -2
- package/src/core/postbuild/analyse.js +135 -0
- package/src/core/postbuild/prerender.js +66 -55
- package/src/core/sync/sync.js +2 -4
- package/src/core/sync/ts.js +6 -0
- package/src/core/sync/write_client_manifest.js +54 -13
- package/src/core/sync/write_server.js +5 -4
- package/src/core/sync/write_tsconfig.js +5 -1
- package/src/core/sync/write_types/index.js +1 -7
- package/src/exports/vite/build/build_server.js +32 -94
- package/src/exports/vite/build/build_service_worker.js +16 -19
- package/src/exports/vite/index.js +158 -157
- package/src/runtime/client/ambient.d.ts +1 -1
- package/src/runtime/client/client.js +15 -8
- package/src/runtime/client/parse.js +1 -1
- package/src/runtime/server/ambient.d.ts +1 -1
- package/src/runtime/server/index.js +1 -1
- package/src/utils/filesystem.js +5 -0
- package/src/utils/fork.js +74 -0
- package/types/index.d.ts +3 -1
- package/types/internal.d.ts +20 -20
- package/src/core/postbuild/index.js +0 -113
- package/src/core/sync/write_matchers.js +0 -25
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { fork } from 'node:child_process';
|
|
2
1
|
import fs from 'node:fs';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
3
|
|
|
6
4
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
7
5
|
import colors from 'kleur';
|
|
8
6
|
import * as vite from 'vite';
|
|
9
7
|
|
|
10
|
-
import { mkdirp, posixify, resolve_entry, rimraf } from '../../utils/filesystem.js';
|
|
8
|
+
import { mkdirp, posixify, read, resolve_entry, rimraf } from '../../utils/filesystem.js';
|
|
11
9
|
import { create_static_module, create_dynamic_module } from '../../core/env.js';
|
|
12
10
|
import * as sync from '../../core/sync/sync.js';
|
|
13
11
|
import { create_assets } from '../../core/sync/create_manifest_data/index.js';
|
|
14
12
|
import { runtime_directory, logger } from '../../core/utils.js';
|
|
15
13
|
import { load_config } from '../../core/config/index.js';
|
|
16
14
|
import { generate_manifest } from '../../core/generate_manifest/index.js';
|
|
17
|
-
import {
|
|
15
|
+
import { build_server_nodes } from './build/build_server.js';
|
|
18
16
|
import { build_service_worker } from './build/build_service_worker.js';
|
|
19
17
|
import { assets_base, find_deps } from './build/utils.js';
|
|
20
18
|
import { dev } from './dev/index.js';
|
|
21
19
|
import { is_illegal, module_guard, normalize_id } from './graph_analysis/index.js';
|
|
22
20
|
import { preview } from './preview/index.js';
|
|
23
21
|
import { get_config_aliases, get_env } from './utils.js';
|
|
22
|
+
import { write_client_manifest } from '../../core/sync/write_client_manifest.js';
|
|
23
|
+
import prerender from '../../core/postbuild/prerender.js';
|
|
24
|
+
import analyse from '../../core/postbuild/analyse.js';
|
|
24
25
|
|
|
25
26
|
export { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
|
26
27
|
|
|
@@ -138,6 +139,11 @@ export async function sveltekit() {
|
|
|
138
139
|
return [...svelte(vite_plugin_svelte_options), ...kit({ svelte_config })];
|
|
139
140
|
}
|
|
140
141
|
|
|
142
|
+
/**
|
|
143
|
+
* If `true`, the server build has been completed and we're creating the client build
|
|
144
|
+
*/
|
|
145
|
+
let secondary_build = false;
|
|
146
|
+
|
|
141
147
|
/**
|
|
142
148
|
* Returns the SvelteKit Vite plugin. Vite executes Rollup hooks as well as some of its own.
|
|
143
149
|
* Background reading is available at:
|
|
@@ -167,22 +173,13 @@ function kit({ svelte_config }) {
|
|
|
167
173
|
/** @type {boolean} */
|
|
168
174
|
let is_build;
|
|
169
175
|
|
|
170
|
-
/** @type {import('types').Logger} */
|
|
171
|
-
let log;
|
|
172
|
-
|
|
173
|
-
/** @type {import('types').Prerendered} */
|
|
174
|
-
let prerendered;
|
|
175
|
-
|
|
176
|
-
/** @type {import('types').PrerenderMap} */
|
|
177
|
-
let prerender_map;
|
|
178
|
-
|
|
179
|
-
/** @type {import('types').BuildData} */
|
|
180
|
-
let build_data;
|
|
181
|
-
|
|
182
176
|
/** @type {{ public: Record<string, string>; private: Record<string, string> }} */
|
|
183
177
|
let env;
|
|
184
178
|
|
|
185
|
-
|
|
179
|
+
/** @type {(() => Promise<void>) | null} */
|
|
180
|
+
let finalise = null;
|
|
181
|
+
|
|
182
|
+
const service_worker_entry_file = resolve_entry(kit.files.serviceWorker);
|
|
186
183
|
|
|
187
184
|
/** @type {import('vite').Plugin} */
|
|
188
185
|
const plugin_setup = {
|
|
@@ -212,12 +209,19 @@ function kit({ svelte_config }) {
|
|
|
212
209
|
const client_hooks = resolve_entry(kit.files.hooks.client);
|
|
213
210
|
if (client_hooks) allow.add(path.dirname(client_hooks));
|
|
214
211
|
|
|
212
|
+
const generated = path.posix.join(kit.outDir, 'generated');
|
|
213
|
+
|
|
215
214
|
// dev and preview config can be shared
|
|
216
215
|
/** @type {import('vite').UserConfig} */
|
|
217
216
|
const new_config = {
|
|
218
217
|
resolve: {
|
|
219
218
|
alias: [
|
|
220
|
-
{
|
|
219
|
+
{
|
|
220
|
+
find: '__CLIENT__',
|
|
221
|
+
replacement: `${generated}/${is_build ? 'client-optimized' : 'client'}`
|
|
222
|
+
},
|
|
223
|
+
{ find: '__SERVER__', replacement: `${generated}/server` },
|
|
224
|
+
{ find: '__GENERATED__', replacement: generated },
|
|
221
225
|
{ find: '$app', replacement: `${runtime_directory}/app` },
|
|
222
226
|
...get_config_aliases(kit)
|
|
223
227
|
]
|
|
@@ -246,6 +250,9 @@ function kit({ svelte_config }) {
|
|
|
246
250
|
};
|
|
247
251
|
|
|
248
252
|
if (is_build) {
|
|
253
|
+
if (!new_config.build) new_config.build = {};
|
|
254
|
+
new_config.build.ssr = !secondary_build;
|
|
255
|
+
|
|
249
256
|
new_config.define = {
|
|
250
257
|
__SVELTEKIT_ADAPTER_NAME__: JSON.stringify(kit.adapter?.name),
|
|
251
258
|
__SVELTEKIT_APP_VERSION_FILE__: JSON.stringify(`${kit.appDir}/version.json`),
|
|
@@ -345,6 +352,35 @@ function kit({ svelte_config }) {
|
|
|
345
352
|
}
|
|
346
353
|
};
|
|
347
354
|
|
|
355
|
+
/**
|
|
356
|
+
* Ensures that client-side code can't accidentally import server-side code,
|
|
357
|
+
* whether in `*.server.js` files, `$lib/server`, or `$env/[static|dynamic]/private`
|
|
358
|
+
* @type {import('vite').Plugin}
|
|
359
|
+
*/
|
|
360
|
+
const plugin_guard = {
|
|
361
|
+
name: 'vite-plugin-sveltekit-guard',
|
|
362
|
+
|
|
363
|
+
writeBundle: {
|
|
364
|
+
sequential: true,
|
|
365
|
+
async handler(_options) {
|
|
366
|
+
if (!secondary_build) return;
|
|
367
|
+
|
|
368
|
+
const guard = module_guard(this, {
|
|
369
|
+
cwd: vite.normalizePath(process.cwd()),
|
|
370
|
+
lib: vite.normalizePath(kit.files.lib)
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
manifest_data.nodes.forEach((_node, i) => {
|
|
374
|
+
const id = vite.normalizePath(
|
|
375
|
+
path.resolve(kit.outDir, `generated/client-optimized/nodes/${i}.js`)
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
guard.check(id);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
|
|
348
384
|
/** @type {import('vite').Plugin} */
|
|
349
385
|
const plugin_compile = {
|
|
350
386
|
name: 'vite-plugin-sveltekit-compile',
|
|
@@ -360,7 +396,7 @@ function kit({ svelte_config }) {
|
|
|
360
396
|
if (is_build) {
|
|
361
397
|
manifest_data = (await sync.all(svelte_config, config_env.mode)).manifest_data;
|
|
362
398
|
|
|
363
|
-
const ssr = config.build?.ssr
|
|
399
|
+
const ssr = /** @type {boolean} */ (config.build?.ssr);
|
|
364
400
|
const prefix = `${kit.appDir}/immutable`;
|
|
365
401
|
|
|
366
402
|
/** @type {Record<string, string>} */
|
|
@@ -368,7 +404,7 @@ function kit({ svelte_config }) {
|
|
|
368
404
|
|
|
369
405
|
if (ssr) {
|
|
370
406
|
input.index = `${runtime_directory}/server/index.js`;
|
|
371
|
-
input.internal = `${kit.outDir}/generated/server
|
|
407
|
+
input.internal = `${kit.outDir}/generated/server/internal.js`;
|
|
372
408
|
|
|
373
409
|
// add entry points for every endpoint...
|
|
374
410
|
manifest_data.routes.forEach((route) => {
|
|
@@ -499,10 +535,10 @@ function kit({ svelte_config }) {
|
|
|
499
535
|
* Clears the output directories.
|
|
500
536
|
*/
|
|
501
537
|
buildStart() {
|
|
502
|
-
if (
|
|
538
|
+
if (secondary_build) return;
|
|
503
539
|
|
|
504
|
-
//
|
|
505
|
-
|
|
540
|
+
// reset (here, not in `config`, because `build --watch` skips `config`)
|
|
541
|
+
finalise = null;
|
|
506
542
|
|
|
507
543
|
if (is_build) {
|
|
508
544
|
if (!vite_config.build.watch) {
|
|
@@ -513,7 +549,7 @@ function kit({ svelte_config }) {
|
|
|
513
549
|
},
|
|
514
550
|
|
|
515
551
|
generateBundle() {
|
|
516
|
-
if (
|
|
552
|
+
if (!secondary_build) return;
|
|
517
553
|
|
|
518
554
|
this.emitFile({
|
|
519
555
|
type: 'asset',
|
|
@@ -529,71 +565,77 @@ function kit({ svelte_config }) {
|
|
|
529
565
|
*/
|
|
530
566
|
writeBundle: {
|
|
531
567
|
sequential: true,
|
|
532
|
-
async handler(_options
|
|
533
|
-
if (
|
|
568
|
+
async handler(_options) {
|
|
569
|
+
if (secondary_build) return; // only run this once
|
|
570
|
+
secondary_build = true;
|
|
534
571
|
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
lib: vite.normalizePath(kit.files.lib)
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
manifest_data.nodes.forEach((_node, i) => {
|
|
541
|
-
const id = vite.normalizePath(path.resolve(kit.outDir, `generated/nodes/${i}.js`));
|
|
572
|
+
const verbose = vite_config.logLevel === 'info';
|
|
573
|
+
const log = logger({ verbose });
|
|
542
574
|
|
|
543
|
-
|
|
544
|
-
});
|
|
575
|
+
/** @type {import('vite').Manifest} */
|
|
576
|
+
const server_manifest = JSON.parse(read(`${out}/server/${vite_config.build.manifest}`));
|
|
545
577
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
578
|
+
/** @type {import('types').BuildData} */
|
|
579
|
+
const build_data = {
|
|
580
|
+
app_dir: kit.appDir,
|
|
581
|
+
app_path: `${kit.paths.base.slice(1)}${kit.paths.base ? '/' : ''}${kit.appDir}`,
|
|
582
|
+
manifest_data,
|
|
583
|
+
service_worker: !!service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable?
|
|
584
|
+
client_entry: null,
|
|
585
|
+
server_manifest
|
|
586
|
+
};
|
|
550
587
|
|
|
551
|
-
const
|
|
552
|
-
|
|
553
|
-
|
|
588
|
+
const manifest_path = `${out}/server/manifest-full.js`;
|
|
589
|
+
fs.writeFileSync(
|
|
590
|
+
manifest_path,
|
|
591
|
+
`export const manifest = ${generate_manifest({
|
|
592
|
+
build_data,
|
|
593
|
+
relative_path: '.',
|
|
594
|
+
routes: manifest_data.routes
|
|
595
|
+
})};\n`
|
|
554
596
|
);
|
|
555
597
|
|
|
556
|
-
|
|
598
|
+
// first, build server nodes without the client manifest so we can analyse it
|
|
599
|
+
build_server_nodes(out, kit, manifest_data, server_manifest, null, null);
|
|
557
600
|
|
|
558
|
-
const
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
manifest_data,
|
|
563
|
-
output_dir: out
|
|
564
|
-
};
|
|
601
|
+
const metadata = await analyse({
|
|
602
|
+
manifest_path,
|
|
603
|
+
env: { ...env.private, ...env.public }
|
|
604
|
+
});
|
|
565
605
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
606
|
+
// create client build
|
|
607
|
+
write_client_manifest(
|
|
608
|
+
kit,
|
|
609
|
+
manifest_data,
|
|
610
|
+
`${kit.outDir}/generated/client-optimized`,
|
|
611
|
+
metadata.nodes
|
|
569
612
|
);
|
|
570
613
|
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
)
|
|
579
|
-
|
|
580
|
-
};
|
|
614
|
+
const { output } = /** @type {import('rollup').RollupOutput} */ (
|
|
615
|
+
await vite.build({
|
|
616
|
+
configFile: vite_config.configFile,
|
|
617
|
+
// CLI args
|
|
618
|
+
mode: vite_config_env.mode,
|
|
619
|
+
logLevel: vite_config.logLevel,
|
|
620
|
+
clearScreen: vite_config.clearScreen
|
|
621
|
+
})
|
|
622
|
+
);
|
|
581
623
|
|
|
582
|
-
|
|
624
|
+
/** @type {import('vite').Manifest} */
|
|
625
|
+
const client_manifest = JSON.parse(read(`${out}/client/${vite_config.build.manifest}`));
|
|
583
626
|
|
|
584
|
-
|
|
627
|
+
build_data.client_entry = find_deps(
|
|
628
|
+
client_manifest,
|
|
629
|
+
posixify(path.relative('.', `${runtime_directory}/client/start.js`)),
|
|
630
|
+
false
|
|
631
|
+
);
|
|
585
632
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
manifest_data,
|
|
591
|
-
service_worker: !!service_worker_entry_file ? 'service-worker.js' : null, // TODO make file configurable?
|
|
592
|
-
client,
|
|
593
|
-
server
|
|
594
|
-
};
|
|
633
|
+
const css = output.filter(
|
|
634
|
+
/** @type {(value: any) => value is import('rollup').OutputAsset} */
|
|
635
|
+
(value) => value.type === 'asset' && value.fileName.endsWith('.css')
|
|
636
|
+
);
|
|
595
637
|
|
|
596
|
-
|
|
638
|
+
// regenerate manifest now that we have client entry...
|
|
597
639
|
fs.writeFileSync(
|
|
598
640
|
manifest_path,
|
|
599
641
|
`export const manifest = ${generate_manifest({
|
|
@@ -603,44 +645,18 @@ function kit({ svelte_config }) {
|
|
|
603
645
|
})};\n`
|
|
604
646
|
);
|
|
605
647
|
|
|
648
|
+
// regenerate nodes with the client manifest...
|
|
649
|
+
build_server_nodes(out, kit, manifest_data, server_manifest, client_manifest, css);
|
|
650
|
+
|
|
651
|
+
// ...and prerender
|
|
606
652
|
log.info('Prerendering');
|
|
607
|
-
await new Promise((fulfil, reject) => {
|
|
608
|
-
const results_path = `${kit.outDir}/generated/prerendered.json`;
|
|
609
|
-
|
|
610
|
-
// do prerendering in a subprocess so any dangling stuff gets killed upon completion
|
|
611
|
-
const script = fileURLToPath(new URL('../../core/postbuild/index.js', import.meta.url));
|
|
612
|
-
|
|
613
|
-
const child = fork(
|
|
614
|
-
script,
|
|
615
|
-
[
|
|
616
|
-
vite_config.build.outDir,
|
|
617
|
-
manifest_path,
|
|
618
|
-
results_path,
|
|
619
|
-
'' + verbose,
|
|
620
|
-
JSON.stringify({ ...env.private, ...env.public })
|
|
621
|
-
],
|
|
622
|
-
{
|
|
623
|
-
stdio: 'inherit'
|
|
624
|
-
}
|
|
625
|
-
);
|
|
626
653
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
return new Map(value);
|
|
634
|
-
}
|
|
635
|
-
return value;
|
|
636
|
-
});
|
|
637
|
-
|
|
638
|
-
prerendered = results.prerendered;
|
|
639
|
-
prerender_map = new Map(results.prerender_map);
|
|
640
|
-
|
|
641
|
-
fulfil(undefined);
|
|
642
|
-
}
|
|
643
|
-
});
|
|
654
|
+
const { prerendered, prerender_map } = await prerender({
|
|
655
|
+
out,
|
|
656
|
+
manifest_path,
|
|
657
|
+
metadata,
|
|
658
|
+
verbose,
|
|
659
|
+
env: { ...env.private, ...env.public }
|
|
644
660
|
});
|
|
645
661
|
|
|
646
662
|
// generate a new manifest that doesn't include prerendered pages
|
|
@@ -661,18 +677,41 @@ function kit({ svelte_config }) {
|
|
|
661
677
|
log.info('Building service worker');
|
|
662
678
|
|
|
663
679
|
await build_service_worker(
|
|
664
|
-
|
|
680
|
+
out,
|
|
681
|
+
kit,
|
|
682
|
+
vite_config,
|
|
683
|
+
manifest_data,
|
|
665
684
|
service_worker_entry_file,
|
|
666
685
|
prerendered,
|
|
667
|
-
|
|
686
|
+
client_manifest
|
|
668
687
|
);
|
|
669
688
|
}
|
|
670
689
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
)
|
|
690
|
+
// we need to defer this to closeBundle, so that adapters copy files
|
|
691
|
+
// created by other Vite plugins
|
|
692
|
+
finalise = async () => {
|
|
693
|
+
console.log(
|
|
694
|
+
`\nRun ${colors
|
|
695
|
+
.bold()
|
|
696
|
+
.cyan('npm run preview')} to preview your production build locally.`
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
if (kit.adapter) {
|
|
700
|
+
const { adapt } = await import('../../core/adapt/index.js');
|
|
701
|
+
await adapt(svelte_config, build_data, metadata, prerendered, prerender_map, log);
|
|
702
|
+
} else {
|
|
703
|
+
console.log(colors.bold().yellow('\nNo adapter specified'));
|
|
674
704
|
|
|
675
|
-
|
|
705
|
+
const link = colors.bold().cyan('https://kit.svelte.dev/docs/adapters');
|
|
706
|
+
console.log(
|
|
707
|
+
`See ${link} to learn how to configure your app to run on the platform of your choosing`
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// avoid making the manifest available to users
|
|
712
|
+
fs.unlinkSync(`${out}/client/${vite_config.build.manifest}`);
|
|
713
|
+
fs.unlinkSync(`${out}/server/${vite_config.build.manifest}`);
|
|
714
|
+
};
|
|
676
715
|
}
|
|
677
716
|
},
|
|
678
717
|
|
|
@@ -682,50 +721,12 @@ function kit({ svelte_config }) {
|
|
|
682
721
|
closeBundle: {
|
|
683
722
|
sequential: true,
|
|
684
723
|
async handler() {
|
|
685
|
-
|
|
686
|
-
// and only adapt when build successfully completes.
|
|
687
|
-
const is_restart = !completed_build;
|
|
688
|
-
if (vite_config.build.ssr || is_restart) {
|
|
689
|
-
return;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
if (kit.adapter) {
|
|
693
|
-
const { adapt } = await import('../../core/adapt/index.js');
|
|
694
|
-
await adapt(svelte_config, build_data, prerendered, prerender_map, { log });
|
|
695
|
-
} else {
|
|
696
|
-
console.log(colors.bold().yellow('\nNo adapter specified'));
|
|
697
|
-
|
|
698
|
-
const link = colors.bold().cyan('https://kit.svelte.dev/docs/adapters');
|
|
699
|
-
console.log(
|
|
700
|
-
`See ${link} to learn how to configure your app to run on the platform of your choosing`
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
// avoid making the manifest available to users
|
|
705
|
-
fs.unlinkSync(`${out}/client/${vite_config.build.manifest}`);
|
|
706
|
-
fs.unlinkSync(`${out}/server/${vite_config.build.manifest}`);
|
|
724
|
+
finalise?.();
|
|
707
725
|
}
|
|
708
726
|
}
|
|
709
727
|
};
|
|
710
728
|
|
|
711
|
-
return [plugin_setup, plugin_virtual_modules, plugin_compile];
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
/** @param {import('rollup').OutputBundle} bundle */
|
|
715
|
-
function collect_output(bundle) {
|
|
716
|
-
/** @type {import('rollup').OutputChunk[]} */
|
|
717
|
-
const chunks = [];
|
|
718
|
-
/** @type {import('rollup').OutputAsset[]} */
|
|
719
|
-
const assets = [];
|
|
720
|
-
for (const value of Object.values(bundle)) {
|
|
721
|
-
// collect asset and output chunks
|
|
722
|
-
if (value.type === 'asset') {
|
|
723
|
-
assets.push(value);
|
|
724
|
-
} else {
|
|
725
|
-
chunks.push(value);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
return { assets, chunks };
|
|
729
|
+
return [plugin_setup, plugin_virtual_modules, plugin_guard, plugin_compile];
|
|
729
730
|
}
|
|
730
731
|
|
|
731
732
|
/**
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
import { parse } from './parse.js';
|
|
26
26
|
|
|
27
27
|
import Root from '__GENERATED__/root.svelte';
|
|
28
|
-
import { nodes, server_loads, dictionary, matchers, hooks } from '
|
|
28
|
+
import { nodes, server_loads, dictionary, matchers, hooks } from '__CLIENT__/manifest.js';
|
|
29
29
|
import { HttpError, Redirect } from '../control.js';
|
|
30
30
|
import { stores } from './singletons.js';
|
|
31
31
|
import { unwrap_promises } from '../../utils/promises.js';
|
|
@@ -921,12 +921,12 @@ export function create_client({ target, base }) {
|
|
|
921
921
|
/** @type {Record<string, string>} */
|
|
922
922
|
const params = {}; // error page does not have params
|
|
923
923
|
|
|
924
|
-
const node = await default_layout_loader();
|
|
925
|
-
|
|
926
924
|
/** @type {import('types').ServerDataNode | null} */
|
|
927
925
|
let server_data_node = null;
|
|
928
926
|
|
|
929
|
-
|
|
927
|
+
const default_layout_has_server_load = server_loads[0] === 0;
|
|
928
|
+
|
|
929
|
+
if (default_layout_has_server_load) {
|
|
930
930
|
// TODO post-https://github.com/sveltejs/kit/discussions/6124 we can use
|
|
931
931
|
// existing root layout data
|
|
932
932
|
try {
|
|
@@ -984,7 +984,7 @@ export function create_client({ target, base }) {
|
|
|
984
984
|
function get_navigation_intent(url, invalidating) {
|
|
985
985
|
if (is_external_url(url, base)) return;
|
|
986
986
|
|
|
987
|
-
const path =
|
|
987
|
+
const path = get_url_path(url);
|
|
988
988
|
|
|
989
989
|
for (const route of routes) {
|
|
990
990
|
const params = route.exec(path);
|
|
@@ -998,6 +998,11 @@ export function create_client({ target, base }) {
|
|
|
998
998
|
}
|
|
999
999
|
}
|
|
1000
1000
|
|
|
1001
|
+
/** @param {URL} url */
|
|
1002
|
+
function get_url_path(url) {
|
|
1003
|
+
return decode_pathname(url.pathname.slice(base.length) || '/');
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1001
1006
|
/**
|
|
1002
1007
|
* @param {{
|
|
1003
1008
|
* url: URL;
|
|
@@ -1175,7 +1180,9 @@ export function create_client({ target, base }) {
|
|
|
1175
1180
|
(entries) => {
|
|
1176
1181
|
for (const entry of entries) {
|
|
1177
1182
|
if (entry.isIntersecting) {
|
|
1178
|
-
preload_code(
|
|
1183
|
+
preload_code(
|
|
1184
|
+
get_url_path(new URL(/** @type {HTMLAnchorElement} */ (entry.target).href))
|
|
1185
|
+
);
|
|
1179
1186
|
observer.unobserve(entry.target);
|
|
1180
1187
|
}
|
|
1181
1188
|
}
|
|
@@ -1200,7 +1207,7 @@ export function create_client({ target, base }) {
|
|
|
1200
1207
|
if (priority <= options.preload_data) {
|
|
1201
1208
|
preload_data(/** @type {URL} */ (url));
|
|
1202
1209
|
} else if (priority <= options.preload_code) {
|
|
1203
|
-
preload_code(/** @type {URL} */ (url)
|
|
1210
|
+
preload_code(get_url_path(/** @type {URL} */ (url)));
|
|
1204
1211
|
}
|
|
1205
1212
|
}
|
|
1206
1213
|
}
|
|
@@ -1220,7 +1227,7 @@ export function create_client({ target, base }) {
|
|
|
1220
1227
|
}
|
|
1221
1228
|
|
|
1222
1229
|
if (options.preload_code === PRELOAD_PRIORITIES.eager) {
|
|
1223
|
-
preload_code(/** @type {URL} */ (url)
|
|
1230
|
+
preload_code(get_url_path(/** @type {URL} */ (url)));
|
|
1224
1231
|
}
|
|
1225
1232
|
}
|
|
1226
1233
|
}
|
|
@@ -3,7 +3,7 @@ import { exec, parse_route_id } from '../../utils/routing.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* @param {import('types').CSRPageNodeLoader[]} nodes
|
|
5
5
|
* @param {number[]} server_loads
|
|
6
|
-
* @param {typeof import('
|
|
6
|
+
* @param {typeof import('__CLIENT__/manifest.js').dictionary} dictionary
|
|
7
7
|
* @param {Record<string, (param: string) => boolean>} matchers
|
|
8
8
|
* @returns {import('types').CSRRoute[]}
|
|
9
9
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { respond } from './respond.js';
|
|
2
2
|
import { set_private_env, set_public_env } from '../shared.js';
|
|
3
|
-
import { options, get_hooks } from '
|
|
3
|
+
import { options, get_hooks } from '__SERVER__/internal.js';
|
|
4
4
|
|
|
5
5
|
export class Server {
|
|
6
6
|
/** @type {import('types').SSROptions} */
|
package/src/utils/filesystem.js
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import child_process from 'node:child_process';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Runs a task in a subprocess so any dangling stuff gets killed upon completion.
|
|
6
|
+
* The subprocess needs to be the file `forked` is called in, and `forked` needs to be called eagerly at the top level.
|
|
7
|
+
* @template T
|
|
8
|
+
* @template U
|
|
9
|
+
* @param {string} module `import.meta.url` of the file
|
|
10
|
+
* @param {(opts: T) => U} callback The function that is invoked in the subprocess
|
|
11
|
+
* @returns {(opts: T) => Promise<U>} A function that when called starts the subprocess
|
|
12
|
+
*/
|
|
13
|
+
export function forked(module, callback) {
|
|
14
|
+
if (process.env.SVELTEKIT_FORK && process.send) {
|
|
15
|
+
process.send({ type: 'ready', module });
|
|
16
|
+
|
|
17
|
+
process.on(
|
|
18
|
+
'message',
|
|
19
|
+
/** @param {any} data */ async (data) => {
|
|
20
|
+
if (data?.type === 'args' && data.module === module) {
|
|
21
|
+
if (process.send) {
|
|
22
|
+
process.send({
|
|
23
|
+
type: 'result',
|
|
24
|
+
module,
|
|
25
|
+
payload: await callback(data.payload)
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {T} opts
|
|
35
|
+
* @returns {Promise<U>}
|
|
36
|
+
*/
|
|
37
|
+
const fn = function (opts) {
|
|
38
|
+
return new Promise((fulfil, reject) => {
|
|
39
|
+
const child = child_process.fork(fileURLToPath(module), {
|
|
40
|
+
stdio: 'inherit',
|
|
41
|
+
env: {
|
|
42
|
+
SVELTEKIT_FORK: 'true'
|
|
43
|
+
},
|
|
44
|
+
serialization: 'advanced'
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
child.on(
|
|
48
|
+
'message',
|
|
49
|
+
/** @param {any} data */ (data) => {
|
|
50
|
+
if (data?.type === 'ready' && data.module === module) {
|
|
51
|
+
child.send({
|
|
52
|
+
type: 'args',
|
|
53
|
+
module,
|
|
54
|
+
payload: opts
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (data?.type === 'result' && data.module === module) {
|
|
59
|
+
child.kill();
|
|
60
|
+
fulfil(data.payload);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
child.on('exit', (code) => {
|
|
66
|
+
if (code) {
|
|
67
|
+
reject(new Error(`Failed with code ${code}`));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return fn;
|
|
74
|
+
}
|
package/types/index.d.ts
CHANGED
|
@@ -1087,7 +1087,8 @@ export type ActionResult<
|
|
|
1087
1087
|
/**
|
|
1088
1088
|
* Creates an `HttpError` object with an HTTP status code and an optional message.
|
|
1089
1089
|
* This object, if thrown during request handling, will cause SvelteKit to
|
|
1090
|
-
* return an error response without invoking `handleError
|
|
1090
|
+
* return an error response without invoking `handleError`.
|
|
1091
|
+
* Make sure you're not catching the thrown error, which results in a noop.
|
|
1091
1092
|
* @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#client_error_responses). Must be in the range 400-599.
|
|
1092
1093
|
* @param body An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
|
|
1093
1094
|
*/
|
|
@@ -1110,6 +1111,7 @@ export interface HttpError {
|
|
|
1110
1111
|
|
|
1111
1112
|
/**
|
|
1112
1113
|
* Create a `Redirect` object. If thrown during request handling, SvelteKit will return a redirect response.
|
|
1114
|
+
* Make sure you're not catching the thrown redirect, which results in a noop.
|
|
1113
1115
|
* @param status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
|
|
1114
1116
|
* @param location The location to redirect to.
|
|
1115
1117
|
*/
|