@sveltejs/kit 3.0.0-next.6 → 3.0.0-next.8
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 +8 -3
- package/src/core/adapt/builder.js +11 -39
- package/src/core/config/index.js +76 -71
- package/src/core/config/options.js +280 -285
- package/src/core/config/types.d.ts +1 -1
- package/src/core/env.js +86 -1
- package/src/core/generate_manifest/index.js +12 -15
- package/src/core/sync/create_manifest_data/index.js +7 -45
- package/src/core/sync/sync.js +0 -2
- package/src/core/sync/write_client_manifest.js +7 -21
- package/src/core/sync/write_non_ambient.js +12 -9
- package/src/core/sync/write_server.js +0 -4
- package/src/core/sync/write_types/index.js +28 -24
- package/src/core/utils.js +2 -2
- package/src/exports/index.js +3 -3
- package/src/exports/internal/client.js +5 -0
- package/src/exports/internal/index.js +1 -91
- package/src/exports/internal/{event.js → server/event.js} +1 -2
- package/src/exports/internal/server/index.js +33 -0
- package/src/exports/internal/shared.js +89 -0
- package/src/exports/node/index.js +5 -9
- package/src/exports/params.js +63 -0
- package/src/exports/public.d.ts +103 -46
- package/src/exports/url.js +84 -0
- package/src/exports/vite/dev/index.js +31 -20
- package/src/exports/vite/index.js +280 -199
- package/src/exports/vite/preview/index.js +14 -15
- package/src/exports/vite/utils.js +8 -10
- package/src/runtime/app/env/internal.js +4 -4
- package/src/runtime/app/forms.js +2 -2
- package/src/runtime/app/paths/client.js +3 -7
- package/src/runtime/app/paths/internal/client.js +4 -2
- package/src/runtime/app/paths/internal/server.js +2 -23
- package/src/runtime/app/paths/server.js +3 -3
- package/src/runtime/app/server/remote/query.js +6 -12
- package/src/runtime/app/state/client.js +1 -2
- package/src/runtime/app/stores.js +13 -76
- package/src/runtime/client/bundle.js +1 -1
- package/src/runtime/client/client-entry.js +3 -0
- package/src/runtime/client/client.js +230 -238
- package/src/runtime/client/entry.js +24 -3
- package/src/runtime/client/payload.js +17 -0
- package/src/runtime/client/remote-functions/cache.svelte.js +3 -1
- package/src/runtime/client/remote-functions/form.svelte.js +11 -30
- package/src/runtime/client/remote-functions/prerender.svelte.js +10 -3
- package/src/runtime/client/remote-functions/query/instance.svelte.js +18 -9
- package/src/runtime/client/remote-functions/query-live/instance.svelte.js +16 -6
- package/src/runtime/client/remote-functions/shared.svelte.js +1 -2
- package/src/runtime/client/state.svelte.js +66 -49
- package/src/runtime/client/types.d.ts +3 -7
- package/src/runtime/client/utils.js +0 -96
- package/src/runtime/components/root.svelte +66 -0
- package/src/runtime/form-utils.js +16 -6
- package/src/runtime/server/cookie.js +17 -7
- package/src/runtime/server/index.js +1 -1
- package/src/runtime/server/page/index.js +7 -14
- package/src/runtime/server/page/load_data.js +1 -1
- package/src/runtime/server/page/render.js +72 -88
- package/src/runtime/server/page/server_routing.js +13 -9
- package/src/runtime/server/remote.js +23 -13
- package/src/runtime/server/respond.js +11 -8
- package/src/runtime/server/utils.js +28 -5
- package/src/runtime/telemetry/otel.js +1 -1
- package/src/runtime/types.d.ts +8 -0
- package/src/types/ambient.d.ts +5 -1
- package/src/types/global-private.d.ts +11 -18
- package/src/types/internal.d.ts +25 -30
- package/src/utils/error.js +1 -1
- package/src/utils/import.js +6 -1
- package/src/utils/mime.js +9 -0
- package/src/utils/params.js +66 -0
- package/src/utils/routing.js +90 -44
- package/src/utils/streaming.js +14 -4
- package/src/utils/url.js +0 -79
- package/src/version.js +1 -1
- package/types/index.d.ts +127 -125
- package/types/index.d.ts.map +12 -8
- package/src/core/sync/write_root.js +0 -148
- package/src/exports/internal/server.js +0 -22
- /package/src/exports/internal/{remote-functions.js → server/remote-functions.js} +0 -0
|
@@ -1,3 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/* in development or if `bundleStrategy` is 'split', this file is used as the entry point */
|
|
2
|
+
|
|
3
|
+
import { set_payload } from './payload.js';
|
|
4
|
+
|
|
5
|
+
/** @type {Promise<typeof import('./client-entry.js')>} */
|
|
6
|
+
let client;
|
|
7
|
+
|
|
8
|
+
/** @param {import('types').SvelteKitPayload} payload */
|
|
9
|
+
export function init(payload) {
|
|
10
|
+
set_payload(payload);
|
|
11
|
+
// Importing the client after setting the payload ensures that modules such as
|
|
12
|
+
// `$app/paths` can read it during initialization.
|
|
13
|
+
client ??= import('./client-entry.js');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** @param {Parameters<import('./client-entry.js').start>} args */
|
|
17
|
+
export async function start(...args) {
|
|
18
|
+
return (await client).start(...args);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @param {Parameters<import('./client-entry.js').load_css>} args */
|
|
22
|
+
export async function load_css(...args) {
|
|
23
|
+
return (await client).load_css(...args);
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @import {SvelteKitPayload} from 'types'; */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Code inside the SvelteKit client runtime should only use this, not the global,
|
|
5
|
+
* so that the file hashes stay stable between rebuilds as long as the SvelteKit runtime doesn't change
|
|
6
|
+
*/
|
|
7
|
+
export let payload = __SVELTEKIT_PAYLOAD__ ?? /** @type {SvelteKitPayload} */ ({});
|
|
8
|
+
|
|
9
|
+
/** @param {SvelteKitPayload} value */
|
|
10
|
+
export function set_payload(value) {
|
|
11
|
+
payload = value;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// this makes Vite inject its dev client code as this module's first dependency
|
|
15
|
+
// so that global constant replacements are done before any other module evaluates.
|
|
16
|
+
// For build, it's inert.
|
|
17
|
+
import.meta.hot;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
/** @import { Query } from './query/instance.svelte.js' */
|
|
2
|
+
/** @import { LiveQuery } from './query-live/instance.svelte.js' */
|
|
1
3
|
import { tick } from 'svelte';
|
|
2
4
|
import { once } from '../../../utils/functions.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
|
-
* @template R
|
|
7
|
+
* @template [R=Query<any> | LiveQuery<any>]
|
|
6
8
|
* @typedef {object} CacheEntry
|
|
7
9
|
* @property {number} proxy_count The number of live proxy instances referencing this
|
|
8
10
|
* entry. The entry is eligible for eviction when this hits zero.
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
query_responses,
|
|
9
9
|
_goto,
|
|
10
10
|
set_nearest_error_page,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
handle_error,
|
|
12
|
+
refreshAll
|
|
13
13
|
} from '../client.js';
|
|
14
14
|
import { tick } from 'svelte';
|
|
15
15
|
import { categorize_updates, remote_request } from './shared.svelte.js';
|
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
build_path_string,
|
|
24
24
|
normalize_issue,
|
|
25
25
|
serialize_binary_form,
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
deep_get,
|
|
27
|
+
DELETE_KEY,
|
|
28
|
+
BINARY_FORM_CONTENT_TYPE
|
|
28
29
|
} from '../../form-utils.js';
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -226,14 +227,14 @@ export function form(id) {
|
|
|
226
227
|
|
|
227
228
|
// if the developer took control of updates via `.updates(...)` (even with
|
|
228
229
|
// no arguments), or the server performed explicit refreshes, don't invalidateAll
|
|
229
|
-
const
|
|
230
|
+
const should_refresh = refreshes === null && !response.r;
|
|
230
231
|
|
|
231
232
|
if (response.redirect) {
|
|
232
233
|
// Use internal version to allow redirects to external URLs
|
|
233
234
|
void _goto(
|
|
234
235
|
response.redirect,
|
|
235
236
|
{
|
|
236
|
-
|
|
237
|
+
refreshAll: should_refresh
|
|
237
238
|
},
|
|
238
239
|
0
|
|
239
240
|
);
|
|
@@ -243,8 +244,8 @@ export function form(id) {
|
|
|
243
244
|
const succeeded = raw_issues.length === 0;
|
|
244
245
|
|
|
245
246
|
if (succeeded) {
|
|
246
|
-
if (
|
|
247
|
-
void
|
|
247
|
+
if (should_refresh) {
|
|
248
|
+
void refreshAll();
|
|
248
249
|
}
|
|
249
250
|
} else {
|
|
250
251
|
if (DEV) {
|
|
@@ -514,14 +515,7 @@ export function form(id) {
|
|
|
514
515
|
if (file) {
|
|
515
516
|
set_nested_value(input, name, file);
|
|
516
517
|
} else {
|
|
517
|
-
|
|
518
|
-
const path_parts = name.split(/\.|\[|\]/).filter(Boolean);
|
|
519
|
-
let current = /** @type {any} */ (input);
|
|
520
|
-
for (let i = 0; i < path_parts.length - 1; i++) {
|
|
521
|
-
if (current[path_parts[i]] == null) return;
|
|
522
|
-
current = current[path_parts[i]];
|
|
523
|
-
}
|
|
524
|
-
delete current[path_parts[path_parts.length - 1]];
|
|
518
|
+
set_nested_value(input, name, DELETE_KEY);
|
|
525
519
|
}
|
|
526
520
|
} else {
|
|
527
521
|
set_nested_value(
|
|
@@ -672,12 +666,7 @@ export function form(id) {
|
|
|
672
666
|
},
|
|
673
667
|
validate: {
|
|
674
668
|
/** @type {RemoteForm<any, any>['validate']} */
|
|
675
|
-
value: async ({
|
|
676
|
-
all = false,
|
|
677
|
-
preflightOnly = false,
|
|
678
|
-
// @ts-expect-error TODO remove this in 3.0
|
|
679
|
-
includeUntouched
|
|
680
|
-
} = {}) => {
|
|
669
|
+
value: async ({ all = false, preflightOnly = false } = {}) => {
|
|
681
670
|
if (!element) return;
|
|
682
671
|
|
|
683
672
|
const id = ++validate_id;
|
|
@@ -728,14 +717,6 @@ export function form(id) {
|
|
|
728
717
|
array = /** @type {InternalRemoteFormIssue[]} */ (result._);
|
|
729
718
|
}
|
|
730
719
|
|
|
731
|
-
if (includeUntouched !== undefined) {
|
|
732
|
-
console.warn(
|
|
733
|
-
`\`{ includeUntouched: ${includeUntouched} }\` has been replaced with \`{ all: ${includeUntouched} }\``
|
|
734
|
-
);
|
|
735
|
-
|
|
736
|
-
all = includeUntouched;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
720
|
if (!all && !submitted) {
|
|
740
721
|
array = array.filter((issue) => can_validate[issue.name]);
|
|
741
722
|
}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
import { app_dir, base } from '$app/paths/internal/client';
|
|
3
3
|
import { version } from '$app/env';
|
|
4
4
|
import * as devalue from 'devalue';
|
|
5
|
-
import { app, _goto, prerender_responses } from '../client.js';
|
|
5
|
+
import { app, _goto, handle_error, prerender_responses } from '../client.js';
|
|
6
6
|
import { get_remote_request_headers, remote_request, unwrap_node } from './shared.svelte.js';
|
|
7
7
|
import { create_remote_key, stringify_remote_arg } from '../../shared.js';
|
|
8
8
|
import { noop } from '../../../utils/functions.js';
|
|
9
|
+
import { HttpError } from '@sveltejs/kit/internal';
|
|
9
10
|
|
|
10
11
|
// Initialize Cache API for prerender functions
|
|
11
12
|
const CACHE_NAME = __SVELTEKIT_DEV__ ? `sveltekit:${Date.now()}` : `sveltekit:${version}`;
|
|
@@ -148,6 +149,7 @@ class Prerender {
|
|
|
148
149
|
/** @type {T | undefined} */
|
|
149
150
|
#current = $state.raw();
|
|
150
151
|
|
|
152
|
+
/** @type {App.Error | undefined} */
|
|
151
153
|
#error = $state.raw(undefined);
|
|
152
154
|
|
|
153
155
|
/**
|
|
@@ -162,10 +164,15 @@ class Prerender {
|
|
|
162
164
|
this.#error = undefined;
|
|
163
165
|
return value;
|
|
164
166
|
},
|
|
165
|
-
(
|
|
167
|
+
async (e) => {
|
|
168
|
+
const error = await handle_error(e, {
|
|
169
|
+
params: {},
|
|
170
|
+
route: { id: null },
|
|
171
|
+
url: new URL(location.href)
|
|
172
|
+
});
|
|
166
173
|
this.#loading = false;
|
|
167
174
|
this.#error = error;
|
|
168
|
-
throw error;
|
|
175
|
+
throw new HttpError(error.status, error); // so that transformError doesn't transform it again
|
|
169
176
|
}
|
|
170
177
|
);
|
|
171
178
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { query_responses } from '../../client.js';
|
|
1
|
+
import { query_responses, handle_error } from '../../client.js';
|
|
2
2
|
import { HttpError } from '@sveltejs/kit/internal';
|
|
3
3
|
import { QUERY_OVERRIDE_KEY } from '../shared.svelte.js';
|
|
4
4
|
import { noop } from '../../../../utils/functions.js';
|
|
@@ -37,7 +37,7 @@ export class Query {
|
|
|
37
37
|
return this.#overrides.reduce((v, r) => r(v), /** @type {T} */ (this.#raw));
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
/** @type {
|
|
40
|
+
/** @type {App.Error | undefined} */
|
|
41
41
|
#error = $state.raw(undefined);
|
|
42
42
|
|
|
43
43
|
/** @type {Promise<T>['then']} */
|
|
@@ -126,22 +126,33 @@ export class Query {
|
|
|
126
126
|
|
|
127
127
|
resolve(undefined);
|
|
128
128
|
})
|
|
129
|
-
.catch((e) => {
|
|
129
|
+
.catch(async (e) => {
|
|
130
130
|
// TODO: Our behavior here could be better:
|
|
131
131
|
// - We should not reject on redirects, but should hook into the router
|
|
132
132
|
// to ensure the query is properly refreshed before the navigation completes
|
|
133
133
|
// - Instead of failing on transport-level errors, we should probably do what
|
|
134
134
|
// LiveQuery does and preserve the last known good value and retry the connection
|
|
135
|
+
if (this.#latest.indexOf(resolve) === -1) return;
|
|
136
|
+
|
|
137
|
+
const error = await handle_error(e, {
|
|
138
|
+
params: {},
|
|
139
|
+
route: { id: null },
|
|
140
|
+
url: new URL(location.href)
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Re-check after the async `handle_error` gap: a later request may have
|
|
144
|
+
// resolved/rejected while we were awaiting and superseded this one, so
|
|
145
|
+
// recompute the index and bail out if this request is no longer current
|
|
135
146
|
const idx = this.#latest.indexOf(resolve);
|
|
136
147
|
if (idx === -1) return;
|
|
137
148
|
|
|
138
149
|
untrack(() => {
|
|
139
150
|
this.#latest.splice(0, idx).forEach((r) => r(undefined));
|
|
140
|
-
this.#error =
|
|
151
|
+
this.#error = error;
|
|
141
152
|
this.#loading = false;
|
|
142
153
|
});
|
|
143
154
|
|
|
144
|
-
reject(
|
|
155
|
+
reject(new HttpError(error.status, error)); // so that transformError doesn't transform it again
|
|
145
156
|
});
|
|
146
157
|
|
|
147
158
|
return promise;
|
|
@@ -229,9 +240,7 @@ export class Query {
|
|
|
229
240
|
this.#promise = Promise.resolve();
|
|
230
241
|
}
|
|
231
242
|
|
|
232
|
-
/**
|
|
233
|
-
* @param {unknown} error
|
|
234
|
-
*/
|
|
243
|
+
/** @param {HttpError} error */
|
|
235
244
|
fail(error) {
|
|
236
245
|
// normally consumed in the constructor, but make sure a leftover
|
|
237
246
|
// SSR record can never shadow the newly-set error
|
|
@@ -239,7 +248,7 @@ export class Query {
|
|
|
239
248
|
|
|
240
249
|
this.#clear_pending();
|
|
241
250
|
this.#loading = false;
|
|
242
|
-
this.#error = error;
|
|
251
|
+
this.#error = error.body;
|
|
243
252
|
|
|
244
253
|
const promise = Promise.reject(error);
|
|
245
254
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { query_responses } from '../../client.js';
|
|
1
|
+
import { query_responses, handle_error } from '../../client.js';
|
|
2
2
|
import { HttpError, Redirect } from '@sveltejs/kit/internal';
|
|
3
3
|
import { noop, once } from '../../../../utils/functions.js';
|
|
4
4
|
import { SharedIterator } from '../../../../utils/shared-iterator.js';
|
|
@@ -24,7 +24,7 @@ export class LiveQuery {
|
|
|
24
24
|
#done = $state(false);
|
|
25
25
|
/** @type {T | undefined} */
|
|
26
26
|
#raw = $state.raw();
|
|
27
|
-
/** @type {
|
|
27
|
+
/** @type {App.Error | undefined} */
|
|
28
28
|
#error = $state.raw(undefined);
|
|
29
29
|
/** @type {Promise<void>} */
|
|
30
30
|
#promise;
|
|
@@ -93,7 +93,7 @@ export class LiveQuery {
|
|
|
93
93
|
// and the query can recover
|
|
94
94
|
const error = new HttpError(node.e.status, node.e);
|
|
95
95
|
this.#loading = false;
|
|
96
|
-
this.#error = error;
|
|
96
|
+
this.#error = error.body;
|
|
97
97
|
|
|
98
98
|
promise.catch(noop);
|
|
99
99
|
this.#reject_first?.(error);
|
|
@@ -175,7 +175,7 @@ export class LiveQuery {
|
|
|
175
175
|
|
|
176
176
|
if (!this.#ready) {
|
|
177
177
|
// If we haven't successfully connected and received a value yet, surface the error
|
|
178
|
-
this
|
|
178
|
+
await this.#fail(error);
|
|
179
179
|
on_connect_failed(error);
|
|
180
180
|
break;
|
|
181
181
|
}
|
|
@@ -385,10 +385,10 @@ export class LiveQuery {
|
|
|
385
385
|
this.#fan_out.push(value);
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
/** @param {
|
|
388
|
+
/** @param {HttpError} error */
|
|
389
389
|
fail(error) {
|
|
390
390
|
this.#loading = false;
|
|
391
|
-
this.#error = error;
|
|
391
|
+
this.#error = error.body;
|
|
392
392
|
// `fail` is terminal — once a live query has hard-failed, the only way to start
|
|
393
393
|
// streaming again is via `reconnect()`. Mark it done and abort any in-flight
|
|
394
394
|
// request so that callers from outside the main loop (e.g. `apply_reconnections`)
|
|
@@ -410,6 +410,16 @@ export class LiveQuery {
|
|
|
410
410
|
this.#fan_out.fail(error);
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
+
/** @param {unknown} e */
|
|
414
|
+
async #fail(e) {
|
|
415
|
+
const error = await handle_error(e, {
|
|
416
|
+
params: {},
|
|
417
|
+
route: { id: null },
|
|
418
|
+
url: new URL(location.href)
|
|
419
|
+
});
|
|
420
|
+
this.fail(new HttpError(error.status, error));
|
|
421
|
+
}
|
|
422
|
+
|
|
413
423
|
get [Symbol.toStringTag]() {
|
|
414
424
|
return 'LiveQuery';
|
|
415
425
|
}
|
|
@@ -137,9 +137,8 @@ export async function remote_request(url, init) {
|
|
|
137
137
|
);
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
141
140
|
* @param {string} key
|
|
142
|
-
* @param {CacheEntry
|
|
141
|
+
* @param {CacheEntry | undefined} entry
|
|
143
142
|
* @param {any} result
|
|
144
143
|
*/
|
|
145
144
|
function refresh(key, entry, result) {
|
|
@@ -1,54 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { version } from '$app/env';
|
|
2
|
+
import { assets } from '$app/paths/internal/client';
|
|
3
|
+
import { BROWSER, DEV } from 'esm-env';
|
|
3
4
|
|
|
4
5
|
/** @type {import('@sveltejs/kit').Page} */
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
6
|
+
export const page = new (class Page {
|
|
7
|
+
data = $state.raw({});
|
|
8
|
+
form = $state.raw(null);
|
|
9
|
+
error = $state.raw(null);
|
|
10
|
+
params = $state.raw({});
|
|
11
|
+
route = $state.raw({ id: null });
|
|
12
|
+
state = $state.raw({});
|
|
13
|
+
status = $state.raw(-1);
|
|
14
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
15
|
+
url = $state.raw(new URL('a:'));
|
|
16
|
+
})();
|
|
17
|
+
|
|
18
|
+
export const navigating = new (class Navigating {
|
|
19
|
+
/** @type {import('@sveltejs/kit').Navigation | null} */
|
|
20
|
+
current = $state.raw(null);
|
|
21
|
+
})();
|
|
22
|
+
|
|
23
|
+
export const updated = new (class Updated {
|
|
24
|
+
current = $state.raw(false);
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
26
|
+
check = async () => false;
|
|
27
|
+
})();
|
|
28
|
+
|
|
29
|
+
if (!DEV && BROWSER) {
|
|
30
|
+
const interval = __SVELTEKIT_APP_VERSION_POLL_INTERVAL__;
|
|
31
|
+
|
|
32
|
+
/** @type {number} */
|
|
33
|
+
let timeout;
|
|
34
|
+
|
|
35
|
+
/** @type {() => Promise<boolean>} */
|
|
36
|
+
async function check() {
|
|
37
|
+
window.clearTimeout(timeout);
|
|
38
|
+
|
|
39
|
+
if (interval) timeout = window.setTimeout(check, interval);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const res = await fetch(`${assets}/${__SVELTEKIT_APP_VERSION_FILE__}`, {
|
|
43
|
+
headers: {
|
|
44
|
+
'cache-control': 'no-cache'
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const data = await res.json();
|
|
53
|
+
const new_update = data.version !== version;
|
|
54
|
+
|
|
55
|
+
if (new_update) {
|
|
56
|
+
updated.current = true;
|
|
57
|
+
window.clearTimeout(timeout);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return new_update;
|
|
61
|
+
} catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (interval) timeout = window.setTimeout(check, interval);
|
|
67
|
+
|
|
68
|
+
updated.check = check;
|
|
52
69
|
}
|
|
53
70
|
|
|
54
71
|
/**
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
Uses
|
|
11
11
|
} from 'types';
|
|
12
12
|
import { Page, ParamMatcher } from '@sveltejs/kit';
|
|
13
|
+
import { RenderNode } from '../types.js';
|
|
13
14
|
|
|
14
15
|
export interface SvelteKitApp {
|
|
15
16
|
/**
|
|
@@ -39,7 +40,7 @@ export interface SvelteKitApp {
|
|
|
39
40
|
dictionary: Record<string, [leaf: number, layouts: number[], errors?: number[]]>;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* A map of `[matcherName: string]:
|
|
43
|
+
* A map of `[matcherName: string]: ParamMatcher`, which is used to match and parse route parameters.
|
|
43
44
|
*
|
|
44
45
|
* In case of router.resolution=server, this object is empty, as resolution happens on the server.
|
|
45
46
|
*/
|
|
@@ -57,8 +58,6 @@ export interface SvelteKitApp {
|
|
|
57
58
|
*/
|
|
58
59
|
hash: boolean;
|
|
59
60
|
|
|
60
|
-
root: typeof SvelteComponent;
|
|
61
|
-
|
|
62
61
|
/**
|
|
63
62
|
* Lazily loads the contents of src/error.html, used as a last-resort
|
|
64
63
|
* error page when the root layout's load function throws during client-side rendering.
|
|
@@ -91,13 +90,10 @@ export type NavigationFinished = {
|
|
|
91
90
|
type: 'loaded';
|
|
92
91
|
state: NavigationState;
|
|
93
92
|
props: {
|
|
94
|
-
constructors: Array<typeof SvelteComponent>;
|
|
95
|
-
errors?: Array<typeof SvelteComponent | undefined>;
|
|
96
|
-
components?: SvelteComponent[];
|
|
97
93
|
page: Page;
|
|
98
94
|
form?: Record<string, any> | null;
|
|
99
95
|
error?: App.Error;
|
|
100
|
-
|
|
96
|
+
tree: RenderNode;
|
|
101
97
|
};
|
|
102
98
|
};
|
|
103
99
|
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { BROWSER, DEV } from 'esm-env';
|
|
2
|
-
import { writable } from 'svelte/store';
|
|
3
|
-
import { assets } from '$app/paths/internal/client';
|
|
4
|
-
import { version } from '$app/env';
|
|
5
|
-
import { noop } from '../../utils/functions.js';
|
|
6
2
|
import { PRELOAD_PRIORITIES } from './constants.js';
|
|
7
3
|
|
|
8
|
-
/* global __SVELTEKIT_APP_VERSION_FILE__, __SVELTEKIT_APP_VERSION_POLL_INTERVAL__ */
|
|
9
|
-
|
|
10
4
|
export const origin = BROWSER ? location.origin : '';
|
|
11
5
|
|
|
12
6
|
/** @param {string | URL} url */
|
|
@@ -211,96 +205,6 @@ export function get_router_options(element) {
|
|
|
211
205
|
};
|
|
212
206
|
}
|
|
213
207
|
|
|
214
|
-
/** @param {any} value */
|
|
215
|
-
export function notifiable_store(value) {
|
|
216
|
-
const store = writable(value);
|
|
217
|
-
let ready = true;
|
|
218
|
-
|
|
219
|
-
function notify() {
|
|
220
|
-
ready = true;
|
|
221
|
-
store.update((val) => val);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/** @param {any} new_value */
|
|
225
|
-
function set(new_value) {
|
|
226
|
-
ready = false;
|
|
227
|
-
store.set(new_value);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/** @param {(value: any) => void} run */
|
|
231
|
-
function subscribe(run) {
|
|
232
|
-
/** @type {any} */
|
|
233
|
-
let old_value;
|
|
234
|
-
return store.subscribe((new_value) => {
|
|
235
|
-
if (old_value === undefined || (ready && new_value !== old_value)) {
|
|
236
|
-
run((old_value = new_value));
|
|
237
|
-
}
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return { notify, set, subscribe };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export const updated_listener = {
|
|
245
|
-
v: noop
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
export function create_updated_store() {
|
|
249
|
-
const { set, subscribe } = writable(false);
|
|
250
|
-
|
|
251
|
-
if (__SVELTEKIT_DEV__ || !BROWSER) {
|
|
252
|
-
return {
|
|
253
|
-
subscribe,
|
|
254
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
255
|
-
check: async () => false
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const interval = __SVELTEKIT_APP_VERSION_POLL_INTERVAL__;
|
|
260
|
-
|
|
261
|
-
/** @type {NodeJS.Timeout} */
|
|
262
|
-
let timeout;
|
|
263
|
-
|
|
264
|
-
/** @type {() => Promise<boolean>} */
|
|
265
|
-
async function check() {
|
|
266
|
-
clearTimeout(timeout);
|
|
267
|
-
|
|
268
|
-
if (interval) timeout = setTimeout(check, interval);
|
|
269
|
-
|
|
270
|
-
try {
|
|
271
|
-
const res = await fetch(`${assets}/${__SVELTEKIT_APP_VERSION_FILE__}`, {
|
|
272
|
-
headers: {
|
|
273
|
-
'cache-control': 'no-cache'
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
if (!res.ok) {
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const data = await res.json();
|
|
282
|
-
const updated = data.version !== version;
|
|
283
|
-
|
|
284
|
-
if (updated) {
|
|
285
|
-
set(true);
|
|
286
|
-
updated_listener.v();
|
|
287
|
-
clearTimeout(timeout);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return updated;
|
|
291
|
-
} catch {
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (interval) timeout = setTimeout(check, interval);
|
|
297
|
-
|
|
298
|
-
return {
|
|
299
|
-
subscribe,
|
|
300
|
-
check
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
|
|
304
208
|
/**
|
|
305
209
|
* Is external if
|
|
306
210
|
* - origin different
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { afterNavigate } from '$app/navigation';
|
|
3
|
+
import type { Page } from '@sveltejs/kit';
|
|
4
|
+
import type { RenderNode } from '../types.js';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
page: Page;
|
|
8
|
+
tree: RenderNode;
|
|
9
|
+
components: any[];
|
|
10
|
+
resetters: Array<(() => void) | undefined>;
|
|
11
|
+
form?: any;
|
|
12
|
+
error?: App.Error;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { page, components, resetters, tree, form, error }: Props = $props();
|
|
16
|
+
|
|
17
|
+
let mounted = $state(false);
|
|
18
|
+
let navigated = $state(false);
|
|
19
|
+
let title = $state('');
|
|
20
|
+
|
|
21
|
+
afterNavigate(() => {
|
|
22
|
+
if (mounted) {
|
|
23
|
+
navigated = true;
|
|
24
|
+
title = document.title || 'untitled page';
|
|
25
|
+
} else {
|
|
26
|
+
mounted = true;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
{#snippet node(n: RenderNode, depth: number)}
|
|
32
|
+
{const Component = $derived(n.component)}
|
|
33
|
+
{const Error = $derived(n.error)}
|
|
34
|
+
{const data = $derived(n.data)}
|
|
35
|
+
|
|
36
|
+
<svelte:boundary onerror={(_, reset) => (resetters[depth] = reset)}>
|
|
37
|
+
{#if n.child}
|
|
38
|
+
<!-- svelte-ignore binding_property_non_reactive -->
|
|
39
|
+
<Component bind:this={components[depth]} {data} {form} params={page.params}>
|
|
40
|
+
{@render node(n.child, depth + 1)}
|
|
41
|
+
</Component>
|
|
42
|
+
{:else}
|
|
43
|
+
<!-- svelte-ignore binding_property_non_reactive -->
|
|
44
|
+
<Component bind:this={components[depth]} {data} {form} params={page.params} {error} />
|
|
45
|
+
{/if}
|
|
46
|
+
|
|
47
|
+
{#snippet failed(error)}
|
|
48
|
+
<Error {error} />
|
|
49
|
+
{/snippet}
|
|
50
|
+
</svelte:boundary>
|
|
51
|
+
{/snippet}
|
|
52
|
+
|
|
53
|
+
{@render node(tree, 0)}
|
|
54
|
+
|
|
55
|
+
{#if mounted}
|
|
56
|
+
<div
|
|
57
|
+
id="svelte-announcer"
|
|
58
|
+
aria-live="assertive"
|
|
59
|
+
aria-atomic="true"
|
|
60
|
+
style="position: absolute; left: 0; top: 0; clip: rect(0 0 0 0); clip-path: inset(50%); overflow: hidden; white-space: nowrap; width: 1px; height: 1px"
|
|
61
|
+
>
|
|
62
|
+
{#if navigated}
|
|
63
|
+
{title}
|
|
64
|
+
{/if}
|
|
65
|
+
</div>
|
|
66
|
+
{/if}
|