@sveltejs/kit 3.0.0-next.11 → 3.0.0-next.12
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/cli.js +8 -8
- package/src/constants.js +1 -1
- package/src/core/config/options.js +43 -35
- package/src/core/env.js +25 -11
- package/src/core/sync/sync.js +11 -14
- package/src/core/sync/utils.js +21 -1
- package/src/core/sync/{write_non_ambient.js → write_app_types.js} +23 -21
- package/src/core/sync/write_client_manifest.js +4 -12
- package/src/core/sync/write_env.js +6 -4
- package/src/core/sync/write_server.js +10 -15
- package/src/core/sync/write_tsconfig/index.js +245 -0
- package/src/core/sync/write_tsconfig/utils.js +162 -0
- package/src/core/sync/write_types/index.js +80 -88
- package/src/exports/internal/server/index.js +3 -1
- package/src/exports/public.d.ts +28 -51
- package/src/exports/vite/dev/index.js +88 -76
- package/src/exports/vite/index.js +364 -144
- package/src/exports/vite/module_ids.js +3 -1
- package/src/exports/vite/utils.js +1 -10
- package/src/runner.js +13 -0
- package/src/runtime/app/forms.js +4 -0
- package/src/runtime/app/manifest/index.js +1 -0
- package/src/runtime/app/paths/client.js +30 -30
- package/src/runtime/app/paths/internal/client.js +26 -0
- package/src/runtime/app/paths/server.js +22 -9
- package/src/runtime/app/paths/types.d.ts +11 -19
- package/src/runtime/app/server/remote/command.js +12 -7
- package/src/runtime/app/server/remote/form.js +29 -26
- package/src/runtime/app/server/remote/prerender.js +9 -2
- package/src/runtime/app/server/remote/query.js +5 -4
- package/src/runtime/app/server/remote/shared.js +48 -30
- package/src/runtime/app/service-worker/index.js +24 -0
- package/src/runtime/app/state/index.js +1 -1
- package/src/runtime/client/client.js +46 -9
- package/src/runtime/client/remote-functions/form.svelte.js +43 -51
- package/src/runtime/client/remote-functions/query/index.js +2 -2
- package/src/runtime/client/remote-functions/query-batch.svelte.js +2 -3
- package/src/runtime/client/remote-functions/query-live/iterator.js +5 -2
- package/src/runtime/client/remote-functions/shared.svelte.js +4 -1
- package/src/runtime/client/state.svelte.js +54 -21
- package/src/runtime/form-utils.js +89 -54
- package/src/runtime/server/cookie.js +1 -1
- package/src/runtime/server/data/index.js +31 -28
- package/src/runtime/server/errors.js +1 -1
- package/src/runtime/server/page/actions.js +3 -3
- package/src/runtime/server/page/render.js +19 -28
- package/src/runtime/server/remote-functions.js +66 -35
- package/src/runtime/server/respond.js +56 -14
- package/src/runtime/server/utils.js +10 -0
- package/src/types/ambient-private.d.ts +8 -0
- package/src/types/ambient.d.ts +22 -27
- package/src/types/global-private.d.ts +12 -0
- package/src/types/internal.d.ts +13 -3
- package/src/utils/url.js +12 -0
- package/src/version.js +1 -1
- package/types/index.d.ts +80 -98
- package/types/index.d.ts.map +4 -1
- package/src/core/sync/write_ambient.js +0 -18
- package/src/core/sync/write_tsconfig.js +0 -258
- /package/src/core/sync/{write_tsconfig_test → write_tsconfig/test-app}/package.json +0 -0
package/src/exports/public.d.ts
CHANGED
|
@@ -288,7 +288,7 @@ export interface Cookies {
|
|
|
288
288
|
/**
|
|
289
289
|
* Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request.
|
|
290
290
|
*
|
|
291
|
-
* The `httpOnly`
|
|
291
|
+
* The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
|
|
292
292
|
*
|
|
293
293
|
* The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
|
|
294
294
|
* @param name the name of the cookie
|
|
@@ -300,7 +300,7 @@ export interface Cookies {
|
|
|
300
300
|
/**
|
|
301
301
|
* Deletes a cookie by setting its value to an empty string and setting the expiry date in the past.
|
|
302
302
|
*
|
|
303
|
-
* The `httpOnly`
|
|
303
|
+
* The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
|
|
304
304
|
*
|
|
305
305
|
* The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
|
|
306
306
|
* @param name the name of the cookie
|
|
@@ -335,7 +335,7 @@ export interface Cookies {
|
|
|
335
335
|
/**
|
|
336
336
|
* Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response.
|
|
337
337
|
*
|
|
338
|
-
* The `httpOnly`
|
|
338
|
+
* The `httpOnly` is `true` by default, as is `secure`, except during development, when it defaults to `false`. These must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP.
|
|
339
339
|
*
|
|
340
340
|
* The `path` option is `'/'` by default. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children.
|
|
341
341
|
* @param name the name of the cookie
|
|
@@ -365,32 +365,10 @@ export interface KitConfig {
|
|
|
365
365
|
/**
|
|
366
366
|
* An object containing zero or more aliases used to replace values in `import` statements. These aliases are automatically passed to Vite and TypeScript.
|
|
367
367
|
*
|
|
368
|
-
*
|
|
369
|
-
* /// file: vite.config.js
|
|
370
|
-
* import { defineConfig } from 'vite';
|
|
371
|
-
* import { sveltekit } from '@sveltejs/kit/vite';
|
|
372
|
-
*
|
|
373
|
-
* export default defineConfig({
|
|
374
|
-
* plugins: [
|
|
375
|
-
* sveltekit({
|
|
376
|
-
* alias: {
|
|
377
|
-
* // this will match a file
|
|
378
|
-
* 'my-file': 'path/to/my-file.js',
|
|
379
|
-
*
|
|
380
|
-
* // this will match a directory and its contents
|
|
381
|
-
* // (`my-directory/x` resolves to `path/to/my-directory/x`)
|
|
382
|
-
* 'my-directory': 'path/to/my-directory',
|
|
383
|
-
*
|
|
384
|
-
* // an alias ending /* will only match
|
|
385
|
-
* // the contents of a directory, not the directory itself
|
|
386
|
-
* 'my-directory/*': 'path/to/my-directory/*'
|
|
387
|
-
* }
|
|
388
|
-
* })
|
|
389
|
-
* ]
|
|
390
|
-
* });
|
|
391
|
-
* ```
|
|
368
|
+
* This option is deprecated. Use [subpath imports](https://svelte.dev/docs/kit/$lib) instead.
|
|
392
369
|
*
|
|
393
370
|
* > [!NOTE] You will need to run `npm run dev` to have SvelteKit automatically generate the required alias configuration in `jsconfig.json` or `tsconfig.json`.
|
|
371
|
+
* @deprecated
|
|
394
372
|
* @default {}
|
|
395
373
|
*/
|
|
396
374
|
alias?: Record<string, string>;
|
|
@@ -846,13 +824,7 @@ export interface KitConfig {
|
|
|
846
824
|
*/
|
|
847
825
|
resolution?: 'client' | 'server';
|
|
848
826
|
};
|
|
849
|
-
serviceWorker?:
|
|
850
|
-
/**
|
|
851
|
-
* Determine which files in your `static` directory will be available in `$service-worker.files`.
|
|
852
|
-
* @default (filename) => !/\.DS_Store/.test(filename)
|
|
853
|
-
*/
|
|
854
|
-
files?: (file: string) => boolean;
|
|
855
|
-
} & (
|
|
827
|
+
serviceWorker?:
|
|
856
828
|
| {
|
|
857
829
|
/**
|
|
858
830
|
* Whether to automatically register the service worker, if it exists.
|
|
@@ -870,8 +842,7 @@ export interface KitConfig {
|
|
|
870
842
|
* @default true
|
|
871
843
|
*/
|
|
872
844
|
register?: false;
|
|
873
|
-
}
|
|
874
|
-
);
|
|
845
|
+
};
|
|
875
846
|
/**
|
|
876
847
|
* Options for enabling [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations.
|
|
877
848
|
* @default { server: false }
|
|
@@ -883,6 +854,9 @@ export interface KitConfig {
|
|
|
883
854
|
*/
|
|
884
855
|
server?: boolean;
|
|
885
856
|
};
|
|
857
|
+
/**
|
|
858
|
+
* @deprecated Add configuration to `tsconfig.json` directly
|
|
859
|
+
*/
|
|
886
860
|
typescript?: {
|
|
887
861
|
/**
|
|
888
862
|
* A function that allows you to edit the generated `tsconfig.json`. You can mutate the config (recommended) or return a new one.
|
|
@@ -897,9 +871,9 @@ export interface KitConfig {
|
|
|
897
871
|
};
|
|
898
872
|
/**
|
|
899
873
|
* Client-side navigation can be buggy if you deploy a new version of your app while people are using it. If the code for the new page is already loaded, it may have stale content; if it isn't, the app's route manifest may point to a JavaScript file that no longer exists.
|
|
900
|
-
* SvelteKit helps you solve this problem through version management.
|
|
874
|
+
* SvelteKit helps you solve this problem through version management. The current version is included in data, remote, and form action responses via the `x-sveltekit-version` header, so SvelteKit can detect new deployments without polling — for example when a navigation triggers a server `load` function, or when a remote function is called. SvelteKit also checks for new versions when the tab regains focus or becomes visible.
|
|
901
875
|
* If SvelteKit encounters an error while loading the page and detects that a new version has been deployed (using the `name` specified here, which defaults to a timestamp of the build) it will fall back to traditional full-page navigation.
|
|
902
|
-
* Not all navigations will result in an error though, for example if the JavaScript for the next page is already loaded. If you still want to force a full-page navigation in these cases, use
|
|
876
|
+
* Not all navigations will result in an error though, for example if the JavaScript for the next page is already loaded. If you still want to force a full-page navigation in these cases, use `beforeNavigate`:
|
|
903
877
|
* ```html
|
|
904
878
|
* /// file: +layout.svelte
|
|
905
879
|
* <script>
|
|
@@ -914,7 +888,7 @@ export interface KitConfig {
|
|
|
914
888
|
* </script>
|
|
915
889
|
* ```
|
|
916
890
|
*
|
|
917
|
-
*
|
|
891
|
+
* In addition to these checks, SvelteKit polls for new versions on an interval and sets [`updated.current`](https://svelte.dev/docs/kit/$app-state#updated) to `true` when it detects one. Set `pollInterval` to `0` to disable polling (the header- and event-based checks will still run).
|
|
918
892
|
*/
|
|
919
893
|
version?: {
|
|
920
894
|
/**
|
|
@@ -941,8 +915,8 @@ export interface KitConfig {
|
|
|
941
915
|
*/
|
|
942
916
|
name?: string;
|
|
943
917
|
/**
|
|
944
|
-
* The interval in milliseconds to poll for version changes. If this is `0`, no polling occurs.
|
|
945
|
-
* @default
|
|
918
|
+
* The interval in milliseconds to poll for version changes. If this is `0`, no polling occurs. SvelteKit also checks for new versions on server responses (via the `x-sveltekit-version` header) and when the tab regains focus or becomes visible, so polling is only needed for long-lived sessions on a single page.
|
|
919
|
+
* @default 3600000
|
|
946
920
|
*/
|
|
947
921
|
pollInterval?: number;
|
|
948
922
|
};
|
|
@@ -1615,9 +1589,10 @@ export interface RequestEvent<
|
|
|
1615
1589
|
/**
|
|
1616
1590
|
* The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object.
|
|
1617
1591
|
*
|
|
1618
|
-
*
|
|
1619
|
-
*
|
|
1620
|
-
*
|
|
1592
|
+
* Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
|
|
1593
|
+
* Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
|
|
1594
|
+
* the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
|
|
1595
|
+
* to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1621
1596
|
*/
|
|
1622
1597
|
params: Params;
|
|
1623
1598
|
/**
|
|
@@ -1635,9 +1610,10 @@ export interface RequestEvent<
|
|
|
1635
1610
|
/**
|
|
1636
1611
|
* The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched.
|
|
1637
1612
|
*
|
|
1638
|
-
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1613
|
+
* Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
|
|
1614
|
+
* Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
|
|
1615
|
+
* the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
|
|
1616
|
+
* to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1641
1617
|
*/
|
|
1642
1618
|
id: RouteId;
|
|
1643
1619
|
};
|
|
@@ -1667,9 +1643,10 @@ export interface RequestEvent<
|
|
|
1667
1643
|
/**
|
|
1668
1644
|
* The requested URL.
|
|
1669
1645
|
*
|
|
1670
|
-
*
|
|
1671
|
-
*
|
|
1672
|
-
*
|
|
1646
|
+
* Inside `query` functions (including `query.batch` and `query.live`), accessing this property throws an error.
|
|
1647
|
+
* Pass values from the page as arguments to the query instead. Inside `form` and `command` functions it relates to the page
|
|
1648
|
+
* the remote function was called from, _not_ the URL of the endpoint SvelteKit creates for the remote function. Never use it
|
|
1649
|
+
* to determine whether or not a user is authorized to access certain data, as these values are part of the request which could be manipulated.
|
|
1673
1650
|
*/
|
|
1674
1651
|
url: URL;
|
|
1675
1652
|
/**
|
|
@@ -2107,7 +2084,7 @@ type AsArgs<Type extends keyof InputTypeMap, Value> = Type extends 'checkbox'
|
|
|
2107
2084
|
? [type: Type, value: Value | (string & {})]
|
|
2108
2085
|
: Type extends 'file' | 'file multiple'
|
|
2109
2086
|
? [type: Type]
|
|
2110
|
-
: [type: Type] | [type: Type, value: Value |
|
|
2087
|
+
: [type: Type] | [type: Type, value: Value | undefined];
|
|
2111
2088
|
|
|
2112
2089
|
/**
|
|
2113
2090
|
* Form field accessor type that provides name(), value(), and issues() methods
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
import { SCHEME } from '../../../utils/url.js';
|
|
30
30
|
import { check_feature } from '../../../utils/features.js';
|
|
31
31
|
import { escape_html } from '../../../utils/escape.js';
|
|
32
|
+
import { get_runner } from '../../../runner.js';
|
|
32
33
|
|
|
33
34
|
// vite-specifc queries that we should skip handling for css urls
|
|
34
35
|
const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
|
|
@@ -39,9 +40,10 @@ const vite_css_query_regex = /(?:\?|&)(?:raw|url|inline)(?:&|$)/;
|
|
|
39
40
|
* @param {import('types').ValidatedConfig} svelte_config
|
|
40
41
|
* @param {() => Array<{ hash: string, file: string }>} get_remotes
|
|
41
42
|
* @param {string} root The project root directory
|
|
43
|
+
* @param {(manifest_data: import('types').ManifestData) => void} set_manifest_data
|
|
42
44
|
* @return {Promise<Promise<() => void>>}
|
|
43
45
|
*/
|
|
44
|
-
export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
46
|
+
export async function dev(vite, vite_config, svelte_config, get_remotes, root, set_manifest_data) {
|
|
45
47
|
/** @type {AsyncLocalStorage<{ event: RequestEvent, config: any, prerender: PrerenderOption }>} */
|
|
46
48
|
const async_local_storage = new AsyncLocalStorage();
|
|
47
49
|
|
|
@@ -78,10 +80,15 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
78
80
|
/** @type {Error | null} */
|
|
79
81
|
let manifest_error = null;
|
|
80
82
|
|
|
81
|
-
|
|
83
|
+
const runner = get_runner(vite);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {string} url
|
|
87
|
+
* @returns {Promise<Record<string, any>>}
|
|
88
|
+
*/
|
|
82
89
|
async function loud_ssr_load_module(url) {
|
|
83
90
|
try {
|
|
84
|
-
return await
|
|
91
|
+
return await runner.import(url);
|
|
85
92
|
} catch (/** @type {any} */ err) {
|
|
86
93
|
const msg = buildErrorMessage(err, [
|
|
87
94
|
styleText('red', `Internal server error: ${err.message}`)
|
|
@@ -92,10 +99,10 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
92
99
|
}
|
|
93
100
|
|
|
94
101
|
// TODO this is inadequate — it doesn't reliably show the overlay on every page load,
|
|
95
|
-
// and when it does appear it may immediately vanish. `vite.
|
|
102
|
+
// and when it does appear it may immediately vanish. `vite.hot.send` broadcasts
|
|
96
103
|
// to all connected clients, even ones that are unaffected by the error.
|
|
97
104
|
// we need a more considered approach
|
|
98
|
-
vite.
|
|
105
|
+
vite.hot.send({
|
|
99
106
|
type: 'error',
|
|
100
107
|
err: /** @type {import('vite').ErrorPayload['err']} */ ({
|
|
101
108
|
...err,
|
|
@@ -116,7 +123,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
116
123
|
|
|
117
124
|
const module = await loud_ssr_load_module(url);
|
|
118
125
|
|
|
119
|
-
const module_node = await vite.moduleGraph.getModuleByUrl(url);
|
|
126
|
+
const module_node = await vite.environments.ssr.moduleGraph.getModuleByUrl(url);
|
|
120
127
|
if (!module_node) throw new Error(`Could not find node for ${url}`);
|
|
121
128
|
|
|
122
129
|
return { module, module_node, url };
|
|
@@ -125,6 +132,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
125
132
|
async function update_manifest() {
|
|
126
133
|
try {
|
|
127
134
|
({ manifest_data } = sync.create(svelte_config, root));
|
|
135
|
+
set_manifest_data(manifest_data);
|
|
128
136
|
|
|
129
137
|
await load_and_validate_params({
|
|
130
138
|
routes: manifest_data.routes,
|
|
@@ -135,13 +143,13 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
135
143
|
|
|
136
144
|
if (manifest_error) {
|
|
137
145
|
manifest_error = null;
|
|
138
|
-
vite.
|
|
146
|
+
vite.hot.send({ type: 'full-reload' });
|
|
139
147
|
}
|
|
140
148
|
} catch (error) {
|
|
141
149
|
manifest_error = /** @type {Error} */ (error);
|
|
142
150
|
|
|
143
151
|
console.error(styleText(['bold', 'red'], manifest_error.message));
|
|
144
|
-
vite.
|
|
152
|
+
vite.hot.send({
|
|
145
153
|
type: 'error',
|
|
146
154
|
err: {
|
|
147
155
|
message: manifest_error.message ?? 'Invalid routes',
|
|
@@ -214,7 +222,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
214
222
|
result.stylesheets = [];
|
|
215
223
|
result.fonts = [];
|
|
216
224
|
|
|
217
|
-
/** @type {import('vite').
|
|
225
|
+
/** @type {import('vite').EnvironmentModuleNode[]} */
|
|
218
226
|
const module_nodes = [];
|
|
219
227
|
|
|
220
228
|
if (node.component) {
|
|
@@ -248,7 +256,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
248
256
|
// in dev we inline all styles to avoid FOUC. this gets populated lazily so that
|
|
249
257
|
// components/stylesheets loaded via import() during `load` are included
|
|
250
258
|
result.inline_styles = async () => {
|
|
251
|
-
/** @type {Set<import('vite').
|
|
259
|
+
/** @type {Set<import('vite').EnvironmentModuleNode>} */
|
|
252
260
|
const deps = new Set();
|
|
253
261
|
|
|
254
262
|
for (const module_node of module_nodes) {
|
|
@@ -264,7 +272,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
264
272
|
? dep.url.replace('?', '?inline&')
|
|
265
273
|
: dep.url + '?inline';
|
|
266
274
|
try {
|
|
267
|
-
const mod = await
|
|
275
|
+
const mod = await runner.import(inlineCssUrl);
|
|
268
276
|
styles[dep.url] = mod.default;
|
|
269
277
|
} catch {
|
|
270
278
|
// this can happen with dynamically imported modules, I think
|
|
@@ -285,7 +293,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
285
293
|
return Object.fromEntries(
|
|
286
294
|
get_remotes().map((remote) => [
|
|
287
295
|
remote.hash,
|
|
288
|
-
() =>
|
|
296
|
+
() => runner.import(remote.file).then((module) => ({ default: module }))
|
|
289
297
|
])
|
|
290
298
|
);
|
|
291
299
|
},
|
|
@@ -314,7 +322,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
314
322
|
if (!manifest_data.params) return {};
|
|
315
323
|
|
|
316
324
|
const url = path.resolve(root, manifest_data.params);
|
|
317
|
-
const module = await
|
|
325
|
+
const module = await runner.import(url);
|
|
318
326
|
|
|
319
327
|
if (!module.params) {
|
|
320
328
|
throw new Error(
|
|
@@ -334,48 +342,37 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
334
342
|
return;
|
|
335
343
|
}
|
|
336
344
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
//
|
|
341
|
-
|
|
342
|
-
|
|
345
|
+
let end = 0;
|
|
346
|
+
|
|
347
|
+
error.stack = error.stack
|
|
348
|
+
.replaceAll('\0', '') // remove null bytes from e.g. virtual module IDs, or the response will fail
|
|
349
|
+
.split('\n')
|
|
350
|
+
.map((line, i) => {
|
|
351
|
+
const match = /^ {4}at (?:[^ ]+ \((.+)\)|(.+))$/.exec(line);
|
|
352
|
+
if (!match) {
|
|
353
|
+
end = i + 1;
|
|
354
|
+
return line;
|
|
355
|
+
}
|
|
343
356
|
|
|
344
|
-
|
|
345
|
-
|
|
357
|
+
const loc = match[1] ?? match[2];
|
|
358
|
+
const file = loc.replace(/:\d+:\d+$/, '');
|
|
346
359
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
.split('\n')
|
|
350
|
-
.map((line, i) => {
|
|
351
|
-
const match = /^ {4}at (?:[^ ]+ \((.+)\)|(.+))$/.exec(line);
|
|
352
|
-
if (!match) {
|
|
360
|
+
if (fs.existsSync(file)) {
|
|
361
|
+
if (!file.includes('node_modules') && !file.includes(SRC_ROOT)) {
|
|
353
362
|
end = i + 1;
|
|
354
|
-
return line;
|
|
355
363
|
}
|
|
356
364
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (fs.existsSync(file)) {
|
|
361
|
-
if (!file.includes('node_modules') && !file.includes(SRC_ROOT)) {
|
|
362
|
-
end = i + 1;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return line.replace(file, path.posix.relative(process.cwd(), file));
|
|
366
|
-
}
|
|
365
|
+
return line.replace(file, path.relative(process.cwd(), file));
|
|
366
|
+
}
|
|
367
367
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
368
|
+
return line;
|
|
369
|
+
})
|
|
370
|
+
.slice(0, end)
|
|
371
|
+
.join('\n');
|
|
372
372
|
|
|
373
|
-
|
|
374
|
-
}
|
|
373
|
+
return error.stack;
|
|
375
374
|
}
|
|
376
375
|
|
|
377
|
-
await update_manifest();
|
|
378
|
-
|
|
379
376
|
const params_file = resolve_entry(svelte_config.kit.files.params);
|
|
380
377
|
|
|
381
378
|
/**
|
|
@@ -386,6 +383,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
386
383
|
vite.watcher.on(event, (file) => {
|
|
387
384
|
if (
|
|
388
385
|
file.startsWith(svelte_config.kit.files.routes + path.sep) ||
|
|
386
|
+
file.startsWith(svelte_config.kit.files.assets + path.sep) ||
|
|
389
387
|
(params_file && file === params_file) ||
|
|
390
388
|
remote_module_pattern.test(file) ||
|
|
391
389
|
// in contrast to server hooks, client hooks are written to the client manifest
|
|
@@ -413,6 +411,11 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
413
411
|
watch('add', () => debounce(update_manifest));
|
|
414
412
|
watch('unlink', () => debounce(update_manifest));
|
|
415
413
|
watch('change', (file) => {
|
|
414
|
+
// `manifest_data` is populated lazily on the first request (see `update_manifest`
|
|
415
|
+
// call in the middleware below), so it may still be undefined if a file changes
|
|
416
|
+
// before the dev server has served a request. In that case there's nothing to
|
|
417
|
+
// update — the manifest will be created from scratch on the first request.
|
|
418
|
+
if (!manifest_data) return;
|
|
416
419
|
// Don't run for a single file if the whole manifest is about to get updated
|
|
417
420
|
// Unless it's a file where the trailing slash page option might have changed
|
|
418
421
|
if (timeout || !/\+(page|layout|server).*$/.test(file)) return;
|
|
@@ -427,7 +430,7 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
427
430
|
if (appTemplate !== 'index.html') {
|
|
428
431
|
vite.watcher.on('change', (file) => {
|
|
429
432
|
if (file === appTemplate) {
|
|
430
|
-
vite.
|
|
433
|
+
vite.hot.send({ type: 'full-reload' });
|
|
431
434
|
}
|
|
432
435
|
});
|
|
433
436
|
}
|
|
@@ -477,6 +480,9 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
477
480
|
const env = loadEnv(vite_config.mode, svelte_config.kit.env.dir, '');
|
|
478
481
|
const emulator = await svelte_config.kit.adapter?.emulate?.();
|
|
479
482
|
|
|
483
|
+
/** @type {Promise<void> | undefined} */
|
|
484
|
+
let init_manifest;
|
|
485
|
+
|
|
480
486
|
return () => {
|
|
481
487
|
const serve_static_middleware = vite.middlewares.stack.find(
|
|
482
488
|
(middleware) =>
|
|
@@ -488,6 +494,11 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
488
494
|
remove_static_middlewares(vite.middlewares);
|
|
489
495
|
|
|
490
496
|
vite.middlewares.use(async (req, res) => {
|
|
497
|
+
// Vite throws a Cannot read properties of undefined (reading 'wrapDynamicImport')
|
|
498
|
+
// if you try to run ssr.runner.import before the server has started so
|
|
499
|
+
// we do it inside here to avoid that
|
|
500
|
+
await (init_manifest ??= update_manifest());
|
|
501
|
+
|
|
491
502
|
// Vite's base middleware strips out the base path. Restore it
|
|
492
503
|
const original_url = req.url;
|
|
493
504
|
req.url = req.originalUrl;
|
|
@@ -541,22 +552,20 @@ export async function dev(vite, vite_config, svelte_config, get_remotes, root) {
|
|
|
541
552
|
);
|
|
542
553
|
|
|
543
554
|
if (resolved_instrumentation) {
|
|
544
|
-
await
|
|
555
|
+
await runner.import(resolved_instrumentation);
|
|
545
556
|
}
|
|
546
557
|
|
|
547
558
|
// we have to import `Server` before calling `set_assets`
|
|
548
559
|
const { Server } = /** @type {import('types').ServerModule} */ (
|
|
549
|
-
await
|
|
550
|
-
fixStacktrace: true
|
|
551
|
-
})
|
|
560
|
+
await runner.import(`${get_runtime_base(root)}/server/index.js`)
|
|
552
561
|
);
|
|
553
562
|
|
|
554
|
-
const { set_fix_stack_trace } = await
|
|
563
|
+
const { set_fix_stack_trace } = await runner.import(
|
|
555
564
|
`${get_runtime_base(root)}/server/internal.js`
|
|
556
565
|
);
|
|
557
566
|
set_fix_stack_trace(fix_stack_trace);
|
|
558
567
|
|
|
559
|
-
const { set_assets } = await
|
|
568
|
+
const { set_assets } = await runner.import('$app/paths/internal/server');
|
|
560
569
|
set_assets(assets);
|
|
561
570
|
|
|
562
571
|
const server = new Server(manifest);
|
|
@@ -649,16 +658,16 @@ function remove_static_middlewares(server) {
|
|
|
649
658
|
|
|
650
659
|
/**
|
|
651
660
|
* @param {import('vite').ViteDevServer} vite
|
|
652
|
-
* @param {import('vite').
|
|
653
|
-
* @param {Set<import('vite').
|
|
661
|
+
* @param {import('vite').EnvironmentModuleNode} node
|
|
662
|
+
* @param {Set<import('vite').EnvironmentModuleNode>} deps
|
|
654
663
|
*/
|
|
655
664
|
async function find_deps(vite, node, deps) {
|
|
656
|
-
// since `
|
|
665
|
+
// since `transformResult.deps` contains URLs instead of `ModuleNode`s, this process is asynchronous.
|
|
657
666
|
// instead of using `await`, we resolve all branches in parallel.
|
|
658
667
|
/** @type {Promise<void>[]} */
|
|
659
668
|
const branches = [];
|
|
660
669
|
|
|
661
|
-
/** @param {import('vite').
|
|
670
|
+
/** @param {import('vite').EnvironmentModuleNode} node */
|
|
662
671
|
async function add(node) {
|
|
663
672
|
if (!deps.has(node)) {
|
|
664
673
|
deps.add(node);
|
|
@@ -668,23 +677,20 @@ async function find_deps(vite, node, deps) {
|
|
|
668
677
|
|
|
669
678
|
/** @param {string} url */
|
|
670
679
|
async function add_by_url(url) {
|
|
671
|
-
const node = await
|
|
680
|
+
const node = await vite.environments.ssr.moduleGraph.getModuleByUrl(url);
|
|
672
681
|
|
|
673
682
|
if (node) {
|
|
674
683
|
await add(node);
|
|
675
684
|
}
|
|
676
685
|
}
|
|
677
686
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
if (transform_result) {
|
|
682
|
-
if (transform_result.deps) {
|
|
683
|
-
transform_result.deps.forEach((url) => branches.push(add_by_url(url)));
|
|
687
|
+
if (node.transformResult) {
|
|
688
|
+
if (node.transformResult.deps) {
|
|
689
|
+
node.transformResult.deps.forEach((url) => branches.push(add_by_url(url)));
|
|
684
690
|
}
|
|
685
691
|
|
|
686
|
-
if (
|
|
687
|
-
|
|
692
|
+
if (node.transformResult.dynamicDeps) {
|
|
693
|
+
node.transformResult.dynamicDeps.forEach((url) => branches.push(add_by_url(url)));
|
|
688
694
|
}
|
|
689
695
|
} else {
|
|
690
696
|
node.importedModules.forEach((node) => branches.push(add(node)));
|
|
@@ -693,16 +699,6 @@ async function find_deps(vite, node, deps) {
|
|
|
693
699
|
await Promise.all(branches);
|
|
694
700
|
}
|
|
695
701
|
|
|
696
|
-
/**
|
|
697
|
-
* @param {import('vite').ViteDevServer} vite
|
|
698
|
-
* @param {string} url
|
|
699
|
-
*/
|
|
700
|
-
function get_server_module_by_url(vite, url) {
|
|
701
|
-
return vite.environments
|
|
702
|
-
? vite.environments.ssr.moduleGraph.getModuleByUrl(url)
|
|
703
|
-
: vite.moduleGraph.getModuleByUrl(url, true);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
702
|
/**
|
|
707
703
|
* Determine if a file is being requested with the correct case,
|
|
708
704
|
* to ensure consistent behaviour between dev and prod and across
|
|
@@ -723,3 +719,19 @@ function has_correct_case(file, assets) {
|
|
|
723
719
|
|
|
724
720
|
return false;
|
|
725
721
|
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Invalidates a module in all environments.
|
|
725
|
+
* @param {import('vite').ViteDevServer} server
|
|
726
|
+
* @param {string} id
|
|
727
|
+
* @returns {void}
|
|
728
|
+
*/
|
|
729
|
+
export function invalidate_module(server, id) {
|
|
730
|
+
for (const environment in server.environments) {
|
|
731
|
+
const module = server.environments[environment].moduleGraph.getModuleById(id);
|
|
732
|
+
if (module) {
|
|
733
|
+
server.environments[environment].moduleGraph.invalidateModule(module);
|
|
734
|
+
void server.environments[environment].reloadModule(module);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|