svelte 5.56.10 → 5.57.0
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/compiler/index.js +1 -1
- package/elements.d.ts +3 -0
- package/package.json +3 -3
- package/src/compiler/phases/1-parse/acorn.js +1 -1
- package/src/compiler/phases/1-parse/utils/html.js +12 -7
- package/src/compiler/phases/2-analyze/css/css-prune.js +10 -0
- package/src/compiler/phases/2-analyze/index.js +26 -3
- package/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +10 -4
- package/src/compiler/phases/2-analyze/visitors/CallExpression.js +1 -1
- package/src/compiler/phases/2-analyze/visitors/DeclarationTag.js +2 -1
- package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +10 -10
- package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +4 -4
- package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +4 -4
- package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +4 -4
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +14 -2
- package/src/compiler/phases/2-analyze/visitors/shared/element.js +2 -8
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +23 -1
- package/src/compiler/phases/3-transform/client/transform-client.js +2 -2
- package/src/compiler/phases/3-transform/client/transform-template/index.js +6 -0
- package/src/compiler/phases/3-transform/client/utils.js +35 -8
- package/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +6 -6
- package/src/compiler/phases/3-transform/client/visitors/BindDirective.js +10 -13
- package/src/compiler/phases/3-transform/client/visitors/ConstTag.js +19 -8
- package/src/compiler/phases/3-transform/client/visitors/DeclarationTag.js +3 -2
- package/src/compiler/phases/3-transform/client/visitors/EachBlock.js +4 -1
- package/src/compiler/phases/3-transform/client/visitors/Fragment.js +2 -7
- package/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +2 -1
- package/src/compiler/phases/3-transform/client/visitors/IfBlock.js +2 -1
- package/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +2 -1
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +106 -44
- package/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +2 -1
- package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +11 -4
- package/src/compiler/phases/3-transform/client/visitors/shared/element.js +6 -1
- package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +1 -6
- package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +5 -5
- package/src/compiler/phases/3-transform/server/transform-server.js +20 -9
- package/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +1 -1
- package/src/compiler/phases/3-transform/server/visitors/DeclarationTag.js +1 -1
- package/src/compiler/phases/3-transform/server/visitors/EachBlock.js +8 -2
- package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +4 -4
- package/src/compiler/phases/3-transform/server/visitors/RegularElement.js +1 -1
- package/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +9 -4
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +5 -4
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +30 -0
- package/src/compiler/phases/bindings.js +3 -1
- package/src/compiler/phases/nodes.js +4 -0
- package/src/compiler/print/index.js +21 -16
- package/src/easing/index.js +62 -0
- package/src/internal/client/constants.js +9 -0
- package/src/internal/client/context.js +15 -5
- package/src/internal/client/dev/hmr.js +15 -4
- package/src/internal/client/dom/blocks/boundary.js +21 -12
- package/src/internal/client/dom/blocks/slot.js +19 -0
- package/src/internal/client/dom/blocks/svelte-head.js +8 -0
- package/src/internal/client/dom/elements/attributes.js +35 -34
- package/src/internal/client/dom/elements/bindings/select.js +99 -9
- package/src/internal/client/dom/elements/bindings/this.js +7 -2
- package/src/internal/client/dom/elements/transitions.js +81 -68
- package/src/internal/client/dom/operations.js +21 -1
- package/src/internal/client/error-handling.js +10 -2
- package/src/internal/client/index.js +9 -2
- package/src/internal/client/proxy.js +8 -3
- package/src/internal/client/reactivity/async.js +23 -3
- package/src/internal/client/reactivity/effects.js +14 -1
- package/src/internal/client/render.js +4 -8
- package/src/internal/client/runtime.js +45 -33
- package/src/internal/client/warnings.js +0 -11
- package/src/internal/server/abort-signal.js +8 -9
- package/src/internal/server/context.js +2 -2
- package/src/internal/server/index.js +1 -1
- package/src/internal/server/renderer.js +163 -52
- package/src/internal/shared/attributes.js +2 -1
- package/src/internal/shared/clone.js +2 -0
- package/src/internal/shared/context.js +3 -2
- package/src/legacy/legacy-server.js +1 -1
- package/src/reactivity/map.js +22 -0
- package/src/reactivity/url.js +2 -0
- package/src/transition/index.js +18 -7
- package/src/version.js +1 -1
- package/types/index.d.ts +135 -37
- package/types/index.d.ts.map +2 -2
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** @import { Component } from 'svelte' */
|
|
2
|
-
/** @import {
|
|
2
|
+
/** @import { HydratableContext, SSRContext } from './types.js' */
|
|
3
|
+
/** @import { Csp, RenderOutput, SyncRenderOutput, Sha256Source } from '../../server/public.js' */
|
|
3
4
|
/** @import { MaybePromise } from '#shared' */
|
|
4
5
|
import { async_mode_flag } from '../flags/index.js';
|
|
5
|
-
import {
|
|
6
|
+
import { STALE_REACTION } from '../client/constants.js';
|
|
6
7
|
import { pop, push, set_ssr_context, ssr_context } from './context.js';
|
|
7
8
|
import * as e from './errors.js';
|
|
8
9
|
import * as w from './warnings.js';
|
|
@@ -12,7 +13,7 @@ import { attributes } from './index.js';
|
|
|
12
13
|
import { get_render_context, with_render_context, init_render_context } from './render-context.js';
|
|
13
14
|
import { sha256 } from './crypto.js';
|
|
14
15
|
import * as devalue from 'devalue';
|
|
15
|
-
import { has_own_property, noop } from '../shared/utils.js';
|
|
16
|
+
import { has_own_property, is_array, noop } from '../shared/utils.js';
|
|
16
17
|
import { escape_html } from '../../escaping.js';
|
|
17
18
|
|
|
18
19
|
/** @typedef {'head' | 'body'} RendererType */
|
|
@@ -88,7 +89,7 @@ export class Renderer {
|
|
|
88
89
|
* State that is local to the branch it is declared in.
|
|
89
90
|
* It will be shallow-copied to all children.
|
|
90
91
|
*
|
|
91
|
-
* @type {{ select_value:
|
|
92
|
+
* @type {{ select_value: any, multiple: boolean }}
|
|
92
93
|
*/
|
|
93
94
|
local;
|
|
94
95
|
|
|
@@ -100,7 +101,7 @@ export class Renderer {
|
|
|
100
101
|
this.#parent = parent;
|
|
101
102
|
|
|
102
103
|
this.global = global;
|
|
103
|
-
this.local = parent ? { ...parent.local } : { select_value: undefined };
|
|
104
|
+
this.local = parent ? { ...parent.local } : { select_value: undefined, multiple: false };
|
|
104
105
|
this.type = parent ? parent.type : 'body';
|
|
105
106
|
}
|
|
106
107
|
|
|
@@ -179,7 +180,7 @@ export class Renderer {
|
|
|
179
180
|
// prevent unhandled rejections, and attach the promise to the renderer instance
|
|
180
181
|
// so that rejections correctly cause rendering to fail
|
|
181
182
|
promise.catch(noop);
|
|
182
|
-
this.promise = promise;
|
|
183
|
+
this.promise = this.global.track(promise);
|
|
183
184
|
|
|
184
185
|
return promises;
|
|
185
186
|
}
|
|
@@ -224,7 +225,7 @@ export class Renderer {
|
|
|
224
225
|
e.await_invalid();
|
|
225
226
|
}
|
|
226
227
|
|
|
227
|
-
child.promise = result;
|
|
228
|
+
child.promise = child.global.track(result);
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
return child;
|
|
@@ -272,7 +273,7 @@ export class Renderer {
|
|
|
272
273
|
e.await_invalid();
|
|
273
274
|
}
|
|
274
275
|
result.catch(noop);
|
|
275
|
-
child.promise = result;
|
|
276
|
+
child.promise = child.global.track(result);
|
|
276
277
|
}
|
|
277
278
|
} catch (error) {
|
|
278
279
|
// synchronous errors are handled here, async errors will be handled in #collect_content_async
|
|
@@ -292,12 +293,14 @@ export class Renderer {
|
|
|
292
293
|
e.await_invalid();
|
|
293
294
|
}
|
|
294
295
|
|
|
295
|
-
child.promise =
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
296
|
+
child.promise = child.global.track(
|
|
297
|
+
/** @type {Promise<unknown>} */ (result).then((transformed) => {
|
|
298
|
+
set_ssr_context(parent_context);
|
|
299
|
+
child.#out.push(Renderer.#serialize_failed_boundary(transformed));
|
|
300
|
+
failed_snippet(child, transformed, noop);
|
|
301
|
+
child.#out.push(BLOCK_CLOSE);
|
|
302
|
+
})
|
|
303
|
+
);
|
|
301
304
|
child.promise.catch(noop);
|
|
302
305
|
} else {
|
|
303
306
|
child.#out.push(Renderer.#serialize_failed_boundary(result));
|
|
@@ -316,8 +319,11 @@ export class Renderer {
|
|
|
316
319
|
*/
|
|
317
320
|
component(fn, component_fn) {
|
|
318
321
|
push(component_fn);
|
|
319
|
-
|
|
320
|
-
child
|
|
322
|
+
// mark before running so `onDestroy` callbacks are still collected if `fn` throws
|
|
323
|
+
this.child((renderer) => {
|
|
324
|
+
renderer.#is_component_body = true;
|
|
325
|
+
return fn(renderer);
|
|
326
|
+
});
|
|
321
327
|
pop();
|
|
322
328
|
}
|
|
323
329
|
|
|
@@ -332,11 +338,13 @@ export class Renderer {
|
|
|
332
338
|
* @returns {void}
|
|
333
339
|
*/
|
|
334
340
|
select(attrs, fn, css_hash, classes, styles, flags, is_rich) {
|
|
335
|
-
const { value, ...select_attrs } = attrs;
|
|
341
|
+
const { value, defaultValue, ...select_attrs } = attrs;
|
|
342
|
+
if (select_attrs.multiple === '') select_attrs.multiple = true;
|
|
336
343
|
|
|
337
344
|
this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags)}>`);
|
|
338
345
|
this.child((renderer) => {
|
|
339
|
-
renderer.local.select_value = value;
|
|
346
|
+
renderer.local.select_value = value === undefined ? defaultValue : value;
|
|
347
|
+
renderer.local.multiple = !!select_attrs.multiple;
|
|
340
348
|
fn(renderer);
|
|
341
349
|
});
|
|
342
350
|
this.push(`${is_rich ? '<!>' : ''}</select>`);
|
|
@@ -364,7 +372,15 @@ export class Renderer {
|
|
|
364
372
|
value = attrs.value;
|
|
365
373
|
}
|
|
366
374
|
|
|
367
|
-
|
|
375
|
+
var select_value = this.local.select_value;
|
|
376
|
+
|
|
377
|
+
if (
|
|
378
|
+
// Super edge-case, but theoretically someone could use arrays with non-multiple selects,
|
|
379
|
+
// so we gotta check for the multiple attribute presence, too.
|
|
380
|
+
this.local.multiple && is_array(select_value)
|
|
381
|
+
? select_value.includes(value)
|
|
382
|
+
: value === select_value
|
|
383
|
+
) {
|
|
368
384
|
renderer.#out.push(' selected=""');
|
|
369
385
|
}
|
|
370
386
|
|
|
@@ -625,6 +641,49 @@ export class Renderer {
|
|
|
625
641
|
}
|
|
626
642
|
}
|
|
627
643
|
|
|
644
|
+
/**
|
|
645
|
+
* Runs every `onDestroy` callback in this renderer tree. On a failed render,
|
|
646
|
+
* cleanup errors are suppressed so they do not mask the render error.
|
|
647
|
+
* @param {boolean} suppress_errors
|
|
648
|
+
*/
|
|
649
|
+
#run_on_destroy(suppress_errors) {
|
|
650
|
+
let first_error;
|
|
651
|
+
let has_error = false;
|
|
652
|
+
|
|
653
|
+
for (const cleanup of this.#collect_on_destroy()) {
|
|
654
|
+
try {
|
|
655
|
+
cleanup();
|
|
656
|
+
} catch (error) {
|
|
657
|
+
if (!suppress_errors && !has_error) {
|
|
658
|
+
first_error = error;
|
|
659
|
+
has_error = true;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (has_error) throw first_error;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* @param {'sync' | 'async'} mode
|
|
669
|
+
* @param {{ idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
|
|
670
|
+
* @returns {Renderer}
|
|
671
|
+
*/
|
|
672
|
+
static #create(mode, options) {
|
|
673
|
+
if (options.idPrefix?.includes('--')) {
|
|
674
|
+
e.invalid_id_prefix();
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
return new Renderer(
|
|
678
|
+
new SSRState(
|
|
679
|
+
mode,
|
|
680
|
+
options.idPrefix ? options.idPrefix + '-' : '',
|
|
681
|
+
options.csp,
|
|
682
|
+
options.transformError
|
|
683
|
+
)
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
|
|
628
687
|
/**
|
|
629
688
|
* Render a component. Throws if any of the children are performing asynchronous work.
|
|
630
689
|
*
|
|
@@ -635,13 +694,27 @@ export class Renderer {
|
|
|
635
694
|
*/
|
|
636
695
|
static #render(component, options) {
|
|
637
696
|
var previous_context = ssr_context;
|
|
697
|
+
const renderer = Renderer.#create('sync', options);
|
|
698
|
+
/** @type {AccumulatedContent | undefined} */
|
|
699
|
+
let result;
|
|
700
|
+
let render_error;
|
|
701
|
+
let failed = false;
|
|
702
|
+
|
|
638
703
|
try {
|
|
639
|
-
|
|
704
|
+
try {
|
|
705
|
+
Renderer.#open_render(renderer, component, options);
|
|
706
|
+
result = Renderer.#close_render(renderer.#collect_content(), renderer);
|
|
707
|
+
} catch (error) {
|
|
708
|
+
render_error = error;
|
|
709
|
+
failed = true;
|
|
710
|
+
}
|
|
640
711
|
|
|
641
|
-
|
|
642
|
-
|
|
712
|
+
renderer.#run_on_destroy(failed);
|
|
713
|
+
if (failed) throw render_error;
|
|
714
|
+
|
|
715
|
+
return /** @type {AccumulatedContent} */ (result);
|
|
643
716
|
} finally {
|
|
644
|
-
abort();
|
|
717
|
+
renderer.global.abort();
|
|
645
718
|
set_ssr_context(previous_context);
|
|
646
719
|
}
|
|
647
720
|
}
|
|
@@ -656,18 +729,35 @@ export class Renderer {
|
|
|
656
729
|
*/
|
|
657
730
|
static async #render_async(component, options) {
|
|
658
731
|
const previous_context = ssr_context;
|
|
732
|
+
const renderer = Renderer.#create('async', options);
|
|
733
|
+
/** @type {(AccumulatedContent & { hashes: { script: Sha256Source[] } }) | undefined} */
|
|
734
|
+
let result;
|
|
735
|
+
let render_error;
|
|
736
|
+
let failed = false;
|
|
659
737
|
|
|
660
738
|
try {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
739
|
+
try {
|
|
740
|
+
Renderer.#open_render(renderer, component, options);
|
|
741
|
+
const content = await renderer.#collect_content_async();
|
|
742
|
+
const hydratables = await renderer.#collect_hydratables();
|
|
743
|
+
if (hydratables !== null) {
|
|
744
|
+
content.head = hydratables + content.head;
|
|
745
|
+
}
|
|
746
|
+
result = Renderer.#close_render(content, renderer);
|
|
747
|
+
} catch (error) {
|
|
748
|
+
render_error = error;
|
|
749
|
+
failed = true;
|
|
750
|
+
renderer.global.abort();
|
|
751
|
+
await renderer.global.settle();
|
|
666
752
|
}
|
|
667
|
-
|
|
753
|
+
|
|
754
|
+
renderer.#run_on_destroy(failed);
|
|
755
|
+
if (failed) throw render_error;
|
|
756
|
+
|
|
757
|
+
return /** @type {AccumulatedContent & { hashes: { script: Sha256Source[] } }} */ (result);
|
|
668
758
|
} finally {
|
|
669
759
|
set_ssr_context(previous_context);
|
|
670
|
-
abort();
|
|
760
|
+
renderer.global.abort();
|
|
671
761
|
}
|
|
672
762
|
}
|
|
673
763
|
|
|
@@ -759,28 +849,15 @@ export class Renderer {
|
|
|
759
849
|
|
|
760
850
|
/**
|
|
761
851
|
* @template {Record<string, any>} Props
|
|
762
|
-
* @param {
|
|
852
|
+
* @param {Renderer} renderer
|
|
763
853
|
* @param {import('svelte').Component<Props>} component
|
|
764
854
|
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
|
|
765
|
-
* @returns {
|
|
855
|
+
* @returns {void}
|
|
766
856
|
*/
|
|
767
|
-
static #open_render(
|
|
768
|
-
if (options.idPrefix?.includes('--')) {
|
|
769
|
-
e.invalid_id_prefix();
|
|
770
|
-
}
|
|
771
|
-
|
|
857
|
+
static #open_render(renderer, component, options) {
|
|
772
858
|
var previous_context = ssr_context;
|
|
773
859
|
|
|
774
860
|
try {
|
|
775
|
-
const renderer = new Renderer(
|
|
776
|
-
new SSRState(
|
|
777
|
-
mode,
|
|
778
|
-
options.idPrefix ? options.idPrefix + '-' : '',
|
|
779
|
-
options.csp,
|
|
780
|
-
options.transformError
|
|
781
|
-
)
|
|
782
|
-
);
|
|
783
|
-
|
|
784
861
|
/** @type {SSRContext} */
|
|
785
862
|
const context = { p: null, c: options.context ?? null, r: renderer };
|
|
786
863
|
set_ssr_context(context);
|
|
@@ -789,8 +866,6 @@ export class Renderer {
|
|
|
789
866
|
// @ts-expect-error
|
|
790
867
|
component(renderer, options.props ?? {});
|
|
791
868
|
renderer.push(BLOCK_CLOSE);
|
|
792
|
-
|
|
793
|
-
return renderer;
|
|
794
869
|
} finally {
|
|
795
870
|
set_ssr_context(previous_context);
|
|
796
871
|
}
|
|
@@ -802,10 +877,6 @@ export class Renderer {
|
|
|
802
877
|
* @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
|
|
803
878
|
*/
|
|
804
879
|
static #close_render(content, renderer) {
|
|
805
|
-
for (const cleanup of renderer.#collect_on_destroy()) {
|
|
806
|
-
cleanup();
|
|
807
|
-
}
|
|
808
|
-
|
|
809
880
|
let head = content.head + renderer.global.get_title();
|
|
810
881
|
let body = content.body;
|
|
811
882
|
|
|
@@ -889,6 +960,14 @@ export class SSRState {
|
|
|
889
960
|
/** @readonly @type {Set<{ hash: string; code: string }>} */
|
|
890
961
|
css = new Set();
|
|
891
962
|
|
|
963
|
+
/** @type {Set<Promise<unknown>>} */
|
|
964
|
+
#pending = new Set();
|
|
965
|
+
|
|
966
|
+
/** @type {AbortController | null} */
|
|
967
|
+
#controller = null;
|
|
968
|
+
|
|
969
|
+
#aborted = false;
|
|
970
|
+
|
|
892
971
|
/**
|
|
893
972
|
* `transformError` passed to `render`. Called when an error boundary catches an error.
|
|
894
973
|
* Throws by default if unset in `render`.
|
|
@@ -919,6 +998,38 @@ export class SSRState {
|
|
|
919
998
|
this.uid = () => `${id_prefix}s${uid++}`;
|
|
920
999
|
}
|
|
921
1000
|
|
|
1001
|
+
/**
|
|
1002
|
+
* @template T
|
|
1003
|
+
* @param {Promise<T>} promise
|
|
1004
|
+
* @returns {Promise<T>}
|
|
1005
|
+
*/
|
|
1006
|
+
track(promise) {
|
|
1007
|
+
this.#pending.add(promise);
|
|
1008
|
+
promise.then(
|
|
1009
|
+
() => this.#pending.delete(promise),
|
|
1010
|
+
() => this.#pending.delete(promise)
|
|
1011
|
+
);
|
|
1012
|
+
return promise;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
async settle() {
|
|
1016
|
+
while (this.#pending.size > 0) {
|
|
1017
|
+
await Promise.allSettled([...this.#pending]);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
abort() {
|
|
1022
|
+
if (this.#aborted) return;
|
|
1023
|
+
this.#aborted = true;
|
|
1024
|
+
this.#controller?.abort(STALE_REACTION);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
get_abort_signal() {
|
|
1028
|
+
const controller = (this.#controller ??= new AbortController());
|
|
1029
|
+
if (this.#aborted) controller.abort(STALE_REACTION);
|
|
1030
|
+
return controller.signal;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
922
1033
|
get_title() {
|
|
923
1034
|
return this.#title.value;
|
|
924
1035
|
}
|
|
@@ -27,7 +27,8 @@ export function attr(name, value, is_boolean = false) {
|
|
|
27
27
|
if (name === 'hidden' && value !== 'until-found') {
|
|
28
28
|
is_boolean = true;
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
// `''` is a present boolean attribute, as it is in markup and on the client
|
|
31
|
+
if (value == null || (is_boolean && !value && value !== '')) return '';
|
|
31
32
|
const normalized =
|
|
32
33
|
(has_own_property.call(replacements, name) && replacements[name].get(value)) || value;
|
|
33
34
|
const assignment = is_boolean ? `=""` : `="${escape_html(normalized, true)}"`;
|
|
@@ -105,6 +105,8 @@ function clone(value, cloned, path, paths, original = null, no_tojson = false) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
if (value instanceof Date) {
|
|
108
|
+
// Ensure SvelteDate snapshots are tracked
|
|
109
|
+
value.getTime();
|
|
108
110
|
return /** @type {Snapshot<T>} */ (structuredClone(value));
|
|
109
111
|
}
|
|
110
112
|
|
|
@@ -5,7 +5,7 @@ import { lifecycle_outside_component, missing_context } from './errors.js';
|
|
|
5
5
|
* @param {(key: object) => T} get_context
|
|
6
6
|
* @param {(key: object, context: T) => T} set_context
|
|
7
7
|
* @param {(key: object) => boolean} has_context
|
|
8
|
-
* @returns {[() => T, (context: T) => T]}
|
|
8
|
+
* @returns {[() => T, (context: T) => T, () => boolean]}
|
|
9
9
|
*/
|
|
10
10
|
export function create_context(get_context, set_context, has_context) {
|
|
11
11
|
const key = {};
|
|
@@ -18,7 +18,8 @@ export function create_context(get_context, set_context, has_context) {
|
|
|
18
18
|
|
|
19
19
|
return get_context(key);
|
|
20
20
|
},
|
|
21
|
-
(context) => set_context(key, context)
|
|
21
|
+
(context) => set_context(key, context),
|
|
22
|
+
() => has_context(key)
|
|
22
23
|
];
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { SvelteComponent } from '../index.js' */
|
|
2
|
-
/** @import { Csp } from '
|
|
2
|
+
/** @import { Csp } from '../server/public.js' */
|
|
3
3
|
import { asClassComponent as as_class_component, createClassComponent } from './legacy-client.js';
|
|
4
4
|
import { render } from '../internal/server/index.js';
|
|
5
5
|
import { async_mode_flag } from '../internal/flags/index.js';
|
package/src/reactivity/map.js
CHANGED
|
@@ -153,6 +153,28 @@ export class SvelteMap extends Map {
|
|
|
153
153
|
return super.get(key);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
/**
|
|
157
|
+
* @param {K} key
|
|
158
|
+
* @param {V} value
|
|
159
|
+
* */
|
|
160
|
+
getOrInsert(key, value) {
|
|
161
|
+
if (!super.has(key)) {
|
|
162
|
+
this.set(key, value);
|
|
163
|
+
}
|
|
164
|
+
return /** @type {V} */ (this.get(key));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {K} key
|
|
169
|
+
* @param {(key: K) => V} callbackFn
|
|
170
|
+
*/
|
|
171
|
+
getOrInsertComputed(key, callbackFn) {
|
|
172
|
+
if (!super.has(key)) {
|
|
173
|
+
this.set(key, callbackFn(key));
|
|
174
|
+
}
|
|
175
|
+
return /** @type {V} */ (this.get(key));
|
|
176
|
+
}
|
|
177
|
+
|
|
156
178
|
/**
|
|
157
179
|
* @param {K} key
|
|
158
180
|
* @param {V} value
|
package/src/reactivity/url.js
CHANGED
|
@@ -163,6 +163,8 @@ export class SvelteURL extends URL {
|
|
|
163
163
|
set protocol(value) {
|
|
164
164
|
super.protocol = value;
|
|
165
165
|
set(this.#protocol, super.protocol);
|
|
166
|
+
// changing the protocol can clear the port when it matches the new scheme's default
|
|
167
|
+
set(this.#port, super.port);
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
get search() {
|
package/src/transition/index.js
CHANGED
|
@@ -28,6 +28,17 @@ function split_css_unit(value) {
|
|
|
28
28
|
return split ? [parseFloat(split[1]), split[2] || 'px'] : [/** @type {number} */ (value), 'px'];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Omits unresolved dimensions rather than passing invalid values to Web Animations.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} property
|
|
35
|
+
* @param {number} value
|
|
36
|
+
* @param {number} t
|
|
37
|
+
*/
|
|
38
|
+
function css_dimension(property, value, t) {
|
|
39
|
+
return Number.isNaN(value) ? '' : `${property}: ${t * value}px;`;
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
/**
|
|
32
43
|
* Animates a `blur` filter alongside an element's opacity.
|
|
33
44
|
*
|
|
@@ -138,13 +149,13 @@ export function slide(node, { delay = 0, duration = 400, easing = cubic_out, axi
|
|
|
138
149
|
css: (t) =>
|
|
139
150
|
'overflow: hidden;' +
|
|
140
151
|
`opacity: ${Math.min(t * 20, 1) * opacity};` +
|
|
141
|
-
|
|
142
|
-
`padding-${secondary_properties[0]}
|
|
143
|
-
`padding-${secondary_properties[1]}
|
|
144
|
-
`margin-${secondary_properties[0]}
|
|
145
|
-
`margin-${secondary_properties[1]}
|
|
146
|
-
`border-${secondary_properties[0]}-width
|
|
147
|
-
`border-${secondary_properties[1]}-width
|
|
152
|
+
css_dimension(primary_property, primary_property_value, t) +
|
|
153
|
+
css_dimension(`padding-${secondary_properties[0]}`, padding_start_value, t) +
|
|
154
|
+
css_dimension(`padding-${secondary_properties[1]}`, padding_end_value, t) +
|
|
155
|
+
css_dimension(`margin-${secondary_properties[0]}`, margin_start_value, t) +
|
|
156
|
+
css_dimension(`margin-${secondary_properties[1]}`, margin_end_value, t) +
|
|
157
|
+
css_dimension(`border-${secondary_properties[0]}-width`, border_width_start_value, t) +
|
|
158
|
+
css_dimension(`border-${secondary_properties[1]}-width`, border_width_end_value, t) +
|
|
148
159
|
`min-${primary_property}: 0`
|
|
149
160
|
};
|
|
150
161
|
}
|
package/src/version.js
CHANGED