svelte 5.55.5 → 5.55.7
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 -3
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/read/style.js +15 -0
- package/src/compiler/phases/3-transform/client/visitors/DebugTag.js +10 -4
- package/src/compiler/phases/3-transform/server/visitors/Component.js +5 -1
- package/src/compiler/phases/3-transform/server/visitors/DebugTag.js +21 -10
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +2 -2
- package/src/internal/client/constants.js +5 -0
- package/src/internal/client/dev/inspect.js +2 -0
- package/src/internal/client/dom/blocks/async.js +1 -5
- package/src/internal/client/dom/blocks/boundary.js +4 -5
- package/src/internal/client/dom/blocks/svelte-head.js +6 -5
- package/src/internal/client/dom/elements/attributes.js +17 -8
- package/src/internal/client/dom/elements/bindings/shared.js +4 -6
- package/src/internal/client/dom/elements/bindings/this.js +1 -1
- package/src/internal/client/dom/elements/class.js +3 -4
- package/src/internal/client/dom/elements/events.js +2 -2
- package/src/internal/client/dom/elements/misc.js +2 -2
- package/src/internal/client/dom/elements/style.js +3 -4
- package/src/internal/client/dom/operations.js +12 -11
- package/src/internal/client/reactivity/async.js +34 -16
- package/src/internal/client/reactivity/batch.js +294 -127
- package/src/internal/client/reactivity/deriveds.js +30 -29
- package/src/internal/client/reactivity/effects.js +1 -9
- package/src/internal/client/reactivity/props.js +7 -1
- package/src/internal/client/reactivity/sources.js +19 -9
- package/src/internal/client/render.js +4 -5
- package/src/internal/server/hydratable.js +7 -2
- package/src/internal/server/index.js +1 -1
- package/src/internal/server/renderer.js +6 -1
- package/src/utils.js +1 -1
- package/src/version.js +1 -1
- package/types/index.d.ts +2 -0
- package/types/index.d.ts.map +1 -1
package/elements.d.ts
CHANGED
|
@@ -2067,9 +2067,9 @@ export interface SvelteHTMLElements {
|
|
|
2067
2067
|
};
|
|
2068
2068
|
'svelte:head': { [name: string]: any };
|
|
2069
2069
|
'svelte:boundary': {
|
|
2070
|
-
onerror?: (error: unknown, reset: () => void) => void;
|
|
2071
|
-
failed?: import('svelte').Snippet<[error: unknown, reset: () => void]
|
|
2072
|
-
pending?: import('svelte').Snippet;
|
|
2070
|
+
onerror?: ((error: unknown, reset: () => void) => void) | null | undefined;
|
|
2071
|
+
failed?: import('svelte').Snippet<[error: unknown, reset: () => void]> | null | undefined;
|
|
2072
|
+
pending?: import('svelte').Snippet | null | undefined;
|
|
2073
2073
|
};
|
|
2074
2074
|
|
|
2075
2075
|
[name: string]: { [name: string]: any };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "svelte",
|
|
3
3
|
"description": "Cybernetically enhanced web apps",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "5.55.
|
|
5
|
+
"version": "5.55.7",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "./types/index.d.ts",
|
|
8
8
|
"engines": {
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"aria-query": "5.3.1",
|
|
165
165
|
"axobject-query": "^4.1.0",
|
|
166
166
|
"clsx": "^2.1.1",
|
|
167
|
-
"devalue": "^5.
|
|
167
|
+
"devalue": "^5.8.1",
|
|
168
168
|
"esm-env": "^1.2.1",
|
|
169
169
|
"esrap": "^2.2.4",
|
|
170
170
|
"is-reference": "^3.0.3",
|
|
@@ -524,6 +524,21 @@ function read_value(parser) {
|
|
|
524
524
|
in_url = true;
|
|
525
525
|
} else if ((char === ';' || char === '{' || char === '}') && !in_url && !quote_mark) {
|
|
526
526
|
return value.trim();
|
|
527
|
+
} else if (
|
|
528
|
+
char === '/' &&
|
|
529
|
+
!in_url &&
|
|
530
|
+
!quote_mark &&
|
|
531
|
+
parser.template[parser.index + 1] === '*'
|
|
532
|
+
) {
|
|
533
|
+
parser.index += 2;
|
|
534
|
+
while (parser.index < parser.template.length) {
|
|
535
|
+
if (parser.template[parser.index] === '*' && parser.template[parser.index + 1] === '/') {
|
|
536
|
+
parser.index += 2;
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
parser.index++;
|
|
540
|
+
}
|
|
541
|
+
continue;
|
|
527
542
|
}
|
|
528
543
|
|
|
529
544
|
value += char;
|
|
@@ -8,6 +8,10 @@ import * as b from '#compiler/builders';
|
|
|
8
8
|
* @param {ComponentContext} context
|
|
9
9
|
*/
|
|
10
10
|
export function DebugTag(node, context) {
|
|
11
|
+
const blockers = node.identifiers
|
|
12
|
+
.map((identifier) => context.state.scope.get(identifier.name)?.blocker)
|
|
13
|
+
.filter((blocker) => blocker != null);
|
|
14
|
+
|
|
11
15
|
const object = b.object(
|
|
12
16
|
node.identifiers.map((identifier) => {
|
|
13
17
|
const visited = b.call('$.snapshot', /** @type {Expression} */ (context.visit(identifier)));
|
|
@@ -20,9 +24,11 @@ export function DebugTag(node, context) {
|
|
|
20
24
|
})
|
|
21
25
|
);
|
|
22
26
|
|
|
23
|
-
const
|
|
27
|
+
const args = [b.thunk(b.block([b.stmt(b.call('console.log', object)), b.debugger]))];
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (blockers.length > 0) {
|
|
30
|
+
args.push(b.array([]), b.array([]), b.array(blockers));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
context.state.init.push(b.stmt(b.call('$.template_effect', ...args)));
|
|
28
34
|
}
|
|
@@ -9,5 +9,9 @@ import { build_inline_component } from './shared/component.js';
|
|
|
9
9
|
* @param {ComponentContext} context
|
|
10
10
|
*/
|
|
11
11
|
export function Component(node, context) {
|
|
12
|
-
build_inline_component(
|
|
12
|
+
build_inline_component(
|
|
13
|
+
node,
|
|
14
|
+
/** @type {Expression} */ (context.visit(b.member_id(node.name))),
|
|
15
|
+
context
|
|
16
|
+
);
|
|
13
17
|
}
|
|
@@ -2,23 +2,34 @@
|
|
|
2
2
|
/** @import { AST } from '#compiler' */
|
|
3
3
|
/** @import { ComponentContext } from '../types.js' */
|
|
4
4
|
import * as b from '#compiler/builders';
|
|
5
|
+
import { create_child_block } from './shared/utils.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @param {AST.DebugTag} node
|
|
8
9
|
* @param {ComponentContext} context
|
|
9
10
|
*/
|
|
10
11
|
export function DebugTag(node, context) {
|
|
12
|
+
const blockers = node.identifiers
|
|
13
|
+
.map((identifier) => context.state.scope.get(identifier.name)?.blocker)
|
|
14
|
+
.filter((blocker) => blocker != null);
|
|
15
|
+
|
|
11
16
|
context.state.template.push(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
b.
|
|
17
|
+
...create_child_block(
|
|
18
|
+
[
|
|
19
|
+
b.stmt(
|
|
20
|
+
b.call(
|
|
21
|
+
'console.log',
|
|
22
|
+
b.object(
|
|
23
|
+
node.identifiers.map((identifier) =>
|
|
24
|
+
b.prop('init', identifier, /** @type {Expression} */ (context.visit(identifier)))
|
|
25
|
+
)
|
|
26
|
+
)
|
|
18
27
|
)
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
),
|
|
29
|
+
b.debugger
|
|
30
|
+
],
|
|
31
|
+
b.array(blockers),
|
|
32
|
+
false
|
|
33
|
+
)
|
|
23
34
|
);
|
|
24
35
|
}
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import * as b from '#compiler/builders';
|
|
13
13
|
import { sanitize_template_string } from '../../../../../utils/sanitize_template_string.js';
|
|
14
14
|
import { regex_whitespaces_strict } from '../../../../patterns.js';
|
|
15
|
-
import { has_await_expression } from '../../../../../utils/ast.js';
|
|
15
|
+
import { has_await_expression, save } from '../../../../../utils/ast.js';
|
|
16
16
|
import { ExpressionMetadata } from '../../../../nodes.js';
|
|
17
17
|
|
|
18
18
|
/** Opens an if/each block, so that we can remove nodes in the case of a mismatch */
|
|
@@ -360,7 +360,7 @@ export class PromiseOptimiser {
|
|
|
360
360
|
|
|
361
361
|
return b.const(
|
|
362
362
|
b.array_pattern(this.expressions.map((_, i) => b.id(`$$${i}`))),
|
|
363
|
-
|
|
363
|
+
save(b.call('Promise.all', promises))
|
|
364
364
|
);
|
|
365
365
|
}
|
|
366
366
|
|
|
@@ -63,6 +63,11 @@ export const STATE_SYMBOL = Symbol('$state');
|
|
|
63
63
|
export const LEGACY_PROPS = Symbol('legacy props');
|
|
64
64
|
export const LOADING_ATTR_SYMBOL = Symbol('');
|
|
65
65
|
export const PROXY_PATH_SYMBOL = Symbol('proxy path');
|
|
66
|
+
export const ATTRIBUTES_CACHE = Symbol('attributes');
|
|
67
|
+
export const CLASS_CACHE = Symbol('class');
|
|
68
|
+
export const STYLE_CACHE = Symbol('style');
|
|
69
|
+
export const TEXT_CACHE = Symbol('text');
|
|
70
|
+
export const FORM_RESET_HANDLER = Symbol('form reset');
|
|
66
71
|
/** An anchor might change, via this symbol on the original anchor we can tell HMR about the updated anchor */
|
|
67
72
|
export const HMR_ANCHOR = Symbol('hmr anchor');
|
|
68
73
|
|
|
@@ -20,6 +20,8 @@ export function inspect(get_value, inspector, show_stack = false) {
|
|
|
20
20
|
// in an error (an `$inspect(object.property)` will run before the
|
|
21
21
|
// `{#if object}...{/if}` that contains it)
|
|
22
22
|
eager_effect(() => {
|
|
23
|
+
error = UNINITIALIZED;
|
|
24
|
+
|
|
23
25
|
try {
|
|
24
26
|
var value = get_value();
|
|
25
27
|
} catch (e) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @import { Blocker, TemplateNode, Value } from '#client' */
|
|
2
|
-
import { flatten
|
|
2
|
+
import { flatten } from '../../reactivity/async.js';
|
|
3
3
|
import { get } from '../../runtime.js';
|
|
4
4
|
import {
|
|
5
5
|
hydrate_next,
|
|
@@ -42,8 +42,6 @@ export function async(node, blockers = [], expressions = [], fn) {
|
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const decrement_pending = increment_pending();
|
|
46
|
-
|
|
47
45
|
if (was_hydrating) {
|
|
48
46
|
var previous_hydrate_node = hydrate_node;
|
|
49
47
|
set_hydrate_node(end);
|
|
@@ -64,8 +62,6 @@ export function async(node, blockers = [], expressions = [], fn) {
|
|
|
64
62
|
if (was_hydrating) {
|
|
65
63
|
set_hydrating(false);
|
|
66
64
|
}
|
|
67
|
-
|
|
68
|
-
decrement_pending();
|
|
69
65
|
}
|
|
70
66
|
});
|
|
71
67
|
}
|
|
@@ -35,19 +35,18 @@ import { queue_micro_task } from '../task.js';
|
|
|
35
35
|
import * as e from '../../errors.js';
|
|
36
36
|
import * as w from '../../warnings.js';
|
|
37
37
|
import { DEV } from 'esm-env';
|
|
38
|
-
import { Batch, current_batch
|
|
38
|
+
import { Batch, current_batch } from '../../reactivity/batch.js';
|
|
39
39
|
import { internal_set, source } from '../../reactivity/sources.js';
|
|
40
40
|
import { tag } from '../../dev/tracing.js';
|
|
41
41
|
import { createSubscriber } from '../../../../reactivity/create-subscriber.js';
|
|
42
42
|
import { create_text } from '../operations.js';
|
|
43
43
|
import { defer_effect } from '../../reactivity/utils.js';
|
|
44
|
-
import { set_signal_status } from '../../reactivity/status.js';
|
|
45
44
|
|
|
46
45
|
/**
|
|
47
46
|
* @typedef {{
|
|
48
|
-
* onerror?: (error: unknown, reset: () => void) => void;
|
|
49
|
-
* failed?: (anchor: Node, error: () => unknown, reset: () => () => void) => void;
|
|
50
|
-
* pending?: (anchor: Node) => void;
|
|
47
|
+
* onerror?: ((error: unknown, reset: () => void) => void) | null;
|
|
48
|
+
* failed?: ((anchor: Node, error: () => unknown, reset: () => () => void) => void) | null;
|
|
49
|
+
* pending?: ((anchor: Node) => void) | null;
|
|
51
50
|
* }} BoundaryProps
|
|
52
51
|
*/
|
|
53
52
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** @import { TemplateNode } from '#client' */
|
|
2
2
|
import { hydrate_node, hydrating, set_hydrate_node, set_hydrating } from '../hydration.js';
|
|
3
3
|
import { create_text, get_first_child, get_next_sibling } from '../operations.js';
|
|
4
|
-
import { block } from '../../reactivity/effects.js';
|
|
5
|
-
import { COMMENT_NODE,
|
|
4
|
+
import { block, branch } from '../../reactivity/effects.js';
|
|
5
|
+
import { COMMENT_NODE, HEAD_EFFECT } from '#client/constants';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {string} hash
|
|
@@ -49,9 +49,10 @@ export function head(hash, render_fn) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
block(() => {
|
|
53
|
+
var e = branch(() => render_fn(anchor));
|
|
54
|
+
e.f |= HEAD_EFFECT;
|
|
55
|
+
});
|
|
55
56
|
} finally {
|
|
56
57
|
if (was_hydrating) {
|
|
57
58
|
set_hydrating(true);
|
|
@@ -5,7 +5,12 @@ import { get_descriptors, get_prototype_of } from '../../../shared/utils.js';
|
|
|
5
5
|
import { create_event, delegate, delegated, event, event_symbol } from './events.js';
|
|
6
6
|
import { add_form_reset_listener, autofocus } from './misc.js';
|
|
7
7
|
import * as w from '../../warnings.js';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ATTRIBUTES_CACHE,
|
|
10
|
+
FORM_RESET_HANDLER,
|
|
11
|
+
IS_XHTML,
|
|
12
|
+
LOADING_ATTR_SYMBOL
|
|
13
|
+
} from '#client/constants';
|
|
9
14
|
import { queue_micro_task } from '../task.js';
|
|
10
15
|
import { is_capture_event, can_delegate_event, normalize_attribute } from '../../../../utils.js';
|
|
11
16
|
import {
|
|
@@ -69,8 +74,7 @@ export function remove_input_defaults(input) {
|
|
|
69
74
|
}
|
|
70
75
|
};
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
input.__on_r = remove_defaults;
|
|
77
|
+
/** @type {any} */ (input)[FORM_RESET_HANDLER] = remove_defaults;
|
|
74
78
|
queue_micro_task(remove_defaults);
|
|
75
79
|
add_form_reset_listener();
|
|
76
80
|
}
|
|
@@ -561,8 +565,7 @@ export function attribute_effect(
|
|
|
561
565
|
*/
|
|
562
566
|
function get_attributes(element) {
|
|
563
567
|
return /** @type {Record<string | symbol, unknown>} **/ (
|
|
564
|
-
|
|
565
|
-
element.__attributes ??= {
|
|
568
|
+
/** @type {any} */ (element)[ATTRIBUTES_CACHE] ??= {
|
|
566
569
|
[IS_CUSTOM_ELEMENT]: element.nodeName.includes('-'),
|
|
567
570
|
[IS_HTML]: element.namespaceURI === NAMESPACE_HTML
|
|
568
571
|
}
|
|
@@ -583,13 +586,19 @@ function get_setters(element) {
|
|
|
583
586
|
var proto = element; // In the case of custom elements there might be setters on the instance
|
|
584
587
|
var element_proto = Element.prototype;
|
|
585
588
|
|
|
586
|
-
// Stop at Element, from there on there's only unnecessary setters we're not interested in
|
|
587
|
-
// Do not use
|
|
589
|
+
// Stop at Element, from there on there's only unnecessary (and dangerous, like innerHTML) setters we're not interested in
|
|
590
|
+
// Do not use constructor.name here as that's unreliable in some browser environments
|
|
588
591
|
while (element_proto !== proto) {
|
|
589
592
|
descriptors = get_descriptors(proto);
|
|
590
593
|
|
|
591
594
|
for (var key in descriptors) {
|
|
592
|
-
if (
|
|
595
|
+
if (
|
|
596
|
+
descriptors[key].set &&
|
|
597
|
+
// better safe than sorry, we don't want spread attributes to mess with HTML content
|
|
598
|
+
key !== 'innerHTML' &&
|
|
599
|
+
key !== 'textContent' &&
|
|
600
|
+
key !== 'innerText'
|
|
601
|
+
) {
|
|
593
602
|
setters.push(key);
|
|
594
603
|
}
|
|
595
604
|
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
set_active_effect,
|
|
6
6
|
set_active_reaction
|
|
7
7
|
} from '../../../runtime.js';
|
|
8
|
+
import { FORM_RESET_HANDLER } from '../../../constants.js';
|
|
8
9
|
import { add_form_reset_listener } from '../misc.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -58,18 +59,15 @@ export function without_reactive_context(fn) {
|
|
|
58
59
|
*/
|
|
59
60
|
export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) {
|
|
60
61
|
element.addEventListener(event, () => without_reactive_context(handler));
|
|
61
|
-
|
|
62
|
-
const prev = element.__on_r;
|
|
62
|
+
const prev = /** @type {any} */ (element)[FORM_RESET_HANDLER];
|
|
63
63
|
if (prev) {
|
|
64
64
|
// special case for checkbox that can have multiple binds (group & checked)
|
|
65
|
-
|
|
66
|
-
element.__on_r = () => {
|
|
65
|
+
/** @type {any} */ (element)[FORM_RESET_HANDLER] = () => {
|
|
67
66
|
prev();
|
|
68
67
|
on_reset(true);
|
|
69
68
|
};
|
|
70
69
|
} else {
|
|
71
|
-
|
|
72
|
-
element.__on_r = () => on_reset(true);
|
|
70
|
+
/** @type {any} */ (element)[FORM_RESET_HANDLER] = () => on_reset(true);
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
add_form_reset_listener();
|
|
@@ -40,7 +40,7 @@ export function bind_this(element_or_component = {}, update, get_value, get_part
|
|
|
40
40
|
parts = get_parts?.() || [];
|
|
41
41
|
|
|
42
42
|
untrack(() => {
|
|
43
|
-
if (
|
|
43
|
+
if (!is_bound_this(get_value(...parts), element_or_component)) {
|
|
44
44
|
update(element_or_component, ...parts);
|
|
45
45
|
// If this is an effect rerun (cause: each block context changes), then nullify the binding at
|
|
46
46
|
// the previous position if it isn't already taken over by a different effect.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { to_class } from '../../../shared/attributes.js';
|
|
2
|
+
import { CLASS_CACHE } from '../../constants.js';
|
|
2
3
|
import { hydrating } from '../hydration.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -11,8 +12,7 @@ import { hydrating } from '../hydration.js';
|
|
|
11
12
|
* @returns {Record<string, boolean> | undefined}
|
|
12
13
|
*/
|
|
13
14
|
export function set_class(dom, is_html, value, hash, prev_classes, next_classes) {
|
|
14
|
-
|
|
15
|
-
var prev = dom.__className;
|
|
15
|
+
var prev = /** @type {any} */ (dom)[CLASS_CACHE];
|
|
16
16
|
|
|
17
17
|
if (
|
|
18
18
|
hydrating ||
|
|
@@ -35,8 +35,7 @@ export function set_class(dom, is_html, value, hash, prev_classes, next_classes)
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
dom.__className = value;
|
|
38
|
+
/** @type {any} */ (dom)[CLASS_CACHE] = value;
|
|
40
39
|
} else if (next_classes && prev_classes !== next_classes) {
|
|
41
40
|
for (var key in next_classes) {
|
|
42
41
|
var is_present = !!next_classes[key];
|
|
@@ -237,9 +237,9 @@ export function handle_event_propagation(event) {
|
|
|
237
237
|
});
|
|
238
238
|
|
|
239
239
|
// This started because of Chromium issue https://chromestatus.com/feature/5128696823545856,
|
|
240
|
-
// where removal or moving of
|
|
240
|
+
// where removal or moving of the DOM can cause sync `blur` events to fire, which can cause logic
|
|
241
241
|
// to run inside the current `active_reaction`, which isn't what we want at all. However, on reflection,
|
|
242
|
-
// it's probably best that all
|
|
242
|
+
// it's probably best that all events handled by Svelte have this behaviour, as we don't really want
|
|
243
243
|
// an event handler to run in the context of another reaction or effect.
|
|
244
244
|
var previous_reaction = active_reaction;
|
|
245
245
|
var previous_effect = active_effect;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hydrating } from '../hydration.js';
|
|
2
2
|
import { clear_text_content, get_first_child } from '../operations.js';
|
|
3
3
|
import { queue_micro_task } from '../task.js';
|
|
4
|
+
import { FORM_RESET_HANDLER } from '../../constants.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* @param {HTMLElement} dom
|
|
@@ -45,8 +46,7 @@ export function add_form_reset_listener() {
|
|
|
45
46
|
Promise.resolve().then(() => {
|
|
46
47
|
if (!evt.defaultPrevented) {
|
|
47
48
|
for (const e of /**@type {HTMLFormElement} */ (evt.target).elements) {
|
|
48
|
-
|
|
49
|
-
e.__on_r?.();
|
|
49
|
+
/** @type {any} */ (e)[FORM_RESET_HANDLER]?.();
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { to_style } from '../../../shared/attributes.js';
|
|
2
|
+
import { STYLE_CACHE } from '../../constants.js';
|
|
2
3
|
import { hydrating } from '../hydration.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -28,8 +29,7 @@ function update_styles(dom, prev = {}, next, priority) {
|
|
|
28
29
|
* @param {Record<string, any> | [Record<string, any>, Record<string, any>]} [next_styles]
|
|
29
30
|
*/
|
|
30
31
|
export function set_style(dom, value, prev_styles, next_styles) {
|
|
31
|
-
|
|
32
|
-
var prev = dom.__style;
|
|
32
|
+
var prev = /** @type {any} */ (dom)[STYLE_CACHE];
|
|
33
33
|
|
|
34
34
|
if (hydrating || prev !== value) {
|
|
35
35
|
var next_style_attr = to_style(value, next_styles);
|
|
@@ -42,8 +42,7 @@ export function set_style(dom, value, prev_styles, next_styles) {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
dom.__style = value;
|
|
45
|
+
/** @type {any} */ (dom)[STYLE_CACHE] = value;
|
|
47
46
|
} else if (next_styles) {
|
|
48
47
|
if (Array.isArray(next_styles)) {
|
|
49
48
|
update_styles(dom, prev_styles?.[0], next_styles[0]);
|
|
@@ -5,7 +5,14 @@ import { init_array_prototype_warnings } from '../dev/equality.js';
|
|
|
5
5
|
import { get_descriptor, is_extensible } from '../../shared/utils.js';
|
|
6
6
|
import { active_effect } from '../runtime.js';
|
|
7
7
|
import { async_mode_flag } from '../../flags/index.js';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ATTRIBUTES_CACHE,
|
|
10
|
+
CLASS_CACHE,
|
|
11
|
+
REACTION_RAN,
|
|
12
|
+
STYLE_CACHE,
|
|
13
|
+
TEXT_CACHE,
|
|
14
|
+
TEXT_NODE
|
|
15
|
+
} from '#client/constants';
|
|
9
16
|
import { eager_block_effects } from '../reactivity/batch.js';
|
|
10
17
|
import { NAMESPACE_HTML } from '../../../constants.js';
|
|
11
18
|
|
|
@@ -48,21 +55,15 @@ export function init_operations() {
|
|
|
48
55
|
|
|
49
56
|
if (is_extensible(element_prototype)) {
|
|
50
57
|
// the following assignments improve perf of lookups on DOM nodes
|
|
51
|
-
|
|
52
|
-
element_prototype
|
|
53
|
-
|
|
54
|
-
element_prototype.__className = undefined;
|
|
55
|
-
// @ts-expect-error
|
|
56
|
-
element_prototype.__attributes = null;
|
|
57
|
-
// @ts-expect-error
|
|
58
|
-
element_prototype.__style = undefined;
|
|
58
|
+
/** @type {any} */ (element_prototype)[CLASS_CACHE] = undefined;
|
|
59
|
+
/** @type {any} */ (element_prototype)[ATTRIBUTES_CACHE] = null;
|
|
60
|
+
/** @type {any} */ (element_prototype)[STYLE_CACHE] = undefined;
|
|
59
61
|
// @ts-expect-error
|
|
60
62
|
element_prototype.__e = undefined;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
if (is_extensible(text_prototype)) {
|
|
64
|
-
|
|
65
|
-
text_prototype.__t = undefined;
|
|
66
|
+
/** @type {any} */ (text_prototype)[TEXT_CACHE] = undefined;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
if (DEV) {
|
|
@@ -55,33 +55,38 @@ export function flatten(blockers, sync, async, fn) {
|
|
|
55
55
|
|
|
56
56
|
/** @param {Value[]} values */
|
|
57
57
|
function finish(values) {
|
|
58
|
+
if ((parent.f & DESTROYED) !== 0) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
restore();
|
|
59
63
|
|
|
60
64
|
try {
|
|
61
65
|
fn(values);
|
|
62
66
|
} catch (error) {
|
|
63
|
-
|
|
64
|
-
invoke_error_boundary(error, parent);
|
|
65
|
-
}
|
|
67
|
+
invoke_error_boundary(error, parent);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
unset_context();
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
var decrement_pending = increment_pending();
|
|
74
|
+
|
|
71
75
|
// Fast path: blockers but no async expressions
|
|
72
76
|
if (async.length === 0) {
|
|
73
|
-
/** @type {Promise<any>} */ (blocker_promise)
|
|
77
|
+
/** @type {Promise<any>} */ (blocker_promise)
|
|
78
|
+
.then(() => finish(sync.map(d)))
|
|
79
|
+
.finally(decrement_pending);
|
|
80
|
+
|
|
74
81
|
return;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
|
-
var decrement_pending = increment_pending();
|
|
78
|
-
|
|
79
84
|
// Full path: has async expressions
|
|
80
85
|
function run() {
|
|
81
86
|
Promise.all(async.map((expression) => async_derived(expression)))
|
|
82
87
|
.then((result) => finish([...sync.map(d), ...result]))
|
|
83
88
|
.catch((error) => invoke_error_boundary(error, parent))
|
|
84
|
-
.finally(
|
|
89
|
+
.finally(decrement_pending);
|
|
85
90
|
}
|
|
86
91
|
|
|
87
92
|
if (blocker_promise) {
|
|
@@ -213,22 +218,35 @@ export async function* for_await_track_reactivity_loss(iterable) {
|
|
|
213
218
|
throw new TypeError('value is not async iterable');
|
|
214
219
|
}
|
|
215
220
|
|
|
216
|
-
|
|
217
|
-
let
|
|
221
|
+
// eslint-disable-next-line no-useless-assignment
|
|
222
|
+
let invoke_return = true;
|
|
223
|
+
|
|
218
224
|
try {
|
|
219
225
|
while (true) {
|
|
220
226
|
const { done, value } = (await track_reactivity_loss(iterator.next()))();
|
|
221
227
|
if (done) {
|
|
222
|
-
|
|
228
|
+
invoke_return = false;
|
|
223
229
|
break;
|
|
224
230
|
}
|
|
225
231
|
var prev = reactivity_loss_tracker;
|
|
226
|
-
|
|
232
|
+
try {
|
|
233
|
+
yield value;
|
|
234
|
+
} catch (e) {
|
|
235
|
+
set_reactivity_loss_tracker(prev);
|
|
236
|
+
// If the yield throws, we need to call `return` but not return its value, instead rethrow
|
|
237
|
+
if (iterator.return !== undefined) {
|
|
238
|
+
(await track_reactivity_loss(iterator.return()))();
|
|
239
|
+
}
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
227
242
|
set_reactivity_loss_tracker(prev);
|
|
228
243
|
}
|
|
244
|
+
} catch (error) {
|
|
245
|
+
invoke_return = false;
|
|
246
|
+
throw error;
|
|
229
247
|
} finally {
|
|
230
|
-
// If the iterator had an abrupt completion and `return` is defined on the iterator, call it and return the value
|
|
231
|
-
if (
|
|
248
|
+
// If the iterator had an abrupt completion (break) and `return` is defined on the iterator, call it and return the value
|
|
249
|
+
if (invoke_return && iterator.return !== undefined) {
|
|
232
250
|
// eslint-disable-next-line no-unsafe-finally
|
|
233
251
|
return /** @type {TReturn} */ ((await track_reactivity_loss(iterator.return()))().value);
|
|
234
252
|
}
|
|
@@ -310,7 +328,7 @@ export function run(thunks) {
|
|
|
310
328
|
// wait one more tick, so that template effects are
|
|
311
329
|
// guaranteed to run before `$effect(...)`
|
|
312
330
|
.then(() => Promise.resolve())
|
|
313
|
-
.finally(
|
|
331
|
+
.finally(decrement_pending);
|
|
314
332
|
|
|
315
333
|
return blockers;
|
|
316
334
|
}
|
|
@@ -334,8 +352,8 @@ export function increment_pending() {
|
|
|
334
352
|
boundary.update_pending_count(1, batch);
|
|
335
353
|
batch.increment(blocking, effect);
|
|
336
354
|
|
|
337
|
-
return (
|
|
355
|
+
return () => {
|
|
338
356
|
boundary.update_pending_count(-1, batch);
|
|
339
|
-
batch.decrement(blocking, effect
|
|
357
|
+
batch.decrement(blocking, effect);
|
|
340
358
|
};
|
|
341
359
|
}
|