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.
Files changed (81) hide show
  1. package/compiler/index.js +1 -1
  2. package/elements.d.ts +3 -0
  3. package/package.json +3 -3
  4. package/src/compiler/phases/1-parse/acorn.js +1 -1
  5. package/src/compiler/phases/1-parse/utils/html.js +12 -7
  6. package/src/compiler/phases/2-analyze/css/css-prune.js +10 -0
  7. package/src/compiler/phases/2-analyze/index.js +26 -3
  8. package/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +10 -4
  9. package/src/compiler/phases/2-analyze/visitors/CallExpression.js +1 -1
  10. package/src/compiler/phases/2-analyze/visitors/DeclarationTag.js +2 -1
  11. package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +10 -10
  12. package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +4 -4
  13. package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +4 -4
  14. package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +4 -4
  15. package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +14 -2
  16. package/src/compiler/phases/2-analyze/visitors/shared/element.js +2 -8
  17. package/src/compiler/phases/2-analyze/visitors/shared/utils.js +23 -1
  18. package/src/compiler/phases/3-transform/client/transform-client.js +2 -2
  19. package/src/compiler/phases/3-transform/client/transform-template/index.js +6 -0
  20. package/src/compiler/phases/3-transform/client/utils.js +35 -8
  21. package/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +6 -6
  22. package/src/compiler/phases/3-transform/client/visitors/BindDirective.js +10 -13
  23. package/src/compiler/phases/3-transform/client/visitors/ConstTag.js +19 -8
  24. package/src/compiler/phases/3-transform/client/visitors/DeclarationTag.js +3 -2
  25. package/src/compiler/phases/3-transform/client/visitors/EachBlock.js +4 -1
  26. package/src/compiler/phases/3-transform/client/visitors/Fragment.js +2 -7
  27. package/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +2 -1
  28. package/src/compiler/phases/3-transform/client/visitors/IfBlock.js +2 -1
  29. package/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +2 -1
  30. package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +106 -44
  31. package/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +2 -1
  32. package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +11 -4
  33. package/src/compiler/phases/3-transform/client/visitors/shared/element.js +6 -1
  34. package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +1 -6
  35. package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +5 -5
  36. package/src/compiler/phases/3-transform/server/transform-server.js +20 -9
  37. package/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +1 -1
  38. package/src/compiler/phases/3-transform/server/visitors/DeclarationTag.js +1 -1
  39. package/src/compiler/phases/3-transform/server/visitors/EachBlock.js +8 -2
  40. package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +4 -4
  41. package/src/compiler/phases/3-transform/server/visitors/RegularElement.js +1 -1
  42. package/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +9 -4
  43. package/src/compiler/phases/3-transform/server/visitors/shared/element.js +5 -4
  44. package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +30 -0
  45. package/src/compiler/phases/bindings.js +3 -1
  46. package/src/compiler/phases/nodes.js +4 -0
  47. package/src/compiler/print/index.js +21 -16
  48. package/src/easing/index.js +62 -0
  49. package/src/internal/client/constants.js +9 -0
  50. package/src/internal/client/context.js +15 -5
  51. package/src/internal/client/dev/hmr.js +15 -4
  52. package/src/internal/client/dom/blocks/boundary.js +21 -12
  53. package/src/internal/client/dom/blocks/slot.js +19 -0
  54. package/src/internal/client/dom/blocks/svelte-head.js +8 -0
  55. package/src/internal/client/dom/elements/attributes.js +35 -34
  56. package/src/internal/client/dom/elements/bindings/select.js +99 -9
  57. package/src/internal/client/dom/elements/bindings/this.js +7 -2
  58. package/src/internal/client/dom/elements/transitions.js +81 -68
  59. package/src/internal/client/dom/operations.js +21 -1
  60. package/src/internal/client/error-handling.js +10 -2
  61. package/src/internal/client/index.js +9 -2
  62. package/src/internal/client/proxy.js +8 -3
  63. package/src/internal/client/reactivity/async.js +23 -3
  64. package/src/internal/client/reactivity/effects.js +14 -1
  65. package/src/internal/client/render.js +4 -8
  66. package/src/internal/client/runtime.js +45 -33
  67. package/src/internal/client/warnings.js +0 -11
  68. package/src/internal/server/abort-signal.js +8 -9
  69. package/src/internal/server/context.js +2 -2
  70. package/src/internal/server/index.js +1 -1
  71. package/src/internal/server/renderer.js +163 -52
  72. package/src/internal/shared/attributes.js +2 -1
  73. package/src/internal/shared/clone.js +2 -0
  74. package/src/internal/shared/context.js +3 -2
  75. package/src/legacy/legacy-server.js +1 -1
  76. package/src/reactivity/map.js +22 -0
  77. package/src/reactivity/url.js +2 -0
  78. package/src/transition/index.js +18 -7
  79. package/src/version.js +1 -1
  80. package/types/index.d.ts +135 -37
  81. package/types/index.d.ts.map +2 -2
@@ -1,4 +1,4 @@
1
- /** @import { BlockStatement } from 'estree' */
1
+ /** @import { BlockStatement, Statement } from 'estree' */
2
2
  /** @import { AST } from '#compiler' */
3
3
  /** @import { ComponentContext } from '../types' */
4
4
  import * as b from '#compiler/builders';
@@ -84,6 +84,9 @@ export function SvelteBoundary(node, context) {
84
84
  }
85
85
 
86
86
  const props = b.object([]);
87
+ /** @type {Statement[]} */
88
+ const init = [];
89
+
87
90
  if (failed_attribute && !failed_snippet) {
88
91
  const failed_callee = build_attribute_value(
89
92
  failed_attribute.value,
@@ -95,13 +98,15 @@ export function SvelteBoundary(node, context) {
95
98
 
96
99
  props.properties.push(b.init('failed', failed_callee));
97
100
  } else if (failed_snippet) {
98
- context.visit(failed_snippet, context.state);
101
+ context.visit(failed_snippet, { ...context.state, init });
99
102
  props.properties.push(b.init('failed', failed_snippet.expression));
100
103
  }
101
104
 
102
- context.state.template.push(
103
- b.stmt(b.call('$$renderer.boundary', props, b.arrow([b.id('$$renderer')], children_body)))
105
+ const boundary = b.stmt(
106
+ b.call('$$renderer.boundary', props, b.arrow([b.id('$$renderer')], children_body))
104
107
  );
108
+
109
+ context.state.template.push(init.length > 0 ? b.block([...init, boundary]) : boundary);
105
110
  }
106
111
 
107
112
  /**
@@ -306,12 +306,14 @@ function get_attribute_name(element, attribute) {
306
306
  * @param {(expression: Expression, metadata: ExpressionMetadata) => Expression} transform
307
307
  */
308
308
  export function build_spread_object(element, attributes, context, transform) {
309
+ const is_select = element.type === 'RegularElement' && element.name === 'select';
309
310
  const object = b.object(
310
311
  attributes.map((attribute) => {
311
312
  if (attribute.type === 'transformed') {
312
313
  return b.prop('init', b.key(attribute.name), attribute.expression);
313
314
  } else if (attribute.type === 'Attribute') {
314
- const name = get_attribute_name(element, attribute);
315
+ let name = get_attribute_name(element, attribute);
316
+ if (is_select && name === 'defaultvalue') name = 'defaultValue';
315
317
  const value = build_attribute_value(
316
318
  attribute.value,
317
319
  context,
@@ -322,10 +324,9 @@ export function build_spread_object(element, attributes, context, transform) {
322
324
  return b.prop('init', b.key(name), value);
323
325
  } else if (attribute.type === 'BindDirective') {
324
326
  const name = get_attribute_name(element, attribute);
327
+ const expression = /** @type {Expression} */ (context.visit(attribute.expression));
325
328
  const value =
326
- attribute.expression.type === 'SequenceExpression'
327
- ? b.call(attribute.expression.expressions[0])
328
- : /** @type {Expression} */ (context.visit(attribute.expression));
329
+ expression.type === 'SequenceExpression' ? b.call(expression.expressions[0]) : expression;
329
330
 
330
331
  return b.prop('init', b.key(name), value);
331
332
  }
@@ -180,6 +180,36 @@ export function build_template(template) {
180
180
  return statements;
181
181
  }
182
182
 
183
+ /**
184
+ * Prepends a hydration marker (e.g. `<!--[0-->`) to a branch. The branch has already been
185
+ * turned into statements by `build_template`, so if it happens to start with a static
186
+ * `$$renderer.push(...)` we fold the marker into that call rather than emitting a second one.
187
+ * @param {BlockStatement} block
188
+ * @param {string} marker
189
+ */
190
+ export function prepend_block_marker(block, marker) {
191
+ const first = block.body[0];
192
+
193
+ if (
194
+ first?.type === 'ExpressionStatement' &&
195
+ first.expression.type === 'CallExpression' &&
196
+ first.expression.callee.type === 'Identifier' &&
197
+ first.expression.callee.name === '$$renderer.push' &&
198
+ first.expression.arguments.length === 1 &&
199
+ first.expression.arguments[0].type === 'TemplateLiteral'
200
+ ) {
201
+ const quasi = first.expression.arguments[0].quasis[0];
202
+
203
+ // markers never contain characters that need escaping in a template literal
204
+ quasi.value.cooked = marker + quasi.value.cooked;
205
+ quasi.value.raw = marker + quasi.value.raw;
206
+
207
+ return;
208
+ }
209
+
210
+ block.body.unshift(b.stmt(b.call(b.id('$$renderer.push'), b.literal(marker))));
211
+ }
212
+
183
213
  /**
184
214
  *
185
215
  * @param {AST.Attribute['value']} value
@@ -23,7 +23,9 @@ export const binding_properties = {
23
23
  event: 'durationchange',
24
24
  omit_in_ssr: true
25
25
  },
26
- focused: {},
26
+ focused: {
27
+ omit_in_ssr: true // no corresponding HTML attribute
28
+ },
27
29
  paused: {
28
30
  valid_elements: ['audio', 'video'],
29
31
  omit_in_ssr: true,
@@ -77,6 +77,9 @@ export class ExpressionMetadata {
77
77
  /** True if the expression contains `await` */
78
78
  has_await = false;
79
79
 
80
+ /** True if an `await` restores the reaction context afterwards, so the thunk must end it */
81
+ has_pickled_await = false;
82
+
80
83
  /** True if the expression includes a member expression */
81
84
  has_member_expression = false;
82
85
 
@@ -142,6 +145,7 @@ export class ExpressionMetadata {
142
145
  this.has_state ||= source.has_state;
143
146
  this.has_call ||= source.has_call;
144
147
  this.has_await ||= source.has_await;
148
+ this.has_pickled_await ||= source.has_pickled_await;
145
149
  this.has_member_expression ||= source.has_member_expression;
146
150
  this.has_assignment ||= source.has_assignment;
147
151
  this.#blockers = null; // so that blockers are recalculated
@@ -587,15 +587,19 @@ const svelte_visitors = (comments, state) => ({
587
587
  last?.type === 'Text' &&
588
588
  /\s$/.test(last.data);
589
589
 
590
- /** @type {AST.SvelteNode[][]} */
590
+ /** @type {{ nodes: AST.SvelteNode[]; leading_whitespace: boolean }[]} */
591
591
  const items = [];
592
592
 
593
593
  /** @type {AST.SvelteNode[]} */
594
594
  let sequence = [];
595
+ let leading_whitespace = false;
595
596
 
596
597
  const flush = () => {
597
- items.push(sequence);
598
- sequence = [];
598
+ if (sequence.length > 0) {
599
+ items.push({ nodes: sequence, leading_whitespace });
600
+ sequence = [];
601
+ leading_whitespace = false;
602
+ }
599
603
  };
600
604
 
601
605
  for (let i = 0; i < node.nodes.length; i += 1) {
@@ -624,6 +628,7 @@ const svelte_visitors = (comments, state) => ({
624
628
 
625
629
  if (child_node.data.startsWith(' ') && prev && prev.type !== 'ExpressionTag') {
626
630
  flush();
631
+ leading_whitespace = true;
627
632
  child_node.data = child_node.data.trimStart();
628
633
  }
629
634
 
@@ -662,20 +667,18 @@ const svelte_visitors = (comments, state) => ({
662
667
  let multiline = false;
663
668
  let width = 0;
664
669
 
665
- const child_contexts = items
666
- .filter((x) => x.length > 0)
667
- .map((sequence) => {
668
- const child_context = context.new();
670
+ const child_contexts = items.map(({ nodes, leading_whitespace }) => {
671
+ const child_context = context.new();
669
672
 
670
- for (const node of sequence) {
671
- child_context.visit(node);
672
- multiline ||= child_context.multiline;
673
- }
673
+ for (const node of nodes) {
674
+ child_context.visit(node);
675
+ multiline ||= child_context.multiline;
676
+ }
674
677
 
675
- width += child_context.measure();
678
+ width += child_context.measure() + (leading_whitespace ? 1 : 0);
676
679
 
677
- return child_context;
678
- });
680
+ return { context: child_context, leading_whitespace };
681
+ });
679
682
 
680
683
  multiline ||= width > LINE_BREAK_THRESHOLD;
681
684
  // Normally context.newline() also makes context.multiline true, but the below loop only
@@ -687,14 +690,16 @@ const svelte_visitors = (comments, state) => ({
687
690
  const prev = child_contexts[i];
688
691
  const next = child_contexts[i + 1];
689
692
 
690
- context.append(prev);
693
+ context.append(prev.context);
691
694
 
692
695
  if (next) {
693
- if (prev.multiline || next.multiline) {
696
+ if (prev.context.multiline || next.context.multiline) {
694
697
  context.margin();
695
698
  context.newline();
696
699
  } else if (multiline) {
697
700
  context.newline();
701
+ } else if (next.leading_whitespace) {
702
+ context.write(' ');
698
703
  }
699
704
  }
700
705
  }
@@ -4,6 +4,8 @@ Distributed under MIT License https://github.com/mattdesl/eases/blob/master/LICE
4
4
  */
5
5
 
6
6
  /**
7
+ * Returns value as is.
8
+ *
7
9
  * @param {number} t
8
10
  * @returns {number}
9
11
  */
@@ -12,6 +14,8 @@ export function linear(t) {
12
14
  }
13
15
 
14
16
  /**
17
+ * Rebound effect on start and end of value range.
18
+ *
15
19
  * @param {number} t
16
20
  * @returns {number}
17
21
  */
@@ -22,6 +26,8 @@ export function backInOut(t) {
22
26
  }
23
27
 
24
28
  /**
29
+ * Rebound effect on start.
30
+ *
25
31
  * @param {number} t
26
32
  * @returns {number}
27
33
  */
@@ -31,6 +37,8 @@ export function backIn(t) {
31
37
  }
32
38
 
33
39
  /**
40
+ * Rebound effect on end.
41
+ *
34
42
  * @param {number} t
35
43
  * @returns {number}
36
44
  */
@@ -40,6 +48,8 @@ export function backOut(t) {
40
48
  }
41
49
 
42
50
  /**
51
+ * Bounce effect on end.
52
+ *
43
53
  * @param {number} t
44
54
  * @returns {number}
45
55
  */
@@ -61,6 +71,8 @@ export function bounceOut(t) {
61
71
  }
62
72
 
63
73
  /**
74
+ * Bounce effect on start and end.
75
+ *
64
76
  * @param {number} t
65
77
  * @returns {number}
66
78
  */
@@ -69,6 +81,8 @@ export function bounceInOut(t) {
69
81
  }
70
82
 
71
83
  /**
84
+ * Bounce effect on start.
85
+ *
72
86
  * @param {number} t
73
87
  * @returns {number}
74
88
  */
@@ -77,6 +91,8 @@ export function bounceIn(t) {
77
91
  }
78
92
 
79
93
  /**
94
+ * Circular effect, accelerate on start, decelerate towards end.
95
+ *
80
96
  * @param {number} t
81
97
  * @returns {number}
82
98
  */
@@ -86,6 +102,8 @@ export function circInOut(t) {
86
102
  }
87
103
 
88
104
  /**
105
+ * Circular effect, accelerate on start.
106
+ *
89
107
  * @param {number} t
90
108
  * @returns {number}
91
109
  */
@@ -94,6 +112,8 @@ export function circIn(t) {
94
112
  }
95
113
 
96
114
  /**
115
+ * Circular effect, decelerate towards end.
116
+ *
97
117
  * @param {number} t
98
118
  * @returns {number}
99
119
  */
@@ -102,6 +122,8 @@ export function circOut(t) {
102
122
  }
103
123
 
104
124
  /**
125
+ * Cubic scaling, accelerate on start, decelerate towards end.
126
+ *
105
127
  * @param {number} t
106
128
  * @returns {number}
107
129
  */
@@ -110,6 +132,8 @@ export function cubicInOut(t) {
110
132
  }
111
133
 
112
134
  /**
135
+ * Cubic scaling, accelerate on start
136
+ *
113
137
  * @param {number} t
114
138
  * @returns {number}
115
139
  */
@@ -118,6 +142,8 @@ export function cubicIn(t) {
118
142
  }
119
143
 
120
144
  /**
145
+ * Cubic scaling, decelerate towards end.
146
+ *
121
147
  * @param {number} t
122
148
  * @returns {number}
123
149
  */
@@ -127,6 +153,8 @@ export function cubicOut(t) {
127
153
  }
128
154
 
129
155
  /**
156
+ * Elastic effect on start and end.
157
+ *
130
158
  * @param {number} t
131
159
  * @returns {number}
132
160
  */
@@ -140,6 +168,8 @@ export function elasticInOut(t) {
140
168
  }
141
169
 
142
170
  /**
171
+ * Elastic effect on start.
172
+ *
143
173
  * @param {number} t
144
174
  * @returns {number}
145
175
  */
@@ -148,6 +178,8 @@ export function elasticIn(t) {
148
178
  }
149
179
 
150
180
  /**
181
+ * Elastic effect on end.
182
+ *
151
183
  * @param {number} t
152
184
  * @returns {number}
153
185
  */
@@ -156,6 +188,8 @@ export function elasticOut(t) {
156
188
  }
157
189
 
158
190
  /**
191
+ * Exponential effect on start and end.
192
+ *
159
193
  * @param {number} t
160
194
  * @returns {number}
161
195
  */
@@ -168,6 +202,8 @@ export function expoInOut(t) {
168
202
  }
169
203
 
170
204
  /**
205
+ * Exponential effect on start.
206
+ *
171
207
  * @param {number} t
172
208
  * @returns {number}
173
209
  */
@@ -176,6 +212,8 @@ export function expoIn(t) {
176
212
  }
177
213
 
178
214
  /**
215
+ * Exponential effect on end.
216
+ *
179
217
  * @param {number} t
180
218
  * @returns {number}
181
219
  */
@@ -184,6 +222,8 @@ export function expoOut(t) {
184
222
  }
185
223
 
186
224
  /**
225
+ * Quadratic scaling, accelerate on start, decelerate towards end.
226
+ *
187
227
  * @param {number} t
188
228
  * @returns {number}
189
229
  */
@@ -195,6 +235,8 @@ export function quadInOut(t) {
195
235
  }
196
236
 
197
237
  /**
238
+ * Quadratic scaling, accelerate on start.
239
+ *
198
240
  * @param {number} t
199
241
  * @returns {number}
200
242
  */
@@ -203,6 +245,8 @@ export function quadIn(t) {
203
245
  }
204
246
 
205
247
  /**
248
+ * Quadratic scaling, decelerate towards end.
249
+ *
206
250
  * @param {number} t
207
251
  * @returns {number}
208
252
  */
@@ -211,6 +255,8 @@ export function quadOut(t) {
211
255
  }
212
256
 
213
257
  /**
258
+ * Quartic scaling, accelerate on start, decelerate towards end.
259
+ *
214
260
  * @param {number} t
215
261
  * @returns {number}
216
262
  */
@@ -219,6 +265,8 @@ export function quartInOut(t) {
219
265
  }
220
266
 
221
267
  /**
268
+ * Quartic scaling, accelerate on start.
269
+ *
222
270
  * @param {number} t
223
271
  * @returns {number}
224
272
  */
@@ -227,6 +275,8 @@ export function quartIn(t) {
227
275
  }
228
276
 
229
277
  /**
278
+ * Quartic scaling, decelerate towards end.
279
+ *
230
280
  * @param {number} t
231
281
  * @returns {number}
232
282
  */
@@ -235,6 +285,8 @@ export function quartOut(t) {
235
285
  }
236
286
 
237
287
  /**
288
+ * Quintic scaling, accelerate on start, decelerate towards end.
289
+ *
238
290
  * @param {number} t
239
291
  * @returns {number}
240
292
  */
@@ -244,6 +296,8 @@ export function quintInOut(t) {
244
296
  }
245
297
 
246
298
  /**
299
+ * Quintic scaling, accelerate on start.
300
+ *
247
301
  * @param {number} t
248
302
  * @returns {number}
249
303
  */
@@ -252,6 +306,8 @@ export function quintIn(t) {
252
306
  }
253
307
 
254
308
  /**
309
+ * Quintic scaling, decelerate towards end.
310
+ *
255
311
  * @param {number} t
256
312
  * @returns {number}
257
313
  */
@@ -260,6 +316,8 @@ export function quintOut(t) {
260
316
  }
261
317
 
262
318
  /**
319
+ * Sinusoidal effect, accelerate on start, decelerate towards end.
320
+ *
263
321
  * @param {number} t
264
322
  * @returns {number}
265
323
  */
@@ -268,6 +326,8 @@ export function sineInOut(t) {
268
326
  }
269
327
 
270
328
  /**
329
+ * Sinusoidal effect, accelerate on start.
330
+ *
271
331
  * @param {number} t
272
332
  * @returns {number}
273
333
  */
@@ -278,6 +338,8 @@ export function sineIn(t) {
278
338
  }
279
339
 
280
340
  /**
341
+ * Sinusoidal effect, decelerate towards end.
342
+ *
281
343
  * @param {number} t
282
344
  * @returns {number}
283
345
  */
@@ -15,6 +15,13 @@ export const BLOCK_EFFECT = 1 << 4;
15
15
  export const BRANCH_EFFECT = 1 << 5;
16
16
  export const ROOT_EFFECT = 1 << 6;
17
17
  export const BOUNDARY_EFFECT = 1 << 7;
18
+ /**
19
+ * Set on the effect that `pause_effect` was called on, i.e. the root of a paused subtree,
20
+ * as opposed to its descendants which are merely `INERT`. This allows `resume_effect` on
21
+ * an ancestor to skip subtrees that were paused for their own reasons (such as a block
22
+ * whose condition is still false) rather than resurrecting them
23
+ */
24
+ export const PAUSED = 1 << 8;
18
25
  /**
19
26
  * Indicates that a reaction is connected to an effect root — either it is an effect,
20
27
  * or it is a derived that is depended on by at least one effect. If a derived has
@@ -60,6 +67,8 @@ export const ASYNC = 1 << 22;
60
67
  export const ERROR_VALUE = 1 << 23;
61
68
 
62
69
  export const STATE_SYMBOL = Symbol('$state');
70
+ /** Marks component export objects, so that `proxy(...)` leaves them untouched */
71
+ export const COMPONENT_SYMBOL = Symbol('component');
63
72
  export const LEGACY_PROPS = Symbol('legacy props');
64
73
  export const LOADING_ATTR_SYMBOL = Symbol('');
65
74
  export const PROXY_PATH_SYMBOL = Symbol('proxy path');
@@ -5,7 +5,8 @@ import { active_effect, active_reaction } from './runtime.js';
5
5
  import { create_user_effect } from './reactivity/effects.js';
6
6
  import { async_mode_flag, legacy_mode_flag } from '../flags/index.js';
7
7
  import { FILENAME } from '../../constants.js';
8
- import { BRANCH_EFFECT } from './constants.js';
8
+ import { BRANCH_EFFECT, COMPONENT_SYMBOL } from './constants.js';
9
+ import { define_property } from '../shared/utils.js';
9
10
  import { create_context, get_or_init_context_map } from '../shared/context.js';
10
11
 
11
12
  /** @type {ComponentContext | null} */
@@ -71,17 +72,17 @@ export function set_dev_current_component_function(fn) {
71
72
  }
72
73
 
73
74
  /**
74
- * Returns a `[get, set]` pair of functions for working with context in a type-safe way.
75
+ * Returns a `[get, set, has]` triplet of functions for working with context in a type-safe way.
75
76
  *
76
77
  * `get` will throw an error if `set` has not yet been called in the current component or any of
77
78
  * its ancestors.
78
79
  *
79
80
  * @template T
80
- * @returns {[() => T, (context: T) => T]}
81
+ * @returns {[() => T, (context: T) => T, () => boolean]}
81
82
  * @since 5.40.0
82
83
  */
83
84
  export function createContext() {
84
- return /** @type {[() => T, (context: T) => T]} */ (
85
+ return /** @type {[() => T, (context: T) => T, () => boolean]} */ (
85
86
  create_context(getContext, setContext, hasContext)
86
87
  );
87
88
  }
@@ -217,7 +218,16 @@ export function pop(component) {
217
218
  dev_current_component_function = component_context?.function ?? null;
218
219
  }
219
220
 
220
- return component ?? /** @type {T} */ ({});
221
+ return mark_as_component(component);
222
+ }
223
+
224
+ /**
225
+ * Add a symbol to the object (or create one if undefined) to mark it as a component so it isn't proxified.
226
+ * @param {any} component
227
+ */
228
+ export function mark_as_component(component = {}) {
229
+ define_property(component, COMPONENT_SYMBOL, { value: true });
230
+ return component;
221
231
  }
222
232
 
223
233
  /** @returns {boolean} */
@@ -57,10 +57,21 @@ export function hmr(fn) {
57
57
  if (ran) set_should_intro(true);
58
58
  });
59
59
 
60
- // Forward the nodes from the inner effect to the outer active effect which would
61
- // get them if the HMR wrapper wasn't there. Do this inside the block not outside
62
- // so that HMR updates to the component will also update the nodes on the active effect.
63
- /** @type {Effect} */ (active_effect).nodes = effect.nodes;
60
+ // Forward the start/end DOM nodes from the inner effect to the outer active effect
61
+ // which would get them if the HMR wrapper wasn't there. Do this inside the block not
62
+ // outside so that HMR updates to the component will also update the nodes on the
63
+ // active effect. We copy only start/end, not the full nodes object, so that
64
+ // pause_children does not collect transitions from both effects and fire outroend twice.
65
+ var inner_nodes = effect.nodes;
66
+ if (inner_nodes) {
67
+ var ae = /** @type {Effect} */ (active_effect);
68
+ if (ae.nodes) {
69
+ ae.nodes.start = inner_nodes.start;
70
+ ae.nodes.end = inner_nodes.end;
71
+ } else {
72
+ ae.nodes = { start: inner_nodes.start, end: inner_nodes.end, a: null, t: null };
73
+ }
74
+ }
64
75
  }, EFFECT_TRANSPARENT);
65
76
 
66
77
  ran = true;
@@ -1,14 +1,8 @@
1
1
  /** @import { Effect, Source, TemplateNode, } from '#client' */
2
- import {
3
- BOUNDARY_EFFECT,
4
- DIRTY,
5
- EFFECT_PRESERVED,
6
- EFFECT_TRANSPARENT,
7
- MAYBE_DIRTY
8
- } from '#client/constants';
2
+ import { BOUNDARY_EFFECT, EFFECT_PRESERVED, EFFECT_TRANSPARENT } from '#client/constants';
9
3
  import { HYDRATION_START_ELSE, HYDRATION_START_FAILED } from '../../../../constants.js';
10
4
  import { component_context, set_component_context } from '../../context.js';
11
- import { handle_error, invoke_error_boundary } from '../../error-handling.js';
5
+ import { invoke_error_boundary } from '../../error-handling.js';
12
6
  import {
13
7
  block,
14
8
  branch,
@@ -271,13 +265,31 @@ export class Boundary {
271
265
  queue_micro_task(() => {
272
266
  var fragment = (this.#offscreen_fragment = document.createDocumentFragment());
273
267
  var anchor = create_text();
268
+ var handled = false;
274
269
 
275
270
  fragment.append(anchor);
276
271
 
277
272
  this.#main_effect = this.#run(() => {
278
- return branch(() => this.#children(anchor));
273
+ try {
274
+ return branch(() => this.#children(anchor));
275
+ } catch (error) {
276
+ try {
277
+ this.error(error);
278
+ handled = true;
279
+ } catch (error) {
280
+ invoke_error_boundary(error, this.#effect.parent);
281
+ }
282
+
283
+ return null;
284
+ }
279
285
  });
280
286
 
287
+ if (this.#main_effect === null) {
288
+ this.#offscreen_fragment = null;
289
+ if (handled) this.#resolve(/** @type {Batch} */ (current_batch));
290
+ return;
291
+ }
292
+
281
293
  if (this.#pending_count === 0) {
282
294
  this.#anchor.before(fragment);
283
295
  this.#offscreen_fragment = null;
@@ -362,9 +374,6 @@ export class Boundary {
362
374
  try {
363
375
  Batch.ensure();
364
376
  return fn();
365
- } catch (e) {
366
- handle_error(e);
367
- return null;
368
377
  } finally {
369
378
  set_active_effect(previous_effect);
370
379
  set_active_reaction(previous_reaction);
@@ -1,4 +1,6 @@
1
1
  import { hydrate_next, hydrating } from '../hydration.js';
2
+ import { create_element, create_text } from '../operations.js';
3
+ import { append } from '../template.js';
2
4
 
3
5
  /**
4
6
  * @param {Comment} anchor
@@ -12,6 +14,23 @@ export function slot(anchor, $$props, name, slot_props, fallback_fn) {
12
14
  hydrate_next();
13
15
  }
14
16
 
17
+ // Custom element slots are native DOM slots.
18
+ // Use the stored reference because the shadow root may be closed.
19
+ if ($$props.$$host?.$$shadowRoot) {
20
+ const element = create_element('slot');
21
+ if (name !== 'default') element.name = name;
22
+
23
+ append(anchor, element);
24
+
25
+ if (fallback_fn !== null) {
26
+ const fallback_anchor = create_text();
27
+ element.append(fallback_anchor);
28
+ fallback_fn(fallback_anchor);
29
+ }
30
+
31
+ return;
32
+ }
33
+
15
34
  var slot_fn = $$props.$$slots?.[name];
16
35
  // Interop: Can use snippets to fill slots
17
36
  var is_interop = false;
@@ -52,6 +52,14 @@ export function head(hash, render_fn) {
52
52
  block(() => {
53
53
  var e = branch(() => render_fn(anchor));
54
54
  e.f |= HEAD_EFFECT;
55
+
56
+ if (!hydrating) {
57
+ if (e.nodes === null) {
58
+ e.nodes = { start: anchor, end: anchor, a: null, t: null };
59
+ } else {
60
+ e.nodes.end = anchor;
61
+ }
62
+ }
55
63
  });
56
64
  } finally {
57
65
  if (was_hydrating) {