@vue/compiler-vapor 3.6.0-beta.8 → 3.6.0-rc.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-vapor v3.6.0-beta.8
2
+ * @vue/compiler-vapor v3.6.0-rc.1
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -12,6 +12,90 @@ let _vue_shared = require("@vue/shared");
12
12
  let source_map_js = require("source-map-js");
13
13
  let _babel_parser = require("@babel/parser");
14
14
  let estree_walker = require("estree-walker");
15
+ //#region packages/compiler-vapor/src/ir/component.ts
16
+ const IRDynamicPropsKind = {
17
+ "EXPRESSION": 0,
18
+ "0": "EXPRESSION",
19
+ "ATTRIBUTE": 1,
20
+ "1": "ATTRIBUTE"
21
+ };
22
+ const IRSlotType = {
23
+ "STATIC": 0,
24
+ "0": "STATIC",
25
+ "DYNAMIC": 1,
26
+ "1": "DYNAMIC",
27
+ "LOOP": 2,
28
+ "2": "LOOP",
29
+ "CONDITIONAL": 3,
30
+ "3": "CONDITIONAL",
31
+ "EXPRESSION": 4,
32
+ "4": "EXPRESSION"
33
+ };
34
+ //#endregion
35
+ //#region packages/compiler-vapor/src/ir/index.ts
36
+ const IRNodeTypes = {
37
+ "ROOT": 0,
38
+ "0": "ROOT",
39
+ "BLOCK": 1,
40
+ "1": "BLOCK",
41
+ "SET_BLOCK_KEY": 2,
42
+ "2": "SET_BLOCK_KEY",
43
+ "SET_PROP": 3,
44
+ "3": "SET_PROP",
45
+ "SET_DYNAMIC_PROPS": 4,
46
+ "4": "SET_DYNAMIC_PROPS",
47
+ "SET_TEXT": 5,
48
+ "5": "SET_TEXT",
49
+ "SET_EVENT": 6,
50
+ "6": "SET_EVENT",
51
+ "SET_DYNAMIC_EVENTS": 7,
52
+ "7": "SET_DYNAMIC_EVENTS",
53
+ "SET_HTML": 8,
54
+ "8": "SET_HTML",
55
+ "SET_TEMPLATE_REF": 9,
56
+ "9": "SET_TEMPLATE_REF",
57
+ "INSERT_NODE": 10,
58
+ "10": "INSERT_NODE",
59
+ "PREPEND_NODE": 11,
60
+ "11": "PREPEND_NODE",
61
+ "CREATE_COMPONENT_NODE": 12,
62
+ "12": "CREATE_COMPONENT_NODE",
63
+ "SLOT_OUTLET_NODE": 13,
64
+ "13": "SLOT_OUTLET_NODE",
65
+ "DIRECTIVE": 14,
66
+ "14": "DIRECTIVE",
67
+ "IF": 15,
68
+ "15": "IF",
69
+ "FOR": 16,
70
+ "16": "FOR",
71
+ "KEY": 17,
72
+ "17": "KEY",
73
+ "GET_TEXT_CHILD": 18,
74
+ "18": "GET_TEXT_CHILD"
75
+ };
76
+ var TemplateRegistry = class {
77
+ constructor() {
78
+ this.entries = [];
79
+ }
80
+ keys() {
81
+ return this.entries.map(({ content }) => content);
82
+ }
83
+ };
84
+ const DynamicFlag = {
85
+ "NONE": 0,
86
+ "0": "NONE",
87
+ "REFERENCED": 1,
88
+ "1": "REFERENCED",
89
+ "NON_TEMPLATE": 2,
90
+ "2": "NON_TEMPLATE",
91
+ "INSERT": 4,
92
+ "4": "INSERT"
93
+ };
94
+ function isBlockOperation(op) {
95
+ const type = op.type;
96
+ return type === 12 || type === 13 || type === 15 || type === 17 || type === 16;
97
+ }
98
+ //#endregion
15
99
  //#region packages/compiler-vapor/src/transforms/utils.ts
16
100
  const newDynamic = () => ({
17
101
  flags: 1,
@@ -68,7 +152,7 @@ const EMPTY_EXPRESSION = (0, _vue_compiler_dom.createSimpleExpression)("", true)
68
152
  //#region packages/compiler-vapor/src/utils.ts
69
153
  const findProp$1 = _vue_compiler_dom.findProp;
70
154
  /** find directive */
71
- const findDir$2 = _vue_compiler_dom.findDir;
155
+ const findDir$4 = _vue_compiler_dom.findDir;
72
156
  function propToExpression(prop) {
73
157
  return prop.type === 6 ? prop.value ? (0, _vue_compiler_dom.createSimpleExpression)(prop.value.content, true, prop.value.loc) : EMPTY_EXPRESSION : prop.exp;
74
158
  }
@@ -78,7 +162,7 @@ function isConstantExpression(exp) {
78
162
  function isStaticExpression(node, bindings) {
79
163
  if (node.ast) return (0, _vue_compiler_dom.isConstantNode)(node.ast, bindings);
80
164
  else if (node.ast === null) {
81
- if (!node.isStatic && (node.content === "true" || node.content === "false")) return true;
165
+ if (!node.isStatic && (node.content === "true" || node.content === "false" || node.content === "null")) return true;
82
166
  return bindings[node.content] === "literal-const";
83
167
  }
84
168
  return false;
@@ -109,6 +193,13 @@ function getLiteralExpressionValue(exp, excludeNumber) {
109
193
  }
110
194
  return exp.isStatic ? exp.content : null;
111
195
  }
196
+ function isInTransition(context) {
197
+ const parentNode = context.parent && context.parent.node;
198
+ return !!(parentNode && isTransitionNode(parentNode));
199
+ }
200
+ function isTransitionNode(node) {
201
+ return node.type === 1 && isTransitionTag(node.tag);
202
+ }
112
203
  function isTransitionTag(tag) {
113
204
  tag = tag.toLowerCase();
114
205
  return tag === "transition" || tag === "vaportransition";
@@ -127,6 +218,7 @@ function isTeleportTag(tag) {
127
218
  }
128
219
  function isBuiltInComponent(tag) {
129
220
  if (isTeleportTag(tag)) return "VaporTeleport";
221
+ else if (tag === "Suspense" || tag === "suspense") return "Suspense";
130
222
  else if (isKeepAliveTag(tag)) return "VaporKeepAlive";
131
223
  else if (isTransitionTag(tag)) return "VaporTransition";
132
224
  else if (isTransitionGroupTag(tag)) return "VaporTransitionGroup";
@@ -138,6 +230,7 @@ function getBlockShape(block) {
138
230
  //#endregion
139
231
  //#region packages/compiler-vapor/src/transform.ts
140
232
  const generatedVarRE = /^[nxr](\d+)$/;
233
+ const childContextInfoCache = /* @__PURE__ */ new WeakMap();
141
234
  var TransformContext = class TransformContext {
142
235
  constructor(ir, node, options = {}) {
143
236
  this.ir = ir;
@@ -148,6 +241,8 @@ var TransformContext = class TransformContext {
148
241
  this.index = 0;
149
242
  this.block = this.ir.block;
150
243
  this.template = "";
244
+ this.templateRoot = false;
245
+ this.templateIndexMap = /* @__PURE__ */ new Map();
151
246
  this.childrenTemplate = [];
152
247
  this.dynamic = this.ir.block.dynamic;
153
248
  this.imports = [];
@@ -157,9 +252,13 @@ var TransformContext = class TransformContext {
157
252
  this.component = this.ir.component;
158
253
  this.directive = this.ir.directive;
159
254
  this.slots = [];
255
+ this.effectIndex = this.block.effect.length;
256
+ this.operationIndex = this.block.operation.length;
160
257
  this.isLastEffectiveChild = true;
161
258
  this.isOnRightmostPath = true;
162
- this.hasInlineAncestorNeedingClose = false;
259
+ this.isSingleRoot = false;
260
+ this.templateCloseTags = void 0;
261
+ this.templateCloseBlocks = false;
163
262
  this.globalId = 0;
164
263
  this.nextIdMap = null;
165
264
  this.ifIndex = 0;
@@ -174,20 +273,28 @@ var TransformContext = class TransformContext {
174
273
  this.initNextIdMap();
175
274
  }
176
275
  enterBlock(ir, isVFor = false) {
177
- const { block, template, dynamic, childrenTemplate, slots } = this;
276
+ const { block, template, templateRoot, templateIndexMap, dynamic, childrenTemplate, slots, effectIndex, operationIndex } = this;
178
277
  this.block = ir;
179
278
  this.dynamic = ir.dynamic;
180
279
  this.template = "";
280
+ this.templateRoot = false;
281
+ this.templateIndexMap = templateIndexMap;
181
282
  this.childrenTemplate = [];
182
283
  this.slots = [];
284
+ this.effectIndex = ir.effect.length;
285
+ this.operationIndex = ir.operation.length;
183
286
  isVFor && this.inVFor++;
184
287
  return () => {
185
288
  this.registerTemplate();
186
289
  this.block = block;
187
290
  this.template = template;
291
+ this.templateRoot = templateRoot;
292
+ this.templateIndexMap = templateIndexMap;
188
293
  this.dynamic = dynamic;
189
294
  this.childrenTemplate = childrenTemplate;
190
295
  this.slots = slots;
296
+ this.effectIndex = effectIndex;
297
+ this.operationIndex = operationIndex;
191
298
  isVFor && this.inVFor--;
192
299
  };
193
300
  }
@@ -212,60 +319,150 @@ var TransformContext = class TransformContext {
212
319
  nextIfIndex() {
213
320
  return this.ifIndex++;
214
321
  }
215
- pushTemplate(content) {
216
- const existingIndex = this.ir.templateIndexMap.get(content);
322
+ getTemplateNamespace() {
323
+ return this.node.type === 1 ? this.node.ns : 0;
324
+ }
325
+ canUseStaticTemplate() {
326
+ if (!this.template) return false;
327
+ if (this.inVFor) return false;
328
+ if (this.dynamic.hasDynamicChild) return false;
329
+ if (this.block.effect.length !== this.effectIndex) return false;
330
+ if (this.block.operation.length !== this.operationIndex) return false;
331
+ if (this.node.type === 2 || this.node.type === 3) return true;
332
+ return this.node.type === 1 && this.node.tagType === 0 && !(this.options.isCustomElement(this.node.tag) || this.node.tag === "template");
333
+ }
334
+ pushTemplate(content, { root = false, static: isStatic = false } = {}) {
335
+ const templateKey = JSON.stringify([
336
+ this.getTemplateNamespace(),
337
+ root,
338
+ isStatic,
339
+ content
340
+ ]);
341
+ const existingIndex = this.templateIndexMap.get(templateKey);
217
342
  if (existingIndex !== void 0) return existingIndex;
218
- const newIndex = this.ir.template.size;
219
- this.ir.template.set(content, this.node.ns);
220
- this.ir.templateIndexMap.set(content, newIndex);
343
+ const ns = this.getTemplateNamespace();
344
+ const newIndex = this.ir.template.entries.length;
345
+ this.ir.template.entries.push({
346
+ content,
347
+ ns,
348
+ root,
349
+ static: isStatic
350
+ });
351
+ this.templateIndexMap.set(templateKey, newIndex);
221
352
  return newIndex;
222
353
  }
223
354
  registerTemplate() {
224
355
  if (!this.template) return -1;
225
- const id = this.pushTemplate(this.template);
356
+ const id = this.pushTemplate(this.template, {
357
+ root: this.templateRoot,
358
+ static: this.canUseStaticTemplate()
359
+ });
226
360
  return this.dynamic.template = id;
227
361
  }
228
- registerEffect(expressions, operation, getIndex = () => this.block.effect.length) {
362
+ registerEffect(expressions, operation, getIndex) {
229
363
  const operations = [operation].flat();
230
364
  expressions = expressions.filter((exp) => !isConstantExpression(exp));
231
365
  if (this.inVOnce || expressions.length === 0 || expressions.every((e) => isStaticExpression(e, this.root.options.bindingMetadata))) return this.registerOperation(...operations);
232
- this.block.effect.splice(getIndex(), 0, {
366
+ const index = getIndex ? getIndex() : this.block.effect.length;
367
+ this.block.effect.splice(index, 0, {
233
368
  expressions,
234
369
  operations
235
370
  });
371
+ if (getIndex) this.shiftEffectBoundaries(index);
236
372
  }
237
373
  registerOperation(...node) {
238
374
  this.block.operation.push(...node);
239
375
  }
376
+ effectBoundary() {
377
+ return {
378
+ operationIndex: this.operationIndex,
379
+ effectIndex: this.effectIndex
380
+ };
381
+ }
240
382
  create(node, index) {
241
383
  let effectiveParent = this;
242
384
  while (effectiveParent && effectiveParent.node.type === 1 && effectiveParent.node.tagType === 3) effectiveParent = effectiveParent.parent;
243
- const isLastEffectiveChild = this.isEffectivelyLastChild(index);
385
+ const childInfo = this.getChildContextInfo();
386
+ const isLastEffectiveChild = childInfo.isLastEffectiveChild[index];
244
387
  const isOnRightmostPath = this.isOnRightmostPath && isLastEffectiveChild;
245
- let hasInlineAncestorNeedingClose = this.hasInlineAncestorNeedingClose;
246
- if (this.node.type === 1) {
247
- if (this.node.tag === "template") hasInlineAncestorNeedingClose = false;
248
- else if (!hasInlineAncestorNeedingClose && !this.isOnRightmostPath && (0, _vue_shared.isInlineTag)(this.node.tag)) hasInlineAncestorNeedingClose = true;
249
- }
388
+ const isSingleRoot = this.isSingleRootChild(childInfo);
250
389
  return Object.assign(Object.create(TransformContext.prototype), this, {
251
390
  node,
252
391
  parent: this,
253
392
  index,
254
393
  template: "",
394
+ templateRoot: false,
255
395
  childrenTemplate: [],
396
+ templateIndexMap: this.templateIndexMap,
256
397
  dynamic: newDynamic(),
398
+ effectIndex: this.block.effect.length,
399
+ operationIndex: this.block.operation.length,
257
400
  effectiveParent,
258
401
  isLastEffectiveChild,
259
402
  isOnRightmostPath,
260
- hasInlineAncestorNeedingClose
403
+ isSingleRoot,
404
+ templateCloseTags: this.templateCloseTags,
405
+ templateCloseBlocks: this.templateCloseBlocks
261
406
  });
262
407
  }
263
- isEffectivelyLastChild(index) {
264
- const children = this.node.children;
265
- if (!children) return true;
266
- return children.every((c, i) => i <= index || c.type === 1 && c.tagType === 1);
408
+ shiftEffectBoundaries(index, dynamic = this.dynamic) {
409
+ const operation = dynamic.operation;
410
+ if (operation && isBlockOperation(operation) && operation.effectIndex !== void 0 && operation.effectIndex >= index) operation.effectIndex++;
411
+ for (const child of dynamic.children) this.shiftEffectBoundaries(index, child);
412
+ }
413
+ getChildContextInfo() {
414
+ const node = this.node;
415
+ if (node.type !== 0 && node.type !== 1) return {
416
+ node,
417
+ hasSingleRootChild: true,
418
+ isLastEffectiveChild: []
419
+ };
420
+ const cached = childContextInfoCache.get(this);
421
+ if (cached && cached.node === node) return cached;
422
+ const { children } = node;
423
+ const isLastEffectiveChild = new Array(children.length);
424
+ let hasFollowingEffectiveChild = false;
425
+ for (let i = children.length - 1; i >= 0; i--) {
426
+ isLastEffectiveChild[i] = !hasFollowingEffectiveChild;
427
+ if (!isComponentChild(children[i])) hasFollowingEffectiveChild = true;
428
+ }
429
+ const childInfo = {
430
+ node,
431
+ hasSingleRootChild: hasSingleRootChild(children),
432
+ isLastEffectiveChild
433
+ };
434
+ childContextInfoCache.set(this, childInfo);
435
+ return childInfo;
436
+ }
437
+ isSingleRootChild(childInfo) {
438
+ if (this.inVFor || !childInfo.hasSingleRootChild) return false;
439
+ if (this.node.type === 0) return true;
440
+ return this.node.type === 1 && this.node.tagType === 3 && !!this.parent && this.isSingleRoot;
267
441
  }
268
442
  };
443
+ function hasSingleRootChild(children) {
444
+ let nonCommentChildren = 0;
445
+ let hasEncounteredIf = false;
446
+ let isSingleIfBlock = true;
447
+ for (const child of children) {
448
+ if ((0, _vue_compiler_dom.isCommentOrWhitespace)(child)) continue;
449
+ nonCommentChildren++;
450
+ if (isIfChild(child)) {
451
+ if (hasEncounteredIf) isSingleIfBlock = false;
452
+ hasEncounteredIf = true;
453
+ } else if (!hasEncounteredIf || !isElseChild(child)) isSingleIfBlock = false;
454
+ }
455
+ return nonCommentChildren === 1 || isSingleIfBlock;
456
+ }
457
+ function isComponentChild(child) {
458
+ return child.type === 1 && child.tagType === 1;
459
+ }
460
+ function isIfChild(child) {
461
+ return child.type === 9 || child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, "if");
462
+ }
463
+ function isElseChild(child) {
464
+ return child.type === 1 && !!(0, _vue_compiler_dom.findDir)(child, /^else(-if)?$/, true);
465
+ }
269
466
  const defaultOptions = {
270
467
  filename: "",
271
468
  prefixIdentifiers: true,
@@ -286,6 +483,7 @@ const defaultOptions = {
286
483
  bindingMetadata: _vue_shared.EMPTY_OBJ,
287
484
  inline: false,
288
485
  isTS: false,
486
+ eventDelegation: true,
289
487
  onError: _vue_compiler_dom.defaultOnError,
290
488
  onWarn: _vue_compiler_dom.defaultOnWarn
291
489
  };
@@ -294,14 +492,11 @@ function transform(node, options = {}) {
294
492
  type: 0,
295
493
  node,
296
494
  source: node.source,
297
- template: /* @__PURE__ */ new Map(),
298
- templateIndexMap: /* @__PURE__ */ new Map(),
299
- rootTemplateIndexes: /* @__PURE__ */ new Set(),
495
+ template: new TemplateRegistry(),
300
496
  component: /* @__PURE__ */ new Set(),
301
497
  directive: /* @__PURE__ */ new Set(),
302
498
  block: newBlock(node),
303
- hasTemplateRef: false,
304
- hasDeferredVShow: false
499
+ hasTemplateRef: false
305
500
  };
306
501
  const context = new TransformContext(ir, node, options);
307
502
  transformNode(context);
@@ -448,6 +643,9 @@ function genCall(name, ...frags) {
448
643
  hasPlaceholder ? name[1] : "null"
449
644
  ], ...frags)];
450
645
  }
646
+ function getParserOptions(plugins) {
647
+ return { plugins: plugins ? plugins.some((plugin) => plugin === "typescript") ? plugins : [...plugins, "typescript"] : ["typescript"] };
648
+ }
451
649
  function codeFragmentToString(code, context) {
452
650
  const { options: { filename, sourceMap } } = context;
453
651
  let map;
@@ -511,80 +709,6 @@ function codeFragmentToString(code, context) {
511
709
  }
512
710
  }
513
711
  //#endregion
514
- //#region packages/compiler-vapor/src/ir/component.ts
515
- const IRDynamicPropsKind = {
516
- "EXPRESSION": 0,
517
- "0": "EXPRESSION",
518
- "ATTRIBUTE": 1,
519
- "1": "ATTRIBUTE"
520
- };
521
- const IRSlotType = {
522
- "STATIC": 0,
523
- "0": "STATIC",
524
- "DYNAMIC": 1,
525
- "1": "DYNAMIC",
526
- "LOOP": 2,
527
- "2": "LOOP",
528
- "CONDITIONAL": 3,
529
- "3": "CONDITIONAL",
530
- "EXPRESSION": 4,
531
- "4": "EXPRESSION"
532
- };
533
- //#endregion
534
- //#region packages/compiler-vapor/src/ir/index.ts
535
- const IRNodeTypes = {
536
- "ROOT": 0,
537
- "0": "ROOT",
538
- "BLOCK": 1,
539
- "1": "BLOCK",
540
- "SET_PROP": 2,
541
- "2": "SET_PROP",
542
- "SET_DYNAMIC_PROPS": 3,
543
- "3": "SET_DYNAMIC_PROPS",
544
- "SET_TEXT": 4,
545
- "4": "SET_TEXT",
546
- "SET_EVENT": 5,
547
- "5": "SET_EVENT",
548
- "SET_DYNAMIC_EVENTS": 6,
549
- "6": "SET_DYNAMIC_EVENTS",
550
- "SET_HTML": 7,
551
- "7": "SET_HTML",
552
- "SET_TEMPLATE_REF": 8,
553
- "8": "SET_TEMPLATE_REF",
554
- "INSERT_NODE": 9,
555
- "9": "INSERT_NODE",
556
- "PREPEND_NODE": 10,
557
- "10": "PREPEND_NODE",
558
- "CREATE_COMPONENT_NODE": 11,
559
- "11": "CREATE_COMPONENT_NODE",
560
- "SLOT_OUTLET_NODE": 12,
561
- "12": "SLOT_OUTLET_NODE",
562
- "DIRECTIVE": 13,
563
- "13": "DIRECTIVE",
564
- "IF": 14,
565
- "14": "IF",
566
- "FOR": 15,
567
- "15": "FOR",
568
- "KEY": 16,
569
- "16": "KEY",
570
- "GET_TEXT_CHILD": 17,
571
- "17": "GET_TEXT_CHILD"
572
- };
573
- const DynamicFlag = {
574
- "NONE": 0,
575
- "0": "NONE",
576
- "REFERENCED": 1,
577
- "1": "REFERENCED",
578
- "NON_TEMPLATE": 2,
579
- "2": "NON_TEMPLATE",
580
- "INSERT": 4,
581
- "4": "INSERT"
582
- };
583
- function isBlockOperation(op) {
584
- const type = op.type;
585
- return type === 11 || type === 12 || type === 14 || type === 16 || type === 15;
586
- }
587
- //#endregion
588
712
  //#region packages/compiler-vapor/src/generators/dom.ts
589
713
  function genInsertNode({ parent, elements, anchor }, { helper }) {
590
714
  let element = elements.map((el) => `n${el}`).join(", ");
@@ -597,7 +721,10 @@ function genPrependNode(oper, { helper }) {
597
721
  //#endregion
598
722
  //#region packages/compiler-vapor/src/generators/expression.ts
599
723
  function genExpression(node, context, assignment) {
724
+ node = context.getExpressionReplacement(node);
600
725
  const { content, ast, isStatic, loc } = node;
726
+ const { options } = context;
727
+ const { inline } = options;
601
728
  if (isStatic) return [[
602
729
  JSON.stringify(content),
603
730
  -2,
@@ -619,23 +746,31 @@ function genExpression(node, context, assignment) {
619
746
  let hasMemberExpression = false;
620
747
  if (ids.length) {
621
748
  const [frag, push] = buildCodeFragment();
622
- ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
623
- const start = id.start - 1;
624
- const end = id.end - 1;
625
- const last = ids[i - 1];
626
- const leadingText = content.slice(last ? last.end - 1 : 0, start);
627
- if (leadingText.length) push([leadingText, -3]);
628
- const source = content.slice(start, end);
749
+ let lastEnd = 0;
750
+ ids.sort((a, b) => a.start - b.start).forEach((id) => {
751
+ const idStart = id.start - 1;
752
+ const idEnd = id.end - 1;
753
+ const source = content.slice(idStart, idEnd);
629
754
  const parentStack = parentStackMap.get(id);
630
755
  const parent = parentStack[parentStack.length - 1];
756
+ let start = idStart;
757
+ let end = idEnd;
758
+ if (inline && options.bindingMetadata && options.bindingMetadata[source] === "setup-let" && parent && parent.type === "UpdateExpression" && parent.argument === id) {
759
+ start = parent.start - 1;
760
+ end = parent.end - 1;
761
+ }
762
+ if (start < lastEnd) return;
763
+ const leadingText = content.slice(lastEnd, start);
764
+ if (leadingText.length) push([leadingText, -3]);
631
765
  hasMemberExpression || (hasMemberExpression = parent && (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression"));
632
766
  push(...genIdentifier(source, context, {
633
767
  start: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, start),
634
768
  end: (0, _vue_compiler_dom.advancePositionWithClone)(node.loc.start, source, end),
635
769
  source
636
- }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack));
637
- if (i === ids.length - 1 && end < content.length) push([content.slice(end), -3]);
770
+ }, hasMemberExpression ? void 0 : assignment, id, parent, parentStack, node));
771
+ lastEnd = end;
638
772
  });
773
+ if (lastEnd < content.length) push([content.slice(lastEnd), -3]);
639
774
  if (assignment && hasMemberExpression) push(` = ${assignment}`);
640
775
  return frag;
641
776
  } else return [[
@@ -644,7 +779,7 @@ function genExpression(node, context, assignment) {
644
779
  loc
645
780
  ]];
646
781
  }
647
- function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
782
+ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack, sourceNode) {
648
783
  const { options, helper, identifiers } = context;
649
784
  const { inline, bindingMetadata } = options;
650
785
  let name = raw;
@@ -664,19 +799,49 @@ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
664
799
  else return genExpression(replacement, context, assignment);
665
800
  }
666
801
  let prefix;
667
- if ((0, _vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand) prefix = `${raw}: `;
668
802
  const type = bindingMetadata && bindingMetadata[raw];
803
+ const isDestructureAssignment = parent && (0, _vue_compiler_dom.isInDestructureAssignment)(parent, parentStack || []);
804
+ const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
805
+ const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
806
+ if ((0, _vue_compiler_dom.isStaticProperty)(parent) && parent.shorthand && !(inline && type === "setup-let" && isDestructureAssignment)) prefix = `${raw}: `;
669
807
  if (inline) switch (type) {
670
808
  case "setup-let":
671
- name = raw = assignment ? `_isRef(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
809
+ if (isAssignmentLVal) {
810
+ const { right, operator } = parent;
811
+ const source = sourceNode;
812
+ const sourceContent = source.content;
813
+ const rightStart = right.start - 1;
814
+ const rightEnd = right.end - 1;
815
+ const rightContent = sourceContent.slice(rightStart, rightEnd);
816
+ const rightExp = (0, _vue_compiler_dom.createSimpleExpression)(rightContent, false, {
817
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightStart),
818
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, sourceContent, rightEnd),
819
+ source: rightContent
820
+ });
821
+ rightExp.ast = parseExp(context, rightContent);
822
+ return [
823
+ prefix,
824
+ `${helper("isRef")}(${raw}) ? ${raw}.value ${operator} `,
825
+ ...genExpression(rightExp, context),
826
+ ` : `,
827
+ [
828
+ raw,
829
+ -2,
830
+ loc,
831
+ name
832
+ ]
833
+ ];
834
+ } else if (isUpdateArg) {
835
+ const { prefix: isPrefix, operator } = parent;
836
+ const updatePrefix = isPrefix ? operator : ``;
837
+ const updatePostfix = isPrefix ? `` : operator;
838
+ raw = `${helper("isRef")}(${raw}) ? ${updatePrefix}${raw}.value${updatePostfix} : ${updatePrefix}${raw}${updatePostfix}`;
839
+ } else if (!isDestructureAssignment) name = raw = assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : (${raw} = ${assignment})` : unref();
672
840
  break;
673
841
  case "setup-ref":
674
842
  name = raw = withAssignment(`${raw}.value`);
675
843
  break;
676
844
  case "setup-maybe-ref":
677
- const isDestructureAssignment = parent && (0, _vue_compiler_dom.isInDestructureAssignment)(parent, parentStack || []);
678
- const isAssignmentLVal = parent && parent.type === "AssignmentExpression" && parent.left === id;
679
- const isUpdateArg = parent && parent.type === "UpdateExpression" && parent.argument === id;
680
845
  raw = isAssignmentLVal || isUpdateArg || isDestructureAssignment ? name = `${raw}.value` : assignment ? `${helper("isRef")}(${raw}) ? (${raw}.value = ${assignment}) : null` : unref();
681
846
  break;
682
847
  case "props":
@@ -711,28 +876,35 @@ function canPrefix(name) {
711
876
  return true;
712
877
  }
713
878
  function processExpressions(context, expressions, shouldDeclare) {
714
- const { seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
879
+ const expressionReplacements = /* @__PURE__ */ new Map();
880
+ const { seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable } = analyzeExpressions(expressions);
715
881
  const reservedNames = new Set(seenIdentifier);
716
- const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames);
717
- const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames);
718
- return genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare);
882
+ const varDeclarations = processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements);
883
+ const expDeclarations = processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements);
884
+ return {
885
+ ...genDeclarations([...varDeclarations, ...expDeclarations], context, shouldDeclare),
886
+ expressionReplacements
887
+ };
719
888
  }
720
889
  function analyzeExpressions(expressions) {
721
890
  const seenVariable = Object.create(null);
722
891
  const variableToExpMap = /* @__PURE__ */ new Map();
723
- const expToVariableMap = /* @__PURE__ */ new Map();
892
+ const expressionRecords = /* @__PURE__ */ new Map();
724
893
  const seenIdentifier = /* @__PURE__ */ new Set();
725
894
  const updatedVariable = /* @__PURE__ */ new Set();
895
+ const getRecord = (exp) => {
896
+ let record = expressionRecords.get(exp);
897
+ if (!record) expressionRecords.set(exp, record = { variables: [] });
898
+ return record;
899
+ };
726
900
  const registerVariable = (name, exp, isIdentifier, loc, parentStack = []) => {
727
901
  if (isIdentifier) seenIdentifier.add(name);
728
902
  seenVariable[name] = (seenVariable[name] || 0) + 1;
729
903
  variableToExpMap.set(name, (variableToExpMap.get(name) || /* @__PURE__ */ new Set()).add(exp));
730
- const variables = expToVariableMap.get(exp) || [];
731
- variables.push({
904
+ getRecord(exp).variables.push({
732
905
  name,
733
906
  loc
734
907
  });
735
- expToVariableMap.set(exp, variables);
736
908
  if (parentStack.some((p) => p.type === "UpdateExpression" || p.type === "AssignmentExpression")) updatedVariable.add(name);
737
909
  };
738
910
  for (const exp of expressions) {
@@ -769,13 +941,20 @@ function analyzeExpressions(expressions) {
769
941
  seenVariable,
770
942
  seenIdentifier,
771
943
  variableToExpMap,
772
- expToVariableMap,
944
+ expressionRecords,
773
945
  updatedVariable
774
946
  };
775
947
  }
776
- function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable, reservedNames) {
948
+ function getProcessedExpression(exp, expressionReplacements) {
949
+ return expressionReplacements.get(exp) || exp;
950
+ }
951
+ function setExpressionReplacement(expressionReplacements, exp, content, ast) {
952
+ expressionReplacements.set(exp, (0, _vue_shared.extend)({ ast }, (0, _vue_compiler_dom.createSimpleExpression)(content, exp.isStatic, exp.loc, exp.constType)));
953
+ }
954
+ function processRepeatedVariables(context, seenVariable, variableToExpMap, expressionRecords, seenIdentifier, updatedVariable, reservedNames, expressionReplacements) {
777
955
  const declarations = [];
778
- const expToReplacementMap = /* @__PURE__ */ new Map();
956
+ const declaredNames = /* @__PURE__ */ new Set();
957
+ const replacementPlan = /* @__PURE__ */ new Map();
779
958
  for (const [name, exps] of variableToExpMap) {
780
959
  if (updatedVariable.has(name)) continue;
781
960
  if ((0, _vue_shared.isGloballyAllowed)(name)) continue;
@@ -784,95 +963,201 @@ function processRepeatedVariables(context, seenVariable, variableToExpMap, expTo
784
963
  const varName = isIdentifier ? name : getUniqueDeclarationName(genVarName(name), reservedNames);
785
964
  exps.forEach((node) => {
786
965
  if (node.ast && varName !== name) {
787
- const replacements = expToReplacementMap.get(node) || [];
788
- replacements.push({
789
- name: varName,
790
- locs: expToVariableMap.get(node).reduce((locs, v) => {
791
- if (v.name === name && v.loc) locs.push(v.loc);
792
- return locs;
793
- }, [])
966
+ for (const variable of getExpressionVariables(expressionRecords, node)) if (variable.name === name && variable.loc) queueContentReplacement(replacementPlan, node, {
967
+ start: variable.loc.start - 1,
968
+ end: variable.loc.end - 1,
969
+ content: varName
794
970
  });
795
- expToReplacementMap.set(node, replacements);
796
971
  }
797
972
  });
798
- if (!declarations.some((d) => d.name === varName) && (!isIdentifier || shouldDeclareVariable(name, expToVariableMap, exps))) declarations.push({
799
- name: varName,
800
- isIdentifier,
801
- value: (0, _vue_shared.extend)({ ast: isIdentifier ? null : parseExp(context, name) }, (0, _vue_compiler_dom.createSimpleExpression)(name)),
802
- rawName: name,
803
- exps,
804
- seenCount: seenVariable[name]
805
- });
973
+ if (!declaredNames.has(varName) && (!isIdentifier || shouldDeclareVariable(name, expressionRecords, exps))) {
974
+ declaredNames.add(varName);
975
+ declarations.push({
976
+ name: varName,
977
+ isIdentifier,
978
+ value: (0, _vue_shared.extend)({ ast: isIdentifier ? null : parseExp(context, name) }, (0, _vue_compiler_dom.createSimpleExpression)(name)),
979
+ rawName: name,
980
+ exps,
981
+ seenCount: seenVariable[name]
982
+ });
983
+ }
806
984
  }
807
985
  }
808
- for (const [exp, replacements] of expToReplacementMap) {
809
- replacements.flatMap(({ name, locs }) => locs.map(({ start, end }) => ({
810
- start,
811
- end,
812
- name
813
- }))).sort((a, b) => b.end - a.end).forEach(({ start, end, name }) => {
814
- exp.content = exp.content.slice(0, start - 1) + name + exp.content.slice(end - 1);
815
- });
816
- exp.ast = parseExp(context, exp.content);
817
- }
986
+ applyReplacementPlan(context, expressionReplacements, replacementPlan);
818
987
  return declarations;
819
988
  }
820
- function shouldDeclareVariable(name, expToVariableMap, exps) {
821
- const vars = Array.from(exps, (exp) => expToVariableMap.get(exp).map((v) => v.name));
822
- if (vars.every((v) => v.length === 1)) return true;
823
- if (vars.some((v) => v.filter((e) => e === name).length > 1)) return true;
824
- const first = vars[0];
825
- if (vars.some((v) => v.length !== first.length)) {
826
- if (vars.some((v) => v.length > first.length && v.every((e) => first.includes(e))) || vars.some((v) => first.length > v.length && first.every((e) => v.includes(e)))) return false;
989
+ function shouldDeclareVariable(name, expressionRecords, exps) {
990
+ const variableUsages = [];
991
+ let allSingleVariable = true;
992
+ let hasRepeatedName = false;
993
+ let hasDifferentLength = false;
994
+ outer: for (const exp of exps) {
995
+ const variables = getExpressionVariables(expressionRecords, exp);
996
+ if (allSingleVariable && variables.length !== 1) allSingleVariable = false;
997
+ if (!hasDifferentLength && variableUsages.length > 0 && variables.length !== variableUsages[0].length) hasDifferentLength = true;
998
+ let nameCount = 0;
999
+ for (const variable of variables) if (variable.name === name && ++nameCount > 1) {
1000
+ hasRepeatedName = true;
1001
+ break outer;
1002
+ }
1003
+ variableUsages.push(variables);
1004
+ }
1005
+ if (allSingleVariable) return true;
1006
+ if (hasRepeatedName) return true;
1007
+ const first = variableUsages[0];
1008
+ if (hasDifferentLength) {
1009
+ for (const variables of variableUsages) {
1010
+ if (variables.length === first.length) continue;
1011
+ const longer = variables.length > first.length ? variables : first;
1012
+ const shorter = variables.length > first.length ? first : variables;
1013
+ const shorterNames = /* @__PURE__ */ new Set();
1014
+ for (const variable of shorter) shorterNames.add(variable.name);
1015
+ let isSubset = true;
1016
+ for (const variable of longer) if (!shorterNames.has(variable.name)) {
1017
+ isSubset = false;
1018
+ break;
1019
+ }
1020
+ if (isSubset) return false;
1021
+ }
827
1022
  return true;
828
1023
  }
829
- if (vars.every((v) => v.every((e, idx) => e === first[idx]))) return false;
830
- return true;
1024
+ for (const variables of variableUsages) for (let i = 0; i < variables.length; i++) if (variables[i].name !== first[i].name) return true;
1025
+ return false;
831
1026
  }
832
- function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap, reservedNames) {
1027
+ function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expressionRecords, reservedNames, expressionReplacements) {
833
1028
  const declarations = [];
834
- const seenExp = expressions.reduce((acc, exp) => {
835
- const vars = expToVariableMap.get(exp);
836
- if (!vars) return acc;
837
- const variables = vars.map((v) => v.name);
838
- if (exp.ast && exp.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v))) && !variables.some((v) => (0, _vue_shared.isGloballyAllowed)(v))) acc[exp.content] = (acc[exp.content] || 0) + 1;
839
- return acc;
840
- }, Object.create(null));
841
- Object.entries(seenExp).forEach(([content, count]) => {
842
- if (count > 1) {
843
- const delVars = {};
844
- for (let i = varDeclarations.length - 1; i >= 0; i--) {
845
- const item = varDeclarations[i];
846
- if (!item.exps || !item.seenCount) continue;
847
- if ([...item.exps].every((node) => node.content === content && item.seenCount === count)) {
848
- delVars[item.name] = item.rawName;
849
- reservedNames.delete(item.name);
850
- varDeclarations.splice(i, 1);
851
- }
852
- }
853
- const value = (0, _vue_shared.extend)({}, expressions.find((exp) => exp.content === content));
854
- Object.keys(delVars).forEach((name) => {
855
- value.content = value.content.replace(name, delVars[name]);
856
- if (value.ast) value.ast = parseExp(context, value.content);
857
- });
858
- const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
859
- declarations.push({
860
- name: varName,
861
- value
1029
+ const seenExp = /* @__PURE__ */ new Map();
1030
+ for (const exp of expressions) {
1031
+ var _expressionRecords$ge;
1032
+ const vars = (_expressionRecords$ge = expressionRecords.get(exp)) === null || _expressionRecords$ge === void 0 ? void 0 : _expressionRecords$ge.variables;
1033
+ if (!vars) continue;
1034
+ const processed = getProcessedExpression(exp, expressionReplacements);
1035
+ if (canCacheExpression(processed, vars, updatedVariable)) {
1036
+ const seen = seenExp.get(processed.content);
1037
+ if (seen) seen.count++;
1038
+ else seenExp.set(processed.content, {
1039
+ count: 1,
1040
+ first: exp
862
1041
  });
863
- expressions.forEach((exp) => {
864
- if (exp.content === content) {
865
- exp.content = varName;
866
- exp.ast = null;
867
- } else if (exp.content.includes(content)) {
868
- exp.content = exp.content.replace(new RegExp(escapeRegExp(content), "g"), varName);
869
- exp.ast = parseExp(context, exp.content);
1042
+ }
1043
+ }
1044
+ const repeatedExpressions = [...seenExp].sort(([contentA], [contentB]) => contentB.length - contentA.length);
1045
+ for (const [content, { count, first }] of repeatedExpressions) if (count > 1) {
1046
+ const removedDeclarations = [];
1047
+ for (let i = varDeclarations.length - 1; i >= 0; i--) {
1048
+ const item = varDeclarations[i];
1049
+ if (!item.exps || !item.seenCount) continue;
1050
+ if ([...item.exps].every((node) => getProcessedExpression(node, expressionReplacements).content === content && item.seenCount === count)) {
1051
+ removedDeclarations.push({
1052
+ name: item.name,
1053
+ rawName: item.rawName
1054
+ });
1055
+ reservedNames.delete(item.name);
1056
+ varDeclarations.splice(i, 1);
1057
+ }
1058
+ }
1059
+ const value = (0, _vue_shared.extend)({}, getProcessedExpression(first, expressionReplacements));
1060
+ const restorePlan = [];
1061
+ for (const { name, rawName } of removedDeclarations) restorePlan.push(...findIdentifierReplacements(value, name, rawName));
1062
+ if (restorePlan.length) {
1063
+ value.content = applyContentReplacements(value.content, restorePlan);
1064
+ if (value.ast) value.ast = parseExp(context, value.content);
1065
+ }
1066
+ const varName = getUniqueDeclarationName(genVarName(content), reservedNames);
1067
+ declarations.push({
1068
+ name: varName,
1069
+ value
1070
+ });
1071
+ for (const exp of expressions) {
1072
+ const processed = getProcessedExpression(exp, expressionReplacements);
1073
+ if (processed.content === content) setExpressionReplacement(expressionReplacements, exp, varName, null);
1074
+ else if (processed.content.includes(content)) {
1075
+ const replacements = findContentReplacements(processed, content, varName);
1076
+ if (replacements.length) {
1077
+ const replacedContent = applyContentReplacements(processed.content, replacements);
1078
+ setExpressionReplacement(expressionReplacements, exp, replacedContent, parseExp(context, replacedContent));
870
1079
  }
871
- });
1080
+ }
872
1081
  }
873
- });
1082
+ }
874
1083
  return declarations;
875
1084
  }
1085
+ function canCacheExpression(processed, vars, updatedVariable) {
1086
+ if (!processed.ast || processed.ast.type === "Identifier") return false;
1087
+ for (const { name } of vars) if (updatedVariable.has(name) || (0, _vue_shared.isGloballyAllowed)(name)) return false;
1088
+ return true;
1089
+ }
1090
+ function getExpressionVariables(expressionRecords, exp) {
1091
+ var _expressionRecords$ge2;
1092
+ return ((_expressionRecords$ge2 = expressionRecords.get(exp)) === null || _expressionRecords$ge2 === void 0 ? void 0 : _expressionRecords$ge2.variables) || [];
1093
+ }
1094
+ function queueContentReplacement(replacementPlan, exp, replacement) {
1095
+ const replacements = replacementPlan.get(exp);
1096
+ if (replacements) replacements.push(replacement);
1097
+ else replacementPlan.set(exp, [replacement]);
1098
+ }
1099
+ function applyReplacementPlan(context, expressionReplacements, replacementPlan) {
1100
+ for (const [exp, replacements] of replacementPlan) {
1101
+ if (!replacements.length) continue;
1102
+ const content = applyContentReplacements(getProcessedExpression(exp, expressionReplacements).content, replacements);
1103
+ setExpressionReplacement(expressionReplacements, exp, content, parseExp(context, content));
1104
+ }
1105
+ }
1106
+ function findContentReplacements(exp, content, replacement) {
1107
+ const identifiers = getIdentifierRanges(exp);
1108
+ if (!identifiers.length) return [];
1109
+ const replacements = [];
1110
+ let searchStart = 0;
1111
+ let start = exp.content.indexOf(content, searchStart);
1112
+ while (start !== -1) {
1113
+ const end = start + content.length;
1114
+ let canReplace = false;
1115
+ for (const identifier of identifiers) {
1116
+ if (start >= identifier.end || end <= identifier.start) continue;
1117
+ if (start > identifier.start || end < identifier.end) {
1118
+ canReplace = false;
1119
+ break;
1120
+ }
1121
+ canReplace = true;
1122
+ }
1123
+ if (canReplace) {
1124
+ replacements.push({
1125
+ start,
1126
+ end,
1127
+ content: replacement
1128
+ });
1129
+ searchStart = end;
1130
+ } else searchStart = start + 1;
1131
+ start = exp.content.indexOf(content, searchStart);
1132
+ }
1133
+ return replacements;
1134
+ }
1135
+ function findIdentifierReplacements(exp, name, replacement) {
1136
+ const replacements = [];
1137
+ for (const { start, end } of getIdentifierRanges(exp)) if (exp.content.slice(start, end) === name) replacements.push({
1138
+ start,
1139
+ end,
1140
+ content: replacement
1141
+ });
1142
+ return replacements;
1143
+ }
1144
+ function getIdentifierRanges(exp) {
1145
+ if (!exp.ast || typeof exp.ast !== "object") return [];
1146
+ const identifiers = [];
1147
+ (0, _vue_compiler_dom.walkIdentifiers)(exp.ast, (id) => {
1148
+ identifiers.push({
1149
+ start: id.start - 1,
1150
+ end: id.end - 1
1151
+ });
1152
+ }, false);
1153
+ return identifiers;
1154
+ }
1155
+ function applyContentReplacements(content, replacements) {
1156
+ replacements.sort((a, b) => b.start - a.start).forEach(({ start, end, content: replacement }) => {
1157
+ content = content.slice(0, start) + replacement + content.slice(end);
1158
+ });
1159
+ return content;
1160
+ }
876
1161
  function genDeclarations(declarations, context, shouldDeclare) {
877
1162
  const [frag, push] = buildCodeFragment();
878
1163
  const ids = Object.create(null);
@@ -900,13 +1185,8 @@ function genDeclarations(declarations, context, shouldDeclare) {
900
1185
  varNames: [...varNames]
901
1186
  };
902
1187
  }
903
- function escapeRegExp(string) {
904
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
905
- }
906
1188
  function parseExp(context, content) {
907
- const plugins = context.options.expressionPlugins;
908
- const options = { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] };
909
- return (0, _babel_parser.parseExpression)(`(${content})`, options);
1189
+ return (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
910
1190
  }
911
1191
  function genVarName(exp) {
912
1192
  return `${exp.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/_+$/, "")}`;
@@ -947,22 +1227,31 @@ const isMemberExpression$3 = (node) => {
947
1227
  function genSetEvent(oper, context) {
948
1228
  const { helper } = context;
949
1229
  const { element, key, keyOverride, value, modifiers, delegate, effect } = oper;
950
- const name = genName();
951
- const handler = [
952
- `${context.helper("createInvoker")}(`,
953
- ...genEventHandler(context, [value], modifiers),
954
- `)`
955
- ];
956
- const eventOptions = genEventOptions();
1230
+ let handler;
957
1231
  if (delegate) {
958
1232
  context.delegates.add(key.content);
959
1233
  if (!context.block.operation.some(isSameDelegateEvent)) return [
960
1234
  NEWLINE,
961
1235
  `n${element}.$evt${key.content} = `,
962
- ...handler
1236
+ ...genDirectHandler()
1237
+ ];
1238
+ }
1239
+ const name = genName();
1240
+ const eventOptions = genEventOptions();
1241
+ return [NEWLINE, ...genCall(helper(effect ? "onBinding" : delegate ? "delegate" : "on"), `n${element}`, name, genHandler(), eventOptions)];
1242
+ function genHandler() {
1243
+ return handler || (handler = genEventHandler(context, [value], modifiers));
1244
+ }
1245
+ function genInvoker() {
1246
+ return [
1247
+ `${helper("createInvoker")}(`,
1248
+ ...genHandler(),
1249
+ `)`
963
1250
  ];
964
1251
  }
965
- return [NEWLINE, ...genCall(helper(delegate ? "delegate" : "on"), `n${element}`, name, handler, eventOptions)];
1252
+ function genDirectHandler() {
1253
+ return modifiers.keys.length || modifiers.nonKeys.length ? genEventHandler(context, [value], modifiers, { modifierHelper: "vapor" }) : genInvoker();
1254
+ }
966
1255
  function genName() {
967
1256
  const expr = genExpression(key, context);
968
1257
  if (keyOverride) {
@@ -982,11 +1271,11 @@ function genSetEvent(oper, context) {
982
1271
  }
983
1272
  function genEventOptions() {
984
1273
  let { options } = modifiers;
985
- if (!options.length && !effect) return;
986
- return genMulti(DELIMITERS_OBJECT_NEWLINE, effect && ["effect: true"], ...options.map((option) => [`${option}: true`]));
1274
+ if (!options.length) return;
1275
+ return genMulti(DELIMITERS_OBJECT_NEWLINE, ...options.map((option) => [`${option}: true`]));
987
1276
  }
988
1277
  function isSameDelegateEvent(op) {
989
- if (op.type === 5 && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true;
1278
+ if (op.type === 6 && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) return true;
990
1279
  }
991
1280
  }
992
1281
  function genSetDynamicEvents(oper, context) {
@@ -996,7 +1285,9 @@ function genSetDynamicEvents(oper, context) {
996
1285
  function genEventHandler(context, values, modifiers = {
997
1286
  nonKeys: [],
998
1287
  keys: []
999
- }, asComponentProp = false, extraWrap = false) {
1288
+ }, options = {}) {
1289
+ const { asComponentProp = false, extraWrap = false, modifierHelper = "runtime" } = options;
1290
+ const useVaporModifierHelper = modifierHelper === "vapor";
1000
1291
  let handlerExp = [];
1001
1292
  if (values) {
1002
1293
  values.forEach((value, index) => {
@@ -1037,16 +1328,16 @@ function genEventHandler(context, values, modifiers = {
1037
1328
  }
1038
1329
  if (handlerExp.length === 0) handlerExp = ["() => {}"];
1039
1330
  const { keys, nonKeys } = modifiers;
1040
- if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys);
1041
- if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys);
1331
+ if (nonKeys.length) handlerExp = genWithModifiers(context, handlerExp, nonKeys, useVaporModifierHelper && !keys.length);
1332
+ if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys, useVaporModifierHelper);
1042
1333
  if (extraWrap) handlerExp.unshift(`() => `);
1043
1334
  return handlerExp;
1044
1335
  }
1045
- function genWithModifiers(context, handler, nonKeys) {
1046
- return genCall(context.helper("withModifiers"), handler, JSON.stringify(nonKeys));
1336
+ function genWithModifiers(context, handler, nonKeys, useVaporHelper = false) {
1337
+ return genCall(context.helper(useVaporHelper ? "withVaporModifiers" : "withModifiers"), handler, JSON.stringify(nonKeys));
1047
1338
  }
1048
- function genWithKeys(context, handler, keys) {
1049
- return genCall(context.helper("withKeys"), handler, JSON.stringify(keys));
1339
+ function genWithKeys(context, handler, keys, useVaporHelper = false) {
1340
+ return genCall(context.helper(useVaporHelper ? "withVaporKeys" : "withKeys"), handler, JSON.stringify(keys));
1050
1341
  }
1051
1342
  function isConstantBinding(value, context) {
1052
1343
  if (value.ast === null) {
@@ -1057,7 +1348,7 @@ function isConstantBinding(value, context) {
1057
1348
  //#region packages/compiler-vapor/src/generators/for.ts
1058
1349
  function genFor(oper, context) {
1059
1350
  const { helper } = context;
1060
- const { source, value, key, index, render, keyProp, once, id, component, onlyChild } = oper;
1351
+ const { source, value, key, index, render, keyProp, once, id, component, onlyChild, slotRoot } = oper;
1061
1352
  const rawValue = value && value.content;
1062
1353
  const rawKey = key && key.content;
1063
1354
  const rawIndex = index && index.content;
@@ -1084,16 +1375,12 @@ function genFor(oper, context) {
1084
1375
  idMap[rawIndex] = `${indexVar}.value`;
1085
1376
  idMap[indexVar] = null;
1086
1377
  }
1087
- const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(render, keyProp, idMap);
1378
+ const { selectorPatterns, keyOnlyBindingPatterns, skippedEffectIndexes } = matchPatterns(render, keyProp, idMap, context);
1088
1379
  const selectorDeclarations = [];
1089
- const selectorSetup = [];
1380
+ const selectorName = (i) => selectorPatterns.length > 1 ? `_selector${id}_${i}` : `_selector${id}`;
1090
1381
  for (let i = 0; i < selectorPatterns.length; i++) {
1091
1382
  const { selector } = selectorPatterns[i];
1092
- const selectorName = `_selector${id}_${i}`;
1093
- selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
1094
- if (i === 0) selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
1095
- selectorSetup.push(NEWLINE, `${selectorName} = `, ...genCall(`createSelector`, [`() => `, ...genExpression(selector, context)]));
1096
- if (i === selectorPatterns.length - 1) selectorSetup.push(INDENT_END, NEWLINE, "}");
1383
+ selectorDeclarations.push(`const ${selectorName(i)} = `, ...genCall(helper("createSelector"), [`() => `, ...genExpression(selector, context)]), NEWLINE);
1097
1384
  }
1098
1385
  const blockFn = context.withId(() => {
1099
1386
  const frag = [];
@@ -1102,27 +1389,27 @@ function genFor(oper, context) {
1102
1389
  const patternFrag = [];
1103
1390
  for (let i = 0; i < selectorPatterns.length; i++) {
1104
1391
  const { effect } = selectorPatterns[i];
1105
- patternFrag.push(NEWLINE, `_selector${id}_${i}(() => {`, INDENT_START);
1392
+ patternFrag.push(NEWLINE, `${selectorName(i)}(`, ...genExpression(keyProp, context), `, () => {`, INDENT_START);
1106
1393
  for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context));
1107
1394
  patternFrag.push(INDENT_END, NEWLINE, `})`);
1108
1395
  }
1109
1396
  for (const { effect } of keyOnlyBindingPatterns) for (const oper of effect.operations) patternFrag.push(...genOperation(oper, context));
1110
1397
  return patternFrag;
1111
- }));
1398
+ }, skippedEffectIndexes));
1112
1399
  else frag.push(...genBlockContent(render, context));
1113
1400
  frag.push(INDENT_END, NEWLINE, "}");
1114
1401
  return frag;
1115
1402
  }, idMap);
1116
1403
  exitScope();
1117
- let flags = 0;
1118
- if (onlyChild) flags |= 1;
1119
- if (component) flags |= 2;
1120
- if (once) flags |= 4;
1404
+ const flags = genForFlags(onlyChild, component, isFragmentBlock(render), !component && isSingleNodeBlock(render), once, slotRoot);
1405
+ const onResetCalls = [];
1406
+ for (let i = 0; i < selectorPatterns.length; i++) onResetCalls.push(NEWLINE, `n${id}.onReset(${selectorName(i)}.reset)`);
1121
1407
  return [
1122
1408
  NEWLINE,
1123
1409
  ...selectorDeclarations,
1124
1410
  `const n${id} = `,
1125
- ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags ? String(flags) : void 0, selectorSetup.length ? selectorSetup : void 0)
1411
+ ...genCall([helper("createFor"), "undefined"], sourceExpr, blockFn, genCallback(keyProp), flags),
1412
+ ...onResetCalls
1126
1413
  ];
1127
1414
  function genCallback(expr) {
1128
1415
  if (!expr) return false;
@@ -1146,6 +1433,51 @@ function genFor(oper, context) {
1146
1433
  return idMap;
1147
1434
  }
1148
1435
  }
1436
+ function genForFlags(onlyChild, component, isFragment, isSingleNode, once, slotRoot) {
1437
+ let flags = 0;
1438
+ const names = [];
1439
+ if (onlyChild) {
1440
+ flags |= 1;
1441
+ names.push("FAST_REMOVE");
1442
+ }
1443
+ if (component) {
1444
+ flags |= 2;
1445
+ names.push("IS_COMPONENT");
1446
+ }
1447
+ if (isFragment) {
1448
+ flags |= 16;
1449
+ names.push("IS_FRAGMENT");
1450
+ }
1451
+ if (isSingleNode) {
1452
+ flags |= 8;
1453
+ names.push("IS_SINGLE_NODE");
1454
+ }
1455
+ if (once) {
1456
+ flags |= 4;
1457
+ names.push("ONCE");
1458
+ }
1459
+ if (slotRoot) {
1460
+ flags |= 32;
1461
+ names.push("SLOT_ROOT");
1462
+ }
1463
+ if (!flags) return;
1464
+ return `${flags} /* ${names.join(", ")} */`;
1465
+ }
1466
+ function isSingleNodeBlock(block) {
1467
+ const child = getSingleReturnedChild(block);
1468
+ return !!child && child.template != null;
1469
+ }
1470
+ function isFragmentBlock(block) {
1471
+ const child = getSingleReturnedChild(block);
1472
+ const operation = child && child.operation;
1473
+ if (!operation) return false;
1474
+ return operation.type === 13 || operation.type === 16 || operation.type === 17 || operation.type === 15 && !operation.once || operation.type === 12 && !!operation.dynamic && !operation.dynamic.isStatic;
1475
+ }
1476
+ function getSingleReturnedChild(block) {
1477
+ if (block.returns.length !== 1) return;
1478
+ const id = block.returns[0];
1479
+ for (const child of block.dynamic.children) if (child.id === id) return child;
1480
+ }
1149
1481
  function parseValueDestructure(value, context) {
1150
1482
  const map = /* @__PURE__ */ new Map();
1151
1483
  if (value) {
@@ -1181,7 +1513,7 @@ function parseValueDestructure(value, context) {
1181
1513
  if (child.type === "AssignmentPattern" && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
1182
1514
  isDynamic = true;
1183
1515
  helper = context.helper("getDefaultValue");
1184
- helperArgs = rawValue.slice(child.right.start - 1, child.right.end - 1);
1516
+ helperArgs = `() => (${rawValue.slice(child.right.start - 1, child.right.end - 1)})`;
1185
1517
  }
1186
1518
  }
1187
1519
  map.set(id.name, {
@@ -1208,34 +1540,44 @@ function buildDestructureIdMap(idToPathMap, baseAccessor, plugins) {
1208
1540
  }
1209
1541
  if (pathInfo.dynamic) {
1210
1542
  const node = idMap[id] = (0, _vue_compiler_dom.createSimpleExpression)(path);
1211
- node.ast = (0, _babel_parser.parseExpression)(`(${path})`, { plugins: plugins ? [...plugins, "typescript"] : ["typescript"] });
1543
+ node.ast = (0, _babel_parser.parseExpression)(`(${path})`, getParserOptions(plugins));
1212
1544
  } else idMap[id] = path;
1213
1545
  } else idMap[id] = path;
1214
1546
  });
1215
1547
  return idMap;
1216
1548
  }
1217
- function matchPatterns(render, keyProp, idMap) {
1549
+ function matchPatterns(render, keyProp, idMap, context) {
1218
1550
  const selectorPatterns = [];
1219
1551
  const keyOnlyBindingPatterns = [];
1220
- render.effect = render.effect.filter((effect) => {
1221
- if (keyProp !== void 0) {
1222
- const selector = matchSelectorPattern(effect, keyProp.content, idMap);
1223
- if (selector) {
1224
- selectorPatterns.push(selector);
1225
- return false;
1226
- }
1227
- const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
1228
- if (keyOnly) {
1229
- keyOnlyBindingPatterns.push(keyOnly);
1230
- return false;
1231
- }
1552
+ let skippedEffectIndexes;
1553
+ if (keyProp === void 0) return {
1554
+ keyOnlyBindingPatterns,
1555
+ selectorPatterns,
1556
+ skippedEffectIndexes
1557
+ };
1558
+ for (let index = 0; index < render.effect.length; index++) {
1559
+ const effect = render.effect[index];
1560
+ const selector = matchSelectorPattern(effect, keyProp.content, idMap, context);
1561
+ if (selector) {
1562
+ selectorPatterns.push(selector);
1563
+ skipEffect(index);
1564
+ continue;
1232
1565
  }
1233
- return true;
1234
- });
1566
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.content);
1567
+ if (keyOnly) {
1568
+ keyOnlyBindingPatterns.push(keyOnly);
1569
+ skipEffect(index);
1570
+ }
1571
+ }
1235
1572
  return {
1236
1573
  keyOnlyBindingPatterns,
1237
- selectorPatterns
1574
+ selectorPatterns,
1575
+ skippedEffectIndexes
1238
1576
  };
1577
+ function skipEffect(index) {
1578
+ if (!skippedEffectIndexes) skippedEffectIndexes = /* @__PURE__ */ new Set();
1579
+ skippedEffectIndexes.add(index);
1580
+ }
1239
1581
  }
1240
1582
  function matchKeyOnlyBindingPattern(effect, key) {
1241
1583
  if (effect.expressions.length === 1) {
@@ -1245,7 +1587,7 @@ function matchKeyOnlyBindingPattern(effect, key) {
1245
1587
  }
1246
1588
  }
1247
1589
  }
1248
- function matchSelectorPattern(effect, key, idMap) {
1590
+ function matchSelectorPattern(effect, key, idMap, context) {
1249
1591
  if (effect.expressions.length === 1) {
1250
1592
  const { ast, content } = effect.expressions[0];
1251
1593
  if (typeof ast === "object" && ast) {
@@ -1270,17 +1612,11 @@ function matchSelectorPattern(effect, key, idMap) {
1270
1612
  }, false);
1271
1613
  if (!hasExtraId) {
1272
1614
  const name = content.slice(selector.start - 1, selector.end - 1);
1615
+ const selectorExpression = (0, _vue_compiler_dom.createSimpleExpression)(name, false, selector.loc);
1616
+ selectorExpression.ast = (0, _babel_parser.parseExpression)(`(${name})`, getParserOptions(context.options.expressionPlugins));
1273
1617
  return {
1274
1618
  effect,
1275
- selector: {
1276
- content: name,
1277
- ast: (0, _vue_shared.extend)({}, selector, {
1278
- start: 1,
1279
- end: name.length + 1
1280
- }),
1281
- loc: selector.loc,
1282
- isStatic: false
1283
- }
1619
+ selector: selectorExpression
1284
1620
  };
1285
1621
  }
1286
1622
  }
@@ -1321,8 +1657,9 @@ function genSetHtml(oper, context) {
1321
1657
  //#region packages/compiler-vapor/src/generators/if.ts
1322
1658
  function genIf(oper, context, isNested = false) {
1323
1659
  const { helper } = context;
1324
- const { condition, positive, negative, once, index, blockShape } = oper;
1660
+ const { condition, positive, negative, once, slotRoot, index, blockShape } = oper;
1325
1661
  const [frag, push] = buildCodeFragment();
1662
+ const flags = genIfFlags(blockShape, once, slotRoot, negative ? index : void 0);
1326
1663
  const conditionExpr = [
1327
1664
  "() => (",
1328
1665
  ...genExpression(condition, context),
@@ -1333,15 +1670,44 @@ function genIf(oper, context, isNested = false) {
1333
1670
  if (negative) if (negative.type === 1) negativeArg = genBlock(negative, context);
1334
1671
  else negativeArg = ["() => ", ...genIf(negative, context, true)];
1335
1672
  if (!isNested) push(NEWLINE, `const n${oper.id} = `);
1336
- push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, String(blockShape), once && "true", index !== void 0 && negative && String(index)));
1673
+ push(...genCall(helper("createIf"), conditionExpr, positiveArg, negativeArg, flags));
1337
1674
  return frag;
1338
1675
  }
1676
+ function genIfFlags(blockShape, once, slotRoot, index) {
1677
+ let flags = blockShape;
1678
+ if (slotRoot) flags |= 128;
1679
+ if (once) flags |= 16;
1680
+ else if (index !== void 0) flags |= index + 1 << 8;
1681
+ if (flags === 1) return false;
1682
+ return `${flags} /* ${genIfFlagNames(once, slotRoot, index, blockShape)} */`;
1683
+ }
1684
+ function genIfFlagNames(once, slotRoot, index, blockShape) {
1685
+ const names = [`TRUE_${genBlockShapeName(blockShape)}`];
1686
+ const falseShape = blockShape >> 2;
1687
+ const hasFalseBranch = (falseShape & 3) !== 0;
1688
+ if (hasFalseBranch) names.push(`FALSE_${genBlockShapeName(falseShape)}`);
1689
+ if (blockShape & 32) names.push("TRUE_NO_SCOPE");
1690
+ if (hasFalseBranch && blockShape & 64) names.push("FALSE_NO_SCOPE");
1691
+ if (once) names.push("ONCE");
1692
+ if (slotRoot) names.push("SLOT_ROOT");
1693
+ if (!once && index !== void 0) names.push(`KEYED_INDEX_${index}`);
1694
+ return names.join(", ");
1695
+ }
1696
+ function genBlockShapeName(flags) {
1697
+ switch (flags & 3) {
1698
+ case 0: return "EMPTY";
1699
+ case 1: return "SINGLE_ROOT";
1700
+ case 2: return "MULTI_ROOT";
1701
+ }
1702
+ return "UNKNOWN";
1703
+ }
1339
1704
  //#endregion
1340
1705
  //#region packages/compiler-vapor/src/generators/prop.ts
1341
1706
  const helpers = {
1342
1707
  setText: { name: "setText" },
1343
1708
  setHtml: { name: "setHtml" },
1344
1709
  setClass: { name: "setClass" },
1710
+ setClassName: { name: "setClassName" },
1345
1711
  setStyle: { name: "setStyle" },
1346
1712
  setValue: { name: "setValue" },
1347
1713
  setAttr: {
@@ -1361,9 +1727,133 @@ function genSetProp(oper, context) {
1361
1727
  const { helper } = context;
1362
1728
  const { prop: { key, values, modifier }, tag } = oper;
1363
1729
  const resolvedHelper = getRuntimeHelper(tag, key.content, modifier);
1730
+ if (key.content === "class" && !resolvedHelper.isSVG && resolvedHelper.name === "setClass") {
1731
+ const className = genSetClassName(oper, context);
1732
+ if (className) return className;
1733
+ }
1364
1734
  const propValue = genPropValue(values, context);
1365
1735
  return [NEWLINE, ...genCall([helper(resolvedHelper.name), null], `n${oper.element}`, resolvedHelper.needKey ? genExpression(key, context) : false, propValue, resolvedHelper.isSVG && "true")];
1366
1736
  }
1737
+ const MAX_CLASS_NAME_ENTRIES = 31;
1738
+ function genSetClassName(oper, context) {
1739
+ const info = resolveClassName(oper.prop.values, context);
1740
+ if (!info) return;
1741
+ const { helper } = context;
1742
+ const flags = genClassFlags(info.entries, context);
1743
+ const classFragments = info.entries.map((entry) => JSON.stringify(!info.prefix && info.entries.length === 1 ? entry.className : ` ${entry.className}`));
1744
+ const fragments = classFragments.length === 1 ? classFragments[0] : genMulti(DELIMITERS_ARRAY, ...classFragments);
1745
+ return [NEWLINE, ...genCall([helper("setClassName"), "\"\""], `n${oper.element}`, flags, fragments, info.prefix && JSON.stringify(info.prefix), info.suffix && JSON.stringify(info.suffix))];
1746
+ }
1747
+ function resolveClassName(values, context) {
1748
+ let prefix = "";
1749
+ let suffix = "";
1750
+ const entries = [];
1751
+ let sawDynamic = false;
1752
+ let sawSuffix = false;
1753
+ for (const rawValue of values) {
1754
+ const value = context.getExpressionReplacement(rawValue);
1755
+ const staticValue = getLiteralExpressionValue(value, true);
1756
+ if (staticValue != null) {
1757
+ const normalized = (0, _vue_shared.normalizeClass)(staticValue);
1758
+ if (normalized) if (sawSuffix) suffix = appendClass$1(suffix, normalized);
1759
+ else if (sawDynamic) {
1760
+ sawSuffix = true;
1761
+ suffix = appendClass$1(suffix, normalized);
1762
+ } else prefix = appendClass$1(prefix, normalized);
1763
+ continue;
1764
+ }
1765
+ const ast = value.ast;
1766
+ if (!ast || sawSuffix) return;
1767
+ sawDynamic = true;
1768
+ if (ast.type === "ObjectExpression") {
1769
+ if (!resolveObjectClassName(value, ast, entries, context)) return;
1770
+ } else if (ast.type === "ConditionalExpression") {
1771
+ if (!resolveConditionalClassName(value, ast, entries, context)) return;
1772
+ } else return;
1773
+ }
1774
+ return entries.length && entries.length <= MAX_CLASS_NAME_ENTRIES ? {
1775
+ prefix,
1776
+ suffix,
1777
+ entries
1778
+ } : void 0;
1779
+ }
1780
+ function resolveObjectClassName(source, ast, entries, context) {
1781
+ for (const prop of ast.properties) {
1782
+ if (prop.type !== "ObjectProperty" || prop.computed) return false;
1783
+ const rawClassName = getObjectPropertyName$1(prop);
1784
+ if (rawClassName == null) return false;
1785
+ const className = (0, _vue_shared.normalizeClass)(rawClassName);
1786
+ if (!className) continue;
1787
+ const value = getBooleanValue(prop.value);
1788
+ entries.push({
1789
+ className,
1790
+ value,
1791
+ condition: value == null ? createSubExpression(source, prop.value, context) : void 0
1792
+ });
1793
+ }
1794
+ return true;
1795
+ }
1796
+ function resolveConditionalClassName(source, ast, entries, context) {
1797
+ const consequent = getStringClassValue(ast.consequent);
1798
+ const alternate = getStringClassValue(ast.alternate);
1799
+ if (consequent && alternate === "") {
1800
+ entries.push({
1801
+ className: consequent,
1802
+ condition: createSubExpression(source, ast.test, context)
1803
+ });
1804
+ return true;
1805
+ } else if (alternate && consequent === "") {
1806
+ entries.push({
1807
+ className: alternate,
1808
+ condition: createSubExpression(source, ast.test, context),
1809
+ negate: true
1810
+ });
1811
+ return true;
1812
+ }
1813
+ return false;
1814
+ }
1815
+ function genClassFlags(entries, context) {
1816
+ const values = [];
1817
+ entries.forEach((entry, index) => {
1818
+ if (index) values.push(" | ");
1819
+ const bit = 1 << index;
1820
+ if (entry.value != null) {
1821
+ values.push(entry.value ? String(bit) : "0");
1822
+ return;
1823
+ }
1824
+ values.push("(", ...genExpression(entry.condition, context), entry.negate ? ` ? 0 : ${bit}` : ` ? ${bit} : 0`, ")");
1825
+ });
1826
+ return values;
1827
+ }
1828
+ function appendClass$1(base, value) {
1829
+ return base ? value ? `${base} ${value}` : base : value;
1830
+ }
1831
+ function getObjectPropertyName$1(prop) {
1832
+ const key = prop.key;
1833
+ if (key.type === "Identifier") return key.name;
1834
+ else if (key.type === "StringLiteral") return key.value;
1835
+ else if (key.type === "NumericLiteral") return String(key.value);
1836
+ }
1837
+ function getStringClassValue(node) {
1838
+ if (node.type === "StringLiteral") return (0, _vue_shared.normalizeClass)(node.value);
1839
+ else if (node.type === "TemplateLiteral" && node.expressions.length === 0) return (0, _vue_shared.normalizeClass)(node.quasis[0].value.cooked || "");
1840
+ else if (node.type === "NullLiteral" || node.type === "BooleanLiteral" && !node.value) return "";
1841
+ }
1842
+ function getBooleanValue(node) {
1843
+ if (node.type === "BooleanLiteral") return node.value;
1844
+ }
1845
+ function createSubExpression(source, node, context) {
1846
+ const start = node.start == null ? 0 : node.start - 1;
1847
+ const end = node.end == null ? source.content.length : node.end - 1;
1848
+ const content = source.content.slice(start, end);
1849
+ const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
1850
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
1851
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
1852
+ source: content
1853
+ });
1854
+ expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
1855
+ return expression;
1856
+ }
1367
1857
  function genDynamicProps$1(oper, context) {
1368
1858
  const { helper } = context;
1369
1859
  const isSVG = (0, _vue_shared.isSVGTag)(oper.tag);
@@ -1392,7 +1882,12 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1392
1882
  if (runtimeCamelize) {
1393
1883
  key.push(" || \"\"");
1394
1884
  key = genCall(helper("camelize"), key);
1395
- }
1885
+ } else if (modifier) key = [
1886
+ "(",
1887
+ ...key,
1888
+ " || \"\"",
1889
+ ")"
1890
+ ];
1396
1891
  if (handler) key = genCall(helper("toHandlerKey"), key);
1397
1892
  return [
1398
1893
  "[",
@@ -1430,8 +1925,23 @@ function getSpecialHelper(keyName, tagName, isSVG) {
1430
1925
  const setTemplateRefIdent = `_setTemplateRef`;
1431
1926
  function genSetTemplateRef(oper, context) {
1432
1927
  const [refValue, refKey] = genRefValue(oper.value, context);
1928
+ if (context.staticTemplateRefHelperCandidate === oper) return genSetStaticTemplateRef(oper, refValue, refKey, context);
1929
+ context.needsTemplateRefSetter = true;
1433
1930
  return [NEWLINE, ...genCall(setTemplateRefIdent, `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
1434
1931
  }
1932
+ function genSetStaticTemplateRef(oper, refValue, refKey, context) {
1933
+ return [NEWLINE, ...genCall(context.helper("setStaticTemplateRef"), `n${oper.element}`, refValue, oper.refFor && "true", refKey)];
1934
+ }
1935
+ function genSetTemplateRefBinding(oper, context) {
1936
+ const [refValue, refKey] = genRefValue(oper.value, context);
1937
+ const setter = context.inSlotBlock && setTemplateRefIdent;
1938
+ if (context.inSlotBlock) context.needsTemplateRefSetter = true;
1939
+ return [NEWLINE, ...genCall([context.helper("setTemplateRefBinding"), "undefined"], `n${oper.element}`, ["() => ", ...refValue], ...setter || oper.refFor || refKey ? [
1940
+ setter,
1941
+ oper.refFor && "true",
1942
+ refKey
1943
+ ] : [])];
1944
+ }
1435
1945
  function genRefValue(value, context) {
1436
1946
  if (value && context.options.inline) {
1437
1947
  const binding = context.options.bindingMetadata[value.content];
@@ -1461,17 +1971,17 @@ function genGetTextChild(oper, context) {
1461
1971
  //#endregion
1462
1972
  //#region packages/compiler-vapor/src/generators/vShow.ts
1463
1973
  function genVShow(oper, context) {
1464
- const { deferred, element } = oper;
1465
- return [
1466
- NEWLINE,
1467
- deferred ? `deferredApplyVShows.push(() => ` : void 0,
1468
- ...genCall(context.helper("applyVShow"), `n${element}`, [
1469
- `() => (`,
1470
- ...genExpression(oper.dir.exp, context),
1471
- `)`
1472
- ]),
1473
- deferred ? `)` : void 0
1474
- ];
1974
+ const { element } = oper;
1975
+ return [NEWLINE, ...genCall(context.helper("applyVShow"), `n${element}`, [
1976
+ `() => (`,
1977
+ ...genExpression(oper.dir.exp, context),
1978
+ `)`
1979
+ ])];
1980
+ }
1981
+ //#endregion
1982
+ //#region packages/compiler-vapor/src/generators/modifier.ts
1983
+ function genDirectiveModifiers(modifiers) {
1984
+ return modifiers.map((value) => `${(0, _vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", ");
1475
1985
  }
1476
1986
  //#endregion
1477
1987
  //#region packages/compiler-vapor/src/generators/vModel.ts
@@ -1488,7 +1998,7 @@ function genVModel(oper, context) {
1488
1998
  `() => (`,
1489
1999
  ...genExpression(exp, context),
1490
2000
  `)`
1491
- ], genModelHandler(exp, context), modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : void 0)];
2001
+ ], genModelHandler(exp, context), modifiers.length ? `{ ${genDirectiveModifiers(modifiers.map((e) => e.content))} }` : void 0)];
1492
2002
  }
1493
2003
  function genModelHandler(exp, context) {
1494
2004
  return [
@@ -1530,25 +2040,31 @@ function genCustomDirectives(opers, context) {
1530
2040
  return genMulti(DELIMITERS_ARRAY.concat("void 0"), directiveVar, value, argument, modifiers);
1531
2041
  }
1532
2042
  }
1533
- function genDirectiveModifiers(modifiers) {
1534
- return modifiers.map((value) => `${(0, _vue_compiler_dom.isSimpleIdentifier)(value) ? value : JSON.stringify(value)}: true`).join(", ");
1535
- }
1536
2043
  function filterCustomDirectives(id, operations) {
1537
- return operations.filter((oper) => oper.type === 13 && oper.element === id && !oper.builtin);
2044
+ return operations.filter((oper) => oper.type === 14 && oper.element === id && !oper.builtin);
1538
2045
  }
1539
2046
  //#endregion
1540
2047
  //#region packages/compiler-vapor/src/generators/component.ts
2048
+ function genStaticModifierPropKey(name) {
2049
+ const key = (0, _vue_shared.getModifierPropName)(name);
2050
+ return [(0, _vue_compiler_dom.isSimpleIdentifier)(key) ? key : JSON.stringify(key)];
2051
+ }
1541
2052
  function genCreateComponent(operation, context) {
1542
2053
  const { helper } = context;
2054
+ const singleUseAssetComponentNames = context.singleUseAssetComponentNames;
2055
+ const useAssetComponentHelper = operation.asset && !operation.dynamic && context.block === context.ir.block && !!singleUseAssetComponentNames && singleUseAssetComponentNames.has(operation.tag);
2056
+ const maybeSelfReference = useAssetComponentHelper && operation.tag.endsWith("__self");
1543
2057
  const tag = genTag();
1544
- const { root, props, slots, once } = operation;
2058
+ const { root, props, slots, once, slotRoot } = operation;
2059
+ const isRuntimeDynamicComponent = !!(operation.dynamic && !operation.dynamic.isStatic);
2060
+ const dynamicComponentFlags = isRuntimeDynamicComponent ? genDynamicComponentFlags(root, once, slotRoot) : false;
1545
2061
  const rawSlots = genRawSlots(slots, context);
1546
2062
  const [ids, handlers] = processInlineHandlers(props, context);
1547
- const rawProps = context.withId(() => genRawProps(props, context), ids);
2063
+ const rawProps = context.withId(() => genRawProps(props, context, true), ids);
1548
2064
  return [
1549
2065
  NEWLINE,
1550
2066
  ...handlers.reduce((acc, { name, value }) => {
1551
- const handler = genEventHandler(context, [value], void 0, false, false);
2067
+ const handler = genEventHandler(context, [value]);
1552
2068
  return [
1553
2069
  ...acc,
1554
2070
  `const ${name} = `,
@@ -1557,18 +2073,21 @@ function genCreateComponent(operation, context) {
1557
2073
  ];
1558
2074
  }, []),
1559
2075
  `const n${operation.id} = `,
1560
- ...genCall(operation.dynamic && !operation.dynamic.isStatic ? helper("createDynamicComponent") : operation.isCustomElement ? helper("createPlainElement") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, root ? "true" : false, once && "true"),
2076
+ ...genCall(isRuntimeDynamicComponent ? helper("createDynamicComponent") : operation.useCreateElement ? helper("createPlainElement") : useAssetComponentHelper ? helper("createAssetComponent") : operation.asset ? helper("createComponentWithFallback") : helper("createComponent"), tag, rawProps, rawSlots, isRuntimeDynamicComponent ? dynamicComponentFlags : root ? "true" : false, isRuntimeDynamicComponent ? false : once && "true", isRuntimeDynamicComponent ? false : maybeSelfReference && "true"),
1561
2077
  ...genDirectivesForElement(operation.id, context)
1562
2078
  ];
1563
2079
  function genTag() {
1564
- if (operation.isCustomElement) return JSON.stringify(operation.tag);
2080
+ if (operation.useCreateElement) return JSON.stringify(operation.tag);
1565
2081
  else if (operation.dynamic) if (operation.dynamic.isStatic) return genCall(helper("resolveDynamicComponent"), genExpression(operation.dynamic, context));
1566
2082
  else return [
1567
2083
  "() => (",
1568
2084
  ...genExpression(operation.dynamic, context),
1569
2085
  ")"
1570
2086
  ];
1571
- else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
2087
+ else if (useAssetComponentHelper) {
2088
+ const name = maybeSelfReference ? operation.tag.slice(0, -6) : operation.tag;
2089
+ return JSON.stringify(name);
2090
+ } else if (operation.asset) return (0, _vue_compiler_dom.toValidAssetId)(operation.tag, "component");
1572
2091
  else {
1573
2092
  const { tag } = operation;
1574
2093
  const builtInTag = isBuiltInComponent(tag);
@@ -1580,6 +2099,24 @@ function genCreateComponent(operation, context) {
1580
2099
  }
1581
2100
  }
1582
2101
  }
2102
+ function genDynamicComponentFlags(root, once, slotRoot) {
2103
+ let flags = 0;
2104
+ const names = [];
2105
+ if (root) {
2106
+ flags |= 1;
2107
+ names.push("SINGLE_ROOT");
2108
+ }
2109
+ if (once) {
2110
+ flags |= 2;
2111
+ names.push("ONCE");
2112
+ }
2113
+ if (slotRoot) {
2114
+ flags |= 4;
2115
+ names.push("SLOT_ROOT");
2116
+ }
2117
+ if (!flags) return false;
2118
+ return `${flags} /* ${names.join(", ")} */`;
2119
+ }
1583
2120
  function getUniqueHandlerName(context, name) {
1584
2121
  const { seenInlineHandlerNames } = context;
1585
2122
  name = genVarName(name);
@@ -1608,14 +2145,14 @@ function processInlineHandlers(props, context) {
1608
2145
  }
1609
2146
  return [ids, handlers];
1610
2147
  }
1611
- function genRawProps(props, context) {
2148
+ function genRawProps(props, context, directStaticLiteralProps = false) {
1612
2149
  const staticProps = props[0];
1613
2150
  if ((0, _vue_shared.isArray)(staticProps)) {
1614
2151
  if (!staticProps.length && props.length === 1) return;
1615
- return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context));
1616
- } else if (props.length) return genStaticProps([], context, genDynamicProps(props, context));
2152
+ return genStaticProps(staticProps, context, genDynamicProps(props.slice(1), context, directStaticLiteralProps), directStaticLiteralProps);
2153
+ } else if (props.length) return genStaticProps([], context, genDynamicProps(props, context, directStaticLiteralProps), directStaticLiteralProps);
1617
2154
  }
1618
- function genStaticProps(props, context, dynamicProps) {
2155
+ function genStaticProps(props, context, dynamicProps, directStaticLiteralProps = false) {
1619
2156
  const args = [];
1620
2157
  const handlerGroups = /* @__PURE__ */ new Map();
1621
2158
  const ensureHandlerGroup = (keyName, keyFrag) => {
@@ -1648,11 +2185,11 @@ function genStaticProps(props, context, dynamicProps) {
1648
2185
  continue;
1649
2186
  }
1650
2187
  const keyFrag = genPropKey(prop, context);
1651
- if (!!prop.handlerModifiers && (prop.handlerModifiers.keys.length > 0 || prop.handlerModifiers.nonKeys.length > 0) || prop.values.length <= 1) addHandler(keyName, keyFrag, genEventHandler(context, prop.values, prop.handlerModifiers, true, false));
1652
- else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, true, false));
2188
+ if (!!prop.handlerModifiers && (prop.handlerModifiers.keys.length > 0 || prop.handlerModifiers.nonKeys.length > 0) || prop.values.length <= 1) addHandler(keyName, keyFrag, genEventHandler(context, prop.values, prop.handlerModifiers, { asComponentProp: true }));
2189
+ else for (const value of prop.values) addHandler(keyName, keyFrag, genEventHandler(context, [value], prop.handlerModifiers, { asComponentProp: true }));
1653
2190
  continue;
1654
2191
  }
1655
- args.push(genProp(prop, context, true));
2192
+ args.push(genProp(prop, context, true, true, directStaticLiteralProps && isDirectStaticLiteralProp(prop, context)));
1656
2193
  if (prop.model) {
1657
2194
  if (prop.key.isStatic) {
1658
2195
  const keyName = `onUpdate:${(0, _vue_shared.camelize)(prop.key.content)}`;
@@ -1671,13 +2208,13 @@ function genStaticProps(props, context, dynamicProps) {
1671
2208
  }
1672
2209
  const { key, modelModifiers } = prop;
1673
2210
  if (modelModifiers && modelModifiers.length) {
1674
- const modifiersKey = key.isStatic ? [(0, _vue_shared.getModifierPropName)(key.content)] : [
2211
+ const modifiersKey = key.isStatic ? genStaticModifierPropKey(key.content) : [
1675
2212
  "[",
1676
2213
  ...genExpression(key, context),
1677
2214
  " + \"Modifiers\"]"
1678
2215
  ];
1679
2216
  const modifiersVal = genDirectiveModifiers(modelModifiers);
1680
- args.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
2217
+ args.push([...modifiersKey, directStaticLiteralProps ? `: { ${modifiersVal} }` : `: () => ({ ${modifiersVal} })`]);
1681
2218
  }
1682
2219
  }
1683
2220
  }
@@ -1692,13 +2229,13 @@ function genStaticProps(props, context, dynamicProps) {
1692
2229
  if (dynamicProps) args.push([`$: `, ...dynamicProps]);
1693
2230
  return genMulti(args.length > 1 ? DELIMITERS_OBJECT_NEWLINE : DELIMITERS_OBJECT, ...args);
1694
2231
  }
1695
- function genDynamicProps(props, context) {
2232
+ function genDynamicProps(props, context, directStaticLiteralProps = false) {
1696
2233
  const { helper } = context;
1697
2234
  const frags = [];
1698
2235
  for (const p of props) {
1699
2236
  let expr;
1700
2237
  if ((0, _vue_shared.isArray)(p)) {
1701
- if (p.length) frags.push(genStaticProps(p, context));
2238
+ if (p.length) frags.push(genStaticProps(p, context, void 0, directStaticLiteralProps));
1702
2239
  continue;
1703
2240
  } else if (p.kind === 1) if (p.model) {
1704
2241
  const entries = [genProp(p, context)];
@@ -1709,21 +2246,21 @@ function genDynamicProps(props, context) {
1709
2246
  ];
1710
2247
  entries.push([
1711
2248
  ...updateKey,
1712
- ": () => ",
2249
+ ": ",
1713
2250
  ...genModelHandler(p.values[0], context)
1714
2251
  ]);
1715
2252
  const { modelModifiers } = p;
1716
2253
  if (modelModifiers && modelModifiers.length) {
1717
- const modifiersKey = p.key.isStatic ? [(0, _vue_shared.getModifierPropName)(p.key.content)] : [
2254
+ const modifiersKey = p.key.isStatic ? genStaticModifierPropKey(p.key.content) : [
1718
2255
  "[",
1719
2256
  ...genExpression(p.key, context),
1720
2257
  " + \"Modifiers\"]"
1721
2258
  ];
1722
2259
  const modifiersVal = genDirectiveModifiers(modelModifiers);
1723
- entries.push([...modifiersKey, `: () => ({ ${modifiersVal} })`]);
2260
+ entries.push([...modifiersKey, `: { ${modifiersVal} }`]);
1724
2261
  }
1725
2262
  expr = genMulti(DELIMITERS_OBJECT_NEWLINE, ...entries);
1726
- } else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context));
2263
+ } else expr = genMulti(DELIMITERS_OBJECT, genProp(p, context, false, false));
1727
2264
  else {
1728
2265
  expr = genExpression(p.value, context);
1729
2266
  if (p.handler) expr = genCall(helper("toHandlers"), expr);
@@ -1736,27 +2273,79 @@ function genDynamicProps(props, context) {
1736
2273
  }
1737
2274
  if (frags.length) return genMulti(DELIMITERS_ARRAY_NEWLINE, ...frags);
1738
2275
  }
1739
- function genProp(prop, context, isStatic) {
2276
+ function genProp(prop, context, isStatic, wrapHandler = true, directStaticLiteral = false) {
1740
2277
  const values = genPropValue(prop.values, context);
1741
2278
  return [
1742
2279
  ...genPropKey(prop, context),
1743
2280
  ": ",
1744
- ...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, true, true) : isStatic ? [
2281
+ ...prop.handler ? genEventHandler(context, prop.values, prop.handlerModifiers, {
2282
+ asComponentProp: true,
2283
+ extraWrap: wrapHandler
2284
+ }) : isStatic ? directStaticLiteral ? values : [
1745
2285
  "() => (",
1746
2286
  ...values,
1747
2287
  ")"
1748
2288
  ] : values
1749
2289
  ];
1750
2290
  }
1751
- function genRawSlots(slots, context) {
1752
- if (!slots.length) return;
1753
- const staticSlots = slots[0];
1754
- if (staticSlots.slotType === 0) return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
1755
- else return genStaticSlots({
2291
+ /**
2292
+ * Static literal values are safe to emit directly because reading them cannot
2293
+ * touch reactive state. Keep handlers, v-model values, and dynamic expressions
2294
+ * as getter sources to preserve lazy access and merge semantics.
2295
+ */
2296
+ function isDirectStaticLiteralProp(prop, context) {
2297
+ return prop.key.isStatic && prop.values.length === 1 && !prop.handler && !prop.model && isDirectConstantValue(prop.values[0], context);
2298
+ }
2299
+ function isDirectConstantValue(value, context) {
2300
+ value = context.getExpressionReplacement(value);
2301
+ if (value.isStatic) return true;
2302
+ const ast = value.ast;
2303
+ if (ast === null) return value.content === "true" || value.content === "false" || value.content === "null" || value.content === "undefined";
2304
+ if (!ast) return false;
2305
+ return isDirectConstantAst(ast);
2306
+ }
2307
+ function isDirectConstantAst(node) {
2308
+ switch (node.type) {
2309
+ case "StringLiteral":
2310
+ case "NumericLiteral":
2311
+ case "BooleanLiteral":
2312
+ case "NullLiteral":
2313
+ case "BigIntLiteral": return true;
2314
+ case "Identifier": return node.name === "undefined";
2315
+ case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
2316
+ case "ArrayExpression": return node.elements.every((element) => element === null || element.type !== "SpreadElement" && isDirectConstantAst(element));
2317
+ case "ObjectExpression": return node.properties.every((prop) => prop.type === "ObjectProperty" && !prop.computed && isDirectConstantAst(prop.value));
2318
+ }
2319
+ return false;
2320
+ }
2321
+ function isDirectTemplateConstantAst(node) {
2322
+ switch (node.type) {
2323
+ case "StringLiteral":
2324
+ case "NumericLiteral":
2325
+ case "BooleanLiteral":
2326
+ case "NullLiteral":
2327
+ case "BigIntLiteral": return true;
2328
+ case "Identifier": return node.name === "undefined";
2329
+ case "TemplateLiteral": return node.expressions.every((expression) => isDirectTemplateConstantAst(expression));
2330
+ }
2331
+ return false;
2332
+ }
2333
+ function genRawSlots(slots, context) {
2334
+ if (!slots.length) return;
2335
+ const staticSlots = slots[0];
2336
+ if (staticSlots.slotType === 0) {
2337
+ const defaultSlot = getSingleDefaultSlot(staticSlots);
2338
+ if (defaultSlot && slots.length === 1) return genSlotBlockWithProps(defaultSlot, context);
2339
+ return genStaticSlots(staticSlots, context, slots.length > 1 ? slots.slice(1) : void 0);
2340
+ } else return genStaticSlots({
1756
2341
  slotType: 0,
1757
2342
  slots: {}
1758
2343
  }, context, slots);
1759
2344
  }
2345
+ function getSingleDefaultSlot({ slots }) {
2346
+ const names = Object.keys(slots);
2347
+ return names.length === 1 && names[0] === "default" ? slots.default : void 0;
2348
+ }
1760
2349
  function genStaticSlots({ slots }, context, dynamicSlots) {
1761
2350
  const args = Object.keys(slots).map((name) => [`${JSON.stringify(name)}: `, ...genSlotBlockWithProps(slots[name], context)]);
1762
2351
  if (dynamicSlots) args.push([`$: `, ...genDynamicSlots(dynamicSlots, context)]);
@@ -1778,15 +2367,16 @@ function genDynamicSlot(slot, context, withFunction = false) {
1778
2367
  frag = genConditionalSlot(slot, context);
1779
2368
  break;
1780
2369
  }
1781
- return withFunction ? [
2370
+ if (!withFunction) return frag;
2371
+ return [
1782
2372
  "() => (",
1783
2373
  ...frag,
1784
2374
  ")"
1785
- ] : frag;
2375
+ ];
1786
2376
  }
1787
2377
  function genBasicDynamicSlot(slot, context) {
1788
2378
  const { name, fn } = slot;
1789
- return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context)]);
2379
+ return genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...genExpression(name, context)], ["fn: ", ...genSlotBlockWithProps(fn, context, false)]);
1790
2380
  }
1791
2381
  function genLoopSlot(slot, context) {
1792
2382
  const { name, fn, loop } = slot;
@@ -1798,7 +2388,7 @@ function genLoopSlot(slot, context) {
1798
2388
  if (rawValue) idMap[rawValue] = rawValue;
1799
2389
  if (rawKey) idMap[rawKey] = rawKey;
1800
2390
  if (rawIndex) idMap[rawIndex] = rawIndex;
1801
- const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context), idMap)]);
2391
+ const slotExpr = genMulti(DELIMITERS_OBJECT_NEWLINE, ["name: ", ...context.withId(() => genExpression(name, context), idMap)], ["fn: ", ...context.withId(() => genSlotBlockWithProps(fn, context, false), idMap)]);
1802
2392
  return [...genCall(context.helper("createForSlots"), genExpression(source, context), [
1803
2393
  ...genMulti([
1804
2394
  "(",
@@ -1824,11 +2414,11 @@ function genConditionalSlot(slot, context) {
1824
2414
  INDENT_END
1825
2415
  ];
1826
2416
  }
1827
- function genSlotBlockWithProps(oper, context) {
2417
+ function genSlotBlockWithProps(oper, context, emitNonStableFlag = true) {
1828
2418
  let propsName;
1829
2419
  let exitScope;
1830
2420
  let depth;
1831
- const { props, node } = oper;
2421
+ const { props } = oper;
1832
2422
  const idToPathMap = props ? parseValueDestructure(props, context) : /* @__PURE__ */ new Map();
1833
2423
  if (props) if (props.ast) {
1834
2424
  [depth, exitScope] = context.enterScope();
@@ -1836,79 +2426,86 @@ function genSlotBlockWithProps(oper, context) {
1836
2426
  } else propsName = props.content;
1837
2427
  const idMap = idToPathMap.size ? buildDestructureIdMap(idToPathMap, propsName || "", context.options.expressionPlugins) : {};
1838
2428
  if (propsName) idMap[propsName] = null;
2429
+ const exitSlotBlock = context.enterSlotBlock();
2430
+ const hasStableRoot = hasStableSlotRoot(oper, context);
2431
+ if (!hasStableRoot) markSlotRootOperations(oper);
1839
2432
  let blockFn = context.withId(() => genBlock(oper, context, propsName ? [propsName] : []), idMap);
2433
+ if (emitNonStableFlag && !hasStableRoot) blockFn = genCall(context.helper("extend"), blockFn, [`{ _: ${genSlotFlags$1(8)} }`]);
2434
+ exitSlotBlock();
1840
2435
  exitScope && exitScope();
1841
- if (node.type === 1) {
1842
- if (needsVaporCtx(oper)) blockFn = [
1843
- `${context.helper("withVaporCtx")}(`,
1844
- ...blockFn,
1845
- `)`
1846
- ];
1847
- }
1848
2436
  return blockFn;
1849
2437
  }
1850
- /**
1851
- * Check if a slot block needs withVaporCtx wrapper.
1852
- * Returns true if the block contains:
1853
- * - Component creation (needs scopeId inheritance)
1854
- * - Slot outlet (needs rawSlots from slot owner)
1855
- */
1856
- function needsVaporCtx(block) {
1857
- return hasComponentOrSlotInBlock(block);
1858
- }
1859
- function hasComponentOrSlotInBlock(block) {
1860
- if (hasComponentOrSlotInOperations(block.operation)) return true;
1861
- return hasComponentOrSlotInDynamic(block.dynamic);
1862
- }
1863
- function hasComponentOrSlotInDynamic(dynamic) {
1864
- if (dynamic.operation) {
1865
- const type = dynamic.operation.type;
1866
- if (type === 11 || type === 12) return true;
1867
- if (type === 14) {
1868
- if (hasComponentOrSlotInIf(dynamic.operation)) return true;
2438
+ function genSlotFlags$1(flags) {
2439
+ const names = [];
2440
+ if (flags & 1) names.push("NO_SLOTTED");
2441
+ if (flags & 2) names.push("ONCE");
2442
+ if (flags & 4) names.push("SLOT_ROOT");
2443
+ if (flags & 8) names.push("NON_STABLE");
2444
+ return `${flags} /* ${names.join(", ")} */`;
2445
+ }
2446
+ const commentOnlyTemplateRE = /^(?:<!--[\s\S]*?-->)+$/;
2447
+ function hasStableSlotRoot(block, context) {
2448
+ let hasValidRoot = false;
2449
+ for (let i = 0; i < block.returns.length; i++) {
2450
+ const id = block.returns[i];
2451
+ const child = findReturnedDynamic$1(block, id);
2452
+ const operation = child && child.operation;
2453
+ if (!operation) {
2454
+ if (child && isStableTemplateSlotRoot(child, context)) hasValidRoot = true;
2455
+ continue;
1869
2456
  }
1870
- if (type === 15) {
1871
- if (hasComponentOrSlotInBlock(dynamic.operation.render)) return true;
2457
+ switch (operation.type) {
2458
+ case 12:
2459
+ if (!operation.dynamic || operation.dynamic.isStatic) {
2460
+ hasValidRoot = true;
2461
+ continue;
2462
+ }
2463
+ continue;
2464
+ case 17:
2465
+ if (hasStableSlotRoot(operation.block, context)) {
2466
+ hasValidRoot = true;
2467
+ continue;
2468
+ }
2469
+ continue;
2470
+ default: continue;
1872
2471
  }
1873
2472
  }
1874
- for (const child of dynamic.children) if (hasComponentOrSlotInDynamic(child)) return true;
1875
- return false;
1876
- }
1877
- function hasComponentOrSlotInOperations(operations) {
1878
- for (const op of operations) switch (op.type) {
1879
- case 11:
1880
- case 12: return true;
1881
- case 14:
1882
- if (hasComponentOrSlotInIf(op)) return true;
1883
- break;
1884
- case 15:
1885
- if (hasComponentOrSlotInBlock(op.render)) return true;
1886
- break;
1887
- }
1888
- return false;
2473
+ return hasValidRoot;
1889
2474
  }
1890
- function hasComponentOrSlotInIf(node) {
1891
- if (hasComponentOrSlotInBlock(node.positive)) return true;
1892
- if (node.negative) if ("positive" in node.negative) return hasComponentOrSlotInIf(node.negative);
1893
- else return hasComponentOrSlotInBlock(node.negative);
1894
- return false;
2475
+ function isStableTemplateSlotRoot(child, context) {
2476
+ if (child.template == null) return false;
2477
+ const content = context.ir.template.entries[child.template].content;
2478
+ return content !== "" && !commentOnlyTemplateRE.test(content.trim());
1895
2479
  }
1896
2480
  //#endregion
1897
2481
  //#region packages/compiler-vapor/src/generators/slotOutlet.ts
1898
2482
  function genSlotOutlet(oper, context) {
1899
2483
  const { helper } = context;
1900
- const { id, name, fallback, noSlotted, once } = oper;
2484
+ const { id, name, fallback, flags } = oper;
1901
2485
  const [frag, push] = buildCodeFragment();
1902
- const nameExpr = name.isStatic ? genExpression(name, context) : [
2486
+ let fallbackArg;
2487
+ if (fallback) {
2488
+ if (context.inSlotBlock) markSlotRootOperations(fallback);
2489
+ fallbackArg = genBlock(fallback, context);
2490
+ }
2491
+ const createSlot = helper("createSlot");
2492
+ const rawPropsArg = genRawProps(oper.props, context, true);
2493
+ const nameArg = name.isStatic && name.content === "default" && !rawPropsArg && !fallbackArg && !flags ? void 0 : name.isStatic ? genExpression(name, context) : [
1903
2494
  "() => (",
1904
2495
  ...genExpression(name, context),
1905
2496
  ")"
1906
2497
  ];
1907
- let fallbackArg;
1908
- if (fallback) fallbackArg = genBlock(fallback, context);
1909
- push(NEWLINE, `const n${id} = `, ...genCall(helper("createSlot"), nameExpr, genRawProps(oper.props, context) || "null", fallbackArg, noSlotted && "true", once && "true"));
2498
+ push(NEWLINE, `const n${id} = `, ...genCall(createSlot, nameArg, rawPropsArg, fallbackArg, genSlotFlags(flags)));
1910
2499
  return frag;
1911
2500
  }
2501
+ function genSlotFlags(flags) {
2502
+ if (!flags) return;
2503
+ const names = [];
2504
+ if (flags & 1) names.push("NO_SLOTTED");
2505
+ if (flags & 2) names.push("ONCE");
2506
+ if (flags & 4) names.push("SLOT_ROOT");
2507
+ return `${flags} /* ${names.join(", ")} */`;
2508
+ }
1912
2509
  //#endregion
1913
2510
  //#region packages/compiler-vapor/src/generators/key.ts
1914
2511
  function genKey(oper, context) {
@@ -1922,6 +2519,9 @@ function genKey(oper, context) {
1922
2519
  ], blockFn));
1923
2520
  return frag;
1924
2521
  }
2522
+ function genSetBlockKey(oper, context) {
2523
+ return [NEWLINE, ...genCall(context.helper("setBlockKey"), `n${oper.element}`, genExpression(oper.value, context))];
2524
+ }
1925
2525
  //#endregion
1926
2526
  //#region packages/compiler-vapor/src/generators/operation.ts
1927
2527
  function genOperations(opers, context) {
@@ -1937,25 +2537,24 @@ function genOperationWithInsertionState(oper, context) {
1937
2537
  }
1938
2538
  function genOperation(oper, context) {
1939
2539
  switch (oper.type) {
1940
- case 2: return genSetProp(oper, context);
1941
- case 3: return genDynamicProps$1(oper, context);
1942
- case 4: return genSetText(oper, context);
1943
- case 5: return genSetEvent(oper, context);
1944
- case 6: return genSetDynamicEvents(oper, context);
1945
- case 7: return genSetHtml(oper, context);
1946
- case 8: return genSetTemplateRef(oper, context);
1947
- case 9: return genInsertNode(oper, context);
1948
- case 10: return genPrependNode(oper, context);
1949
- case 14: return genIf(oper, context);
1950
- case 15: return genFor(oper, context);
1951
- case 16: return genKey(oper, context);
1952
- case 11: return genCreateComponent(oper, context);
1953
- case 12: return genSlotOutlet(oper, context);
1954
- case 13: return genBuiltinDirective(oper, context);
1955
- case 17: return genGetTextChild(oper, context);
1956
- default:
1957
- const exhaustiveCheck = oper;
1958
- throw new Error(`Unhandled operation type in genOperation: ${exhaustiveCheck}`);
2540
+ case 2: return genSetBlockKey(oper, context);
2541
+ case 3: return genSetProp(oper, context);
2542
+ case 4: return genDynamicProps$1(oper, context);
2543
+ case 5: return genSetText(oper, context);
2544
+ case 6: return genSetEvent(oper, context);
2545
+ case 7: return genSetDynamicEvents(oper, context);
2546
+ case 8: return genSetHtml(oper, context);
2547
+ case 9: return genSetTemplateRef(oper, context);
2548
+ case 10: return genInsertNode(oper, context);
2549
+ case 11: return genPrependNode(oper, context);
2550
+ case 15: return genIf(oper, context);
2551
+ case 16: return genFor(oper, context);
2552
+ case 17: return genKey(oper, context);
2553
+ case 12: return genCreateComponent(oper, context);
2554
+ case 13: return genSlotOutlet(oper, context);
2555
+ case 14: return genBuiltinDirective(oper, context);
2556
+ case 18: return genGetTextChild(oper, context);
2557
+ default: throw new Error(`Unhandled operation type in genOperation: ${oper}`);
1959
2558
  }
1960
2559
  }
1961
2560
  function genEffects(effects, context, genExtraFrag) {
@@ -1964,28 +2563,35 @@ function genEffects(effects, context, genExtraFrag) {
1964
2563
  const [frag, push, unshift] = buildCodeFragment();
1965
2564
  const shouldDeclare = genExtraFrag === void 0;
1966
2565
  let operationsCount = 0;
1967
- const { ids, frag: declarationFrags, varNames } = processExpressions(context, expressions, shouldDeclare);
1968
- push(...declarationFrags);
1969
- for (let i = 0; i < effects.length; i++) {
1970
- const effect = effects[i];
1971
- operationsCount += effect.operations.length;
1972
- const frags = context.withId(() => genEffect(effect, context), ids);
1973
- i > 0 && push(NEWLINE);
1974
- if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
1975
- push(...frags);
1976
- }
1977
- if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
1978
- unshift(`{`, INDENT_START, NEWLINE);
1979
- push(INDENT_END, NEWLINE, "}");
1980
- if (!effects.length) unshift(NEWLINE);
1981
- }
1982
- if (effects.length) {
1983
- unshift(NEWLINE, `${helper("renderEffect")}(() => `);
1984
- push(`)`);
1985
- }
1986
- if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
1987
- if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
1988
- return frag;
2566
+ const { ids, frag: declarationFrags, varNames, expressionReplacements } = processExpressions(context, expressions, shouldDeclare);
2567
+ if (shouldDeclare && !declarationFrags.length && !varNames.length) {
2568
+ const effect = effects.length === 1 ? effects[0] : void 0;
2569
+ const operation = effect && effect.operations.length === 1 ? effect.operations[0] : void 0;
2570
+ if (operation && operation.type === 9 && operation.effect && !operation.refFor) return context.withExpressionReplacements(expressionReplacements, () => context.withId(() => genSetTemplateRefBinding(operation, context), ids));
2571
+ }
2572
+ return context.withExpressionReplacements(expressionReplacements, () => {
2573
+ push(...declarationFrags);
2574
+ for (let i = 0; i < effects.length; i++) {
2575
+ const effect = effects[i];
2576
+ operationsCount += effect.operations.length;
2577
+ const frags = context.withId(() => genEffect(effect, context), ids);
2578
+ i > 0 && push(NEWLINE);
2579
+ if (frag[frag.length - 1] === ")" && frags[0] === "(") push(";");
2580
+ push(...frags);
2581
+ }
2582
+ if (frag.filter((frag) => frag === NEWLINE).length > 1 || operationsCount > 1 || declarationFrags.length > 0) {
2583
+ unshift(`{`, INDENT_START, NEWLINE);
2584
+ push(INDENT_END, NEWLINE, "}");
2585
+ if (!effects.length) unshift(NEWLINE);
2586
+ }
2587
+ if (effects.length) {
2588
+ unshift(NEWLINE, `${helper("renderEffect")}(() => `);
2589
+ push(`)`);
2590
+ }
2591
+ if (!shouldDeclare && varNames.length) unshift(NEWLINE, `let `, varNames.join(", "));
2592
+ if (genExtraFrag) push(...context.withId(genExtraFrag, ids));
2593
+ return frag;
2594
+ });
1989
2595
  }
1990
2596
  function genEffect({ operations }, context) {
1991
2597
  const [frag, push] = buildCodeFragment();
@@ -1995,21 +2601,24 @@ function genEffect({ operations }, context) {
1995
2601
  return frag;
1996
2602
  }
1997
2603
  function genInsertionState(operation, context) {
1998
- const { parent, anchor, logicalIndex, append, last } = operation;
1999
- return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${parent}`, anchor == null ? void 0 : anchor === -1 ? `0` : append ? "null" : `n${anchor}`, logicalIndex !== void 0 ? String(logicalIndex) : void 0, last && "true")];
2604
+ const { parent, anchor, logicalIndex, append } = operation;
2605
+ const isPrepend = anchor === -1;
2606
+ return [NEWLINE, ...genCall(context.helper("setInsertionState"), `n${parent}`, anchor == null ? void 0 : isPrepend ? `0` : append ? "null" : `n${anchor}`, logicalIndex !== void 0 && (!isPrepend || logicalIndex !== 0) ? String(logicalIndex) : void 0)];
2000
2607
  }
2001
2608
  //#endregion
2002
2609
  //#region packages/compiler-vapor/src/generators/template.ts
2003
- function genTemplates(templates, rootIndexes, context) {
2610
+ function genTemplates(templates, context) {
2004
2611
  const result = [];
2005
- let i = 0;
2006
- templates.forEach((ns, template) => {
2007
- result.push(`const ${context.tName(i)} = ${context.helper("template")}(${JSON.stringify(template).replace(IMPORT_EXPR_RE, `" + $1 + "`)}${rootIndexes.has(i) ? ", true" : ns ? ", false" : ""}${ns ? `, ${ns}` : ""})\n`);
2008
- i++;
2612
+ templates.forEach(({ content, ns, root, static: isStatic }, i) => {
2613
+ let args = JSON.stringify(content).replace(IMPORT_EXPR_RE, `" + $1 + "`);
2614
+ const flags = (root ? 1 : 0) | (isStatic ? 2 : 0);
2615
+ if (flags || ns) args += `, ${flags}`;
2616
+ if (ns) args += `, ${ns}`;
2617
+ result.push(`const ${context.tName(i)} = ${context.helper("template")}(${args})\n`);
2009
2618
  });
2010
2619
  return result.join("");
2011
2620
  }
2012
- function genSelf(dynamic, context) {
2621
+ function genSelf(dynamic, context, flushBeforeDynamic) {
2013
2622
  const [frag, push] = buildCodeFragment();
2014
2623
  const { id, template, operation, hasDynamicChild } = dynamic;
2015
2624
  if (id !== void 0 && template !== void 0) {
@@ -2017,46 +2626,145 @@ function genSelf(dynamic, context) {
2017
2626
  push(...genDirectivesForElement(id, context));
2018
2627
  }
2019
2628
  if (operation) push(...genOperationWithInsertionState(operation, context));
2020
- if (hasDynamicChild) push(...genChildren(dynamic, context, push, `n${id}`));
2629
+ if (hasDynamicChild) push(...genChildren(dynamic, context, push, `n${id}`, flushBeforeDynamic));
2021
2630
  return frag;
2022
2631
  }
2023
- function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2024
- const { helper } = context;
2632
+ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`, flushBeforeDynamic) {
2025
2633
  const [frag, push] = buildCodeFragment();
2026
2634
  const { children } = dynamic;
2027
2635
  let offset = 0;
2636
+ /**
2637
+ * `reusable` means the previous access target is a p* cursor that can be
2638
+ * reassigned by the next lookup. Referenced n* variables must stay stable.
2639
+ */
2028
2640
  let prev;
2029
2641
  for (const [index, child] of children.entries()) {
2030
2642
  if (child.flags & 2) offset--;
2031
2643
  if (child.flags & 4 && child.template != null) {
2032
- push(...genSelf(child, context));
2644
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2645
+ push(...genSelf(child, context, flushBeforeDynamic));
2033
2646
  continue;
2034
2647
  }
2035
2648
  const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2036
2649
  if (id === void 0 && !child.hasDynamicChild) {
2037
- push(...genSelf(child, context));
2650
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2651
+ push(...genSelf(child, context, flushBeforeDynamic));
2038
2652
  continue;
2039
2653
  }
2040
2654
  const elementIndex = index + offset;
2041
2655
  const logicalIndex = child.logicalIndex !== void 0 ? String(child.logicalIndex) : void 0;
2042
- const variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
2043
- pushBlock(NEWLINE, `const ${variable} = `);
2044
- if (prev) if (elementIndex - prev[1] === 1) pushBlock(...genCall(helper("next"), prev[0], logicalIndex));
2045
- else pushBlock(...genCall(helper("nthChild"), from, String(elementIndex), logicalIndex));
2046
- else if (elementIndex === 0) pushBlock(...genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0));
2047
- else {
2048
- let init = genCall(helper("child"), from);
2049
- if (elementIndex === 1) init = genCall(helper("next"), init, logicalIndex);
2050
- else if (elementIndex > 1) init = genCall(helper("nthChild"), from, String(elementIndex), logicalIndex);
2051
- pushBlock(...init);
2656
+ const inlinePlaceholder = id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6);
2657
+ const accessPath = genAccessPath(context, from, child, elementIndex, logicalIndex, prev);
2658
+ if (inlinePlaceholder) {
2659
+ if (prev && prev[2]) {
2660
+ push(...genChildren(child, context, pushBlock, [
2661
+ "(",
2662
+ prev[0],
2663
+ " = ",
2664
+ ...accessPath,
2665
+ ")"
2666
+ ], flushBeforeDynamic));
2667
+ prev = [
2668
+ prev[0],
2669
+ elementIndex,
2670
+ true
2671
+ ];
2672
+ continue;
2673
+ }
2674
+ if (!hasAdjacentFollowingAccessChild(children, index, elementIndex, offset)) {
2675
+ push(...genChildren(child, context, pushBlock, accessPath, flushBeforeDynamic));
2676
+ continue;
2677
+ }
2678
+ }
2679
+ let variable;
2680
+ if (id === void 0 && prev && prev[2]) {
2681
+ variable = prev[0];
2682
+ pushBlock(NEWLINE, `${variable} = `, ...accessPath);
2683
+ } else {
2684
+ variable = id === void 0 ? context.pName(context.block.tempId++) : `n${id}`;
2685
+ pushBlock(NEWLINE, id === void 0 ? `let ${variable} = ` : `const ${variable} = `, ...accessPath);
2686
+ }
2687
+ if (id === child.anchor && !child.hasDynamicChild) {
2688
+ flushBeforeDynamic && flushBeforeDynamic(child, push);
2689
+ push(...genSelf(child, context, flushBeforeDynamic));
2052
2690
  }
2053
- if (id === child.anchor && !child.hasDynamicChild) push(...genSelf(child, context));
2054
2691
  if (id !== void 0) push(...genDirectivesForElement(id, context));
2055
- prev = [variable, elementIndex];
2056
- push(...genChildren(child, context, pushBlock, variable));
2692
+ prev = [
2693
+ variable,
2694
+ elementIndex,
2695
+ id === void 0
2696
+ ];
2697
+ push(...genChildren(child, context, pushBlock, variable, flushBeforeDynamic));
2057
2698
  }
2058
2699
  return frag;
2059
2700
  }
2701
+ /**
2702
+ * Build one DOM lookup path while preserving the fast sibling walk:
2703
+ * adjacent nodes use _next(prev), otherwise fall back to _nthChild(parent).
2704
+ */
2705
+ function genAccessPath({ helper }, from, child, elementIndex, logicalIndex, prev) {
2706
+ if (prev) return elementIndex - prev[1] === 1 ? genCall(helper("next"), prev[0], logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
2707
+ if (elementIndex === 0) return genCall(helper("child"), from, child.logicalIndex !== 0 ? logicalIndex : void 0);
2708
+ const firstChild = genCall(helper("child"), from);
2709
+ return elementIndex === 1 ? genCall(helper("next"), firstChild, logicalIndex) : genNthChild(helper("nthChild"), from, elementIndex, logicalIndex);
2710
+ }
2711
+ /**
2712
+ * Only inline a placeholder when materializing it would not save a parent
2713
+ * lookup. If its child tree needs the parent more than once, keep p* so the
2714
+ * generated code does not duplicate _child/_nthChild work.
2715
+ */
2716
+ function canInlinePlaceholder(dynamic) {
2717
+ return dynamic.hasDynamicChild === true && countParentAccessUsages(dynamic) === 1;
2718
+ }
2719
+ /**
2720
+ * A following access can reuse the current placeholder cursor only when it is
2721
+ * the next DOM sibling. Gapped siblings need _nthChild(parent, index) instead.
2722
+ */
2723
+ function hasAdjacentFollowingAccessChild(children, index, elementIndex, offset) {
2724
+ let futureOffset = offset;
2725
+ for (let i = index + 1; i < children.length; i++) {
2726
+ const child = children[i];
2727
+ if (child.flags & 2) futureOffset--;
2728
+ if (!(child.flags & 4 && child.template != null) && (!!(child.flags & 1) || child.hasDynamicChild)) return i + futureOffset - elementIndex === 1;
2729
+ }
2730
+ return false;
2731
+ }
2732
+ /**
2733
+ * Mirrors genChildren's traversal closely enough to count how many emitted
2734
+ * access paths would start from this placeholder's parent. This is the guard
2735
+ * that keeps inline placeholders from duplicating parent lookups.
2736
+ */
2737
+ function countParentAccessUsages(dynamic) {
2738
+ let usages = 0;
2739
+ let offset = 0;
2740
+ let prev;
2741
+ for (const [index, child] of dynamic.children.entries()) {
2742
+ if (child.flags & 2) offset--;
2743
+ if (child.flags & 4 && child.template != null) continue;
2744
+ const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2745
+ if (id === void 0 && !child.hasDynamicChild) continue;
2746
+ const elementIndex = index + offset;
2747
+ const usesParent = !prev || elementIndex - prev[0] !== 1;
2748
+ if (id === void 0 && canInlinePlaceholder(child) && child.template == null && child.operation === void 0 && !(child.flags & 6)) {
2749
+ if (prev && prev[1]) {
2750
+ if (usesParent) usages++;
2751
+ prev = [elementIndex, true];
2752
+ continue;
2753
+ }
2754
+ if (!hasAdjacentFollowingAccessChild(dynamic.children, index, elementIndex, offset)) {
2755
+ if (usesParent) usages++;
2756
+ continue;
2757
+ }
2758
+ }
2759
+ if (usesParent) usages++;
2760
+ prev = [elementIndex, id === void 0];
2761
+ }
2762
+ return usages;
2763
+ }
2764
+ function genNthChild(nthChild, from, elementIndex, logicalIndex) {
2765
+ const index = String(elementIndex);
2766
+ return genCall(nthChild, from, index, logicalIndex === index ? void 0 : logicalIndex);
2767
+ }
2060
2768
  //#endregion
2061
2769
  //#region packages/compiler-vapor/src/generators/block.ts
2062
2770
  function genBlock(oper, context, args = [], root) {
@@ -2071,12 +2779,16 @@ function genBlock(oper, context, args = [], root) {
2071
2779
  "}"
2072
2780
  ];
2073
2781
  }
2074
- function genBlockContent(block, context, root, genEffectsExtraFrag) {
2782
+ function genBlockContent(block, context, root, genEffectsExtraFrag, skippedEffectIndexes) {
2075
2783
  const [frag, push] = buildCodeFragment();
2076
2784
  const { dynamic, effect, operation, returns } = block;
2077
2785
  const resetBlock = context.enterBlock(block);
2786
+ const singleUseAssetComponentNames = root ? collectSingleUseAssetComponents(block) : void 0;
2787
+ const prevSingleUseAssetComponentNames = context.singleUseAssetComponentNames;
2788
+ if (singleUseAssetComponentNames) context.singleUseAssetComponentNames = singleUseAssetComponentNames;
2078
2789
  if (root) {
2079
2790
  for (let name of context.ir.component) {
2791
+ if (singleUseAssetComponentNames && singleUseAssetComponentNames.has(name)) continue;
2080
2792
  const id = (0, _vue_compiler_dom.toValidAssetId)(name, "component");
2081
2793
  const maybeSelfReference = name.endsWith("__self");
2082
2794
  if (maybeSelfReference) name = name.slice(0, -6);
@@ -2084,24 +2796,167 @@ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2084
2796
  }
2085
2797
  genResolveAssets("directive", "resolveDirective");
2086
2798
  }
2087
- for (const child of dynamic.children) push(...genSelf(child, context));
2088
- for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`));
2089
- push(...genOperations(operation, context));
2090
- push(...genEffects(effect, context, genEffectsExtraFrag));
2091
- if (root && context.ir.hasDeferredVShow) push(NEWLINE, `deferredApplyVShows.forEach(fn => fn())`);
2799
+ let operationIndex = 0;
2800
+ let effectIndex = 0;
2801
+ const flushPendingOperations = (operationEnd, effectEnd, push) => {
2802
+ while (operationIndex < operationEnd) {
2803
+ push(...genOperationWithInsertionState(operation[operationIndex], context));
2804
+ operationIndex++;
2805
+ }
2806
+ if (effectIndex < effectEnd) {
2807
+ push(...genEffectRange(effectIndex, effectEnd));
2808
+ effectIndex = effectEnd;
2809
+ }
2810
+ };
2811
+ const flushBeforeDynamic = (dynamic, push) => {
2812
+ const operation = dynamic.operation;
2813
+ if (operation && isBlockOperation(operation) && operation.operationIndex !== void 0 && operation.effectIndex !== void 0) flushPendingOperations(operation.operationIndex, operation.effectIndex, push);
2814
+ };
2815
+ for (const child of dynamic.children) {
2816
+ flushBeforeDynamic(child, push);
2817
+ push(...genSelf(child, context, flushBeforeDynamic));
2818
+ }
2819
+ for (const child of dynamic.children) if (!child.hasDynamicChild) push(...genChildren(child, context, push, `n${child.id}`, flushBeforeDynamic));
2820
+ if (operationIndex < operation.length) push(...genOperations(operation.slice(operationIndex), context));
2821
+ if (effectIndex < effect.length) push(...genEffectRange(effectIndex, effect.length, genEffectsExtraFrag));
2822
+ else if (genEffectsExtraFrag) push(...genEffects([], context, genEffectsExtraFrag));
2092
2823
  push(NEWLINE, `return `);
2093
2824
  const returnNodes = returns.map((n) => `n${n}`);
2094
- push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"]);
2825
+ push(...returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "[]"]);
2095
2826
  resetBlock();
2827
+ context.singleUseAssetComponentNames = prevSingleUseAssetComponentNames;
2096
2828
  return frag;
2829
+ function genEffectRange(start, end, genExtraFrag) {
2830
+ if (!skippedEffectIndexes) return genEffects(effect.slice(start, end), context, genExtraFrag);
2831
+ const effects = [];
2832
+ for (let i = start; i < end; i++) if (!skippedEffectIndexes.has(i)) effects.push(effect[i]);
2833
+ if (effects.length || genExtraFrag) return genEffects(effects, context, genExtraFrag);
2834
+ return [];
2835
+ }
2097
2836
  function genResolveAssets(kind, helper) {
2098
2837
  for (const name of context.ir[kind]) push(NEWLINE, `const ${(0, _vue_compiler_dom.toValidAssetId)(name, kind)} = `, ...genCall(context.helper(helper), JSON.stringify(name)));
2099
2838
  }
2100
2839
  }
2840
+ function markSlotRootOperations(block) {
2841
+ for (let i = 0; i < block.returns.length; i++) {
2842
+ const child = findReturnedDynamic$1(block, block.returns[i]);
2843
+ const operation = child && child.operation;
2844
+ if (!operation) continue;
2845
+ if (operation.type === 15) markSlotRootIf(operation);
2846
+ else if (operation.type === 16) markSlotRootFor(operation);
2847
+ else if (operation.type === 12) markSlotRootComponent(operation);
2848
+ }
2849
+ }
2850
+ function markSlotRootIf(operation) {
2851
+ if (!operation.once) operation.slotRoot = true;
2852
+ markSlotRootOperations(operation.positive);
2853
+ const negative = operation.negative;
2854
+ if (!negative) return;
2855
+ if (negative.type === 15) markSlotRootIf(negative);
2856
+ else markSlotRootOperations(negative);
2857
+ }
2858
+ function markSlotRootFor(operation) {
2859
+ if (!operation.once) operation.slotRoot = true;
2860
+ markSlotRootOperations(operation.render);
2861
+ }
2862
+ function markSlotRootComponent(operation) {
2863
+ if (!operation.once && operation.dynamic && !operation.dynamic.isStatic) operation.slotRoot = true;
2864
+ }
2865
+ function findReturnedDynamic$1(block, id) {
2866
+ for (let i = 0; i < block.dynamic.children.length; i++) {
2867
+ const child = block.dynamic.children[i];
2868
+ if (child.id === id) return child;
2869
+ }
2870
+ }
2871
+ function collectSingleUseAssetComponents(block) {
2872
+ const usageMap = /* @__PURE__ */ new Map();
2873
+ const seenOperations = /* @__PURE__ */ new Set();
2874
+ visitBlock(block, true);
2875
+ const names = /* @__PURE__ */ new Set();
2876
+ for (const [name, usage] of usageMap) if (usage.count === 1 && usage.root) names.add(name);
2877
+ return names;
2878
+ function visitBlock(block, rootCandidate) {
2879
+ visitDynamic(block.dynamic, rootCandidate);
2880
+ for (const operation of block.operation) visitOperation(operation, rootCandidate);
2881
+ for (const effect of block.effect) for (const operation of effect.operations) visitOperation(operation, false);
2882
+ }
2883
+ function visitDynamic(dynamic, rootCandidate) {
2884
+ if (dynamic.operation) visitOperation(dynamic.operation, rootCandidate);
2885
+ for (const child of dynamic.children) visitDynamic(child, rootCandidate);
2886
+ }
2887
+ function visitOperation(operation, rootCandidate) {
2888
+ if (seenOperations.has(operation)) return;
2889
+ seenOperations.add(operation);
2890
+ if (operation.type === 12) {
2891
+ if (operation.asset) {
2892
+ const usage = usageMap.get(operation.tag) || {
2893
+ count: 0,
2894
+ root: false
2895
+ };
2896
+ usage.count++;
2897
+ if (rootCandidate) usage.root = true;
2898
+ usageMap.set(operation.tag, usage);
2899
+ }
2900
+ visitSlots(operation.slots);
2901
+ return;
2902
+ }
2903
+ switch (operation.type) {
2904
+ case 15:
2905
+ visitBlock(operation.positive, false);
2906
+ if (operation.negative) if (operation.negative.type === 15) visitOperation(operation.negative, false);
2907
+ else visitBlock(operation.negative, false);
2908
+ break;
2909
+ case 16:
2910
+ visitBlock(operation.render, false);
2911
+ break;
2912
+ case 17:
2913
+ visitBlock(operation.block, false);
2914
+ break;
2915
+ case 13:
2916
+ if (operation.fallback) visitBlock(operation.fallback, false);
2917
+ break;
2918
+ }
2919
+ }
2920
+ function visitSlots(slots) {
2921
+ for (const slot of slots) switch (slot.slotType) {
2922
+ case 0:
2923
+ for (const name in slot.slots) visitBlock(slot.slots[name], false);
2924
+ break;
2925
+ case 1:
2926
+ case 2:
2927
+ visitBlock(slot.fn, false);
2928
+ break;
2929
+ case 3:
2930
+ visitSlots([slot.positive]);
2931
+ if (slot.negative) visitSlots([slot.negative]);
2932
+ break;
2933
+ }
2934
+ }
2935
+ }
2101
2936
  //#endregion
2102
2937
  //#region packages/compiler-vapor/src/generate.ts
2103
2938
  const idWithTrailingDigitsRE = /^([A-Za-z_$][\w$]*)(\d+)$/;
2939
+ const helperNameAliases = {
2940
+ withVaporKeys: "withKeys",
2941
+ withVaporModifiers: "withModifiers"
2942
+ };
2104
2943
  var CodegenContext = class {
2944
+ withExpressionReplacements(map, fn) {
2945
+ if (map.size === 0) return fn();
2946
+ this.expressionReplacements.unshift(map);
2947
+ try {
2948
+ return fn();
2949
+ } finally {
2950
+ (0, _vue_shared.remove)(this.expressionReplacements, map);
2951
+ }
2952
+ }
2953
+ getExpressionReplacement(node) {
2954
+ for (const map of this.expressionReplacements) {
2955
+ const replacement = map.get(node);
2956
+ if (replacement) return replacement;
2957
+ }
2958
+ return node;
2959
+ }
2105
2960
  withId(fn, map) {
2106
2961
  const { identifiers } = this;
2107
2962
  const ids = Object.keys(map);
@@ -2118,9 +2973,19 @@ var CodegenContext = class {
2118
2973
  this.block = block;
2119
2974
  return () => this.block = parent;
2120
2975
  }
2976
+ enterSlotBlock() {
2977
+ const parent = this.inSlotBlock;
2978
+ this.inSlotBlock = true;
2979
+ return () => this.inSlotBlock = parent;
2980
+ }
2121
2981
  enterScope() {
2122
2982
  return [this.scopeLevel++, () => this.scopeLevel--];
2123
2983
  }
2984
+ isHelperNameAvailable(name) {
2985
+ if (this.bindingNames.has(name)) return false;
2986
+ for (const alias of this.helpers.values()) if (alias === name) return false;
2987
+ return true;
2988
+ }
2124
2989
  initNextIdMap() {
2125
2990
  if (this.bindingNames.size === 0) return;
2126
2991
  const map = /* @__PURE__ */ new Map();
@@ -2155,26 +3020,36 @@ var CodegenContext = class {
2155
3020
  this.ir = ir;
2156
3021
  this.bindingNames = /* @__PURE__ */ new Set();
2157
3022
  this.helpers = /* @__PURE__ */ new Map();
3023
+ this.needsTemplateRefSetter = false;
3024
+ this.inSlotBlock = false;
2158
3025
  this.helper = (name) => {
2159
3026
  if (this.helpers.has(name)) return this.helpers.get(name);
2160
- const base = `_${name}`;
2161
- if (this.bindingNames.size === 0 || !this.bindingNames.has(base)) {
3027
+ const base = `_${helperNameAliases[name] || name}`;
3028
+ if (this.isHelperNameAvailable(base)) {
2162
3029
  this.helpers.set(name, base);
2163
3030
  return base;
2164
3031
  }
2165
- const alias = `${base}${getNextId(this.nextIdMap.get(base), 1)}`;
2166
- this.helpers.set(name, alias);
2167
- return alias;
3032
+ const map = this.nextIdMap.get(base);
3033
+ let next = 1;
3034
+ while (true) {
3035
+ const alias = `${base}${getNextId(map, next)}`;
3036
+ if (this.isHelperNameAvailable(alias)) {
3037
+ this.helpers.set(name, alias);
3038
+ return alias;
3039
+ }
3040
+ next++;
3041
+ }
2168
3042
  };
2169
3043
  this.delegates = /* @__PURE__ */ new Set();
2170
3044
  this.identifiers = Object.create(null);
3045
+ this.expressionReplacements = [];
2171
3046
  this.seenInlineHandlerNames = Object.create(null);
2172
3047
  this.scopeLevel = 0;
2173
3048
  this.templateVars = /* @__PURE__ */ new Map();
2174
3049
  this.nextIdMap = /* @__PURE__ */ new Map();
2175
3050
  this.lastIdMap = /* @__PURE__ */ new Map();
2176
3051
  this.lastTIndex = -1;
2177
- this.options = (0, _vue_shared.extend)({
3052
+ const defaultOptions = {
2178
3053
  mode: "module",
2179
3054
  prefixIdentifiers: true,
2180
3055
  sourceMap: false,
@@ -2189,10 +3064,12 @@ var CodegenContext = class {
2189
3064
  inline: false,
2190
3065
  bindingMetadata: {},
2191
3066
  expressionPlugins: []
2192
- }, options);
3067
+ };
3068
+ this.options = (0, _vue_shared.extend)(defaultOptions, options);
2193
3069
  this.block = ir.block;
2194
3070
  this.bindingNames = new Set(this.options.bindingMetadata ? Object.keys(this.options.bindingMetadata) : []);
2195
3071
  this.initNextIdMap();
3072
+ this.staticTemplateRefHelperCandidate = getStaticTemplateRefHelperCandidate(ir.block);
2196
3073
  }
2197
3074
  };
2198
3075
  function generate(ir, options = {}) {
@@ -2205,13 +3082,15 @@ function generate(ir, options = {}) {
2205
3082
  const signature = (options.isTS ? args.map((arg) => `${arg}: any`) : args).join(", ");
2206
3083
  if (!inline) push(NEWLINE, `export function ${functionName}(${signature}) {`);
2207
3084
  push(INDENT_START);
2208
- if (ir.hasTemplateRef) push(NEWLINE, `const ${setTemplateRefIdent} = ${context.helper("createTemplateRefSetter")}()`);
2209
- if (ir.hasDeferredVShow) push(NEWLINE, `const deferredApplyVShows = []`);
2210
- push(...genBlockContent(ir.block, context, true));
3085
+ const templateRefSetterHelper = ir.hasTemplateRef ? context.helper("createTemplateRefSetter") : void 0;
3086
+ const body = genBlockContent(ir.block, context, true);
3087
+ if (context.needsTemplateRefSetter) push(NEWLINE, `const ${setTemplateRefIdent} = ${templateRefSetterHelper}()`);
3088
+ else if (templateRefSetterHelper) context.helpers.delete("createTemplateRefSetter");
3089
+ push(...body);
2211
3090
  push(INDENT_END, NEWLINE);
2212
3091
  if (!inline) push("}");
2213
3092
  const delegates = genDelegates(context);
2214
- const templates = genTemplates(ir.template, ir.rootTemplateIndexes, context);
3093
+ const templates = genTemplates(ir.template.entries, context);
2215
3094
  const preamble = genHelperImports(context) + genAssetImports(context) + templates + delegates;
2216
3095
  const newlineCount = [...preamble].filter((c) => c === "\n").length;
2217
3096
  if (newlineCount && !inline) frag.unshift(...new Array(newlineCount).fill(LF));
@@ -2242,78 +3121,70 @@ function genAssetImports({ ir }) {
2242
3121
  }
2243
3122
  return imports;
2244
3123
  }
3124
+ function getStaticTemplateRefHelperCandidate(block) {
3125
+ if (block.operation.length !== 1) return;
3126
+ const operation = block.operation[0];
3127
+ if (operation.type === 9 && !operation.effect && !operation.refFor && operation.value.isStatic) return operation;
3128
+ }
2245
3129
  //#endregion
2246
- //#region packages/compiler-vapor/src/transforms/transformChildren.ts
2247
- const transformChildren = (node, context) => {
2248
- const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
2249
- if (!isFragment && node.type !== 1) return;
2250
- for (const [i, child] of node.children.entries()) {
2251
- const childContext = context.create(child, i);
2252
- transformNode(childContext);
2253
- const childDynamic = childContext.dynamic;
2254
- if (isFragment) {
2255
- childContext.reference();
2256
- childContext.registerTemplate();
2257
- if (!(childDynamic.flags & 2) || childDynamic.flags & 4) context.block.returns.push(childContext.dynamic.id);
2258
- } else context.childrenTemplate.push(childContext.template);
2259
- if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) context.dynamic.hasDynamicChild = true;
2260
- context.dynamic.children[i] = childDynamic;
2261
- }
2262
- if (!isFragment) processDynamicChildren(context);
2263
- };
2264
- function processDynamicChildren(context) {
2265
- let prevDynamics = [];
2266
- let staticCount = 0;
2267
- let dynamicCount = 0;
2268
- let lastInsertionChild;
2269
- const children = context.dynamic.children;
2270
- let logicalIndex = 0;
2271
- for (const [index, child] of children.entries()) {
2272
- if (child.flags & 4) {
2273
- child.logicalIndex = logicalIndex;
2274
- prevDynamics.push(lastInsertionChild = child);
2275
- logicalIndex++;
2276
- }
2277
- if (!(child.flags & 2)) {
2278
- child.logicalIndex = logicalIndex;
2279
- if (prevDynamics.length) {
2280
- if (staticCount) {
2281
- context.childrenTemplate[index - prevDynamics.length] = `<!>`;
2282
- prevDynamics[0].flags -= 2;
2283
- const anchor = prevDynamics[0].anchor = context.increaseId();
2284
- registerInsertion(prevDynamics, context, anchor);
2285
- } else registerInsertion(prevDynamics, context, -1);
2286
- dynamicCount += prevDynamics.length;
2287
- prevDynamics = [];
2288
- }
2289
- staticCount++;
2290
- logicalIndex++;
2291
- }
3130
+ //#region packages/compiler-vapor/src/transforms/vBind.ts
3131
+ function normalizeBindShorthand(arg, context) {
3132
+ if (arg.type !== 4 || !arg.isStatic) {
3133
+ context.options.onError((0, _vue_compiler_dom.createCompilerError)(53, arg.loc));
3134
+ return (0, _vue_compiler_dom.createSimpleExpression)("", true, arg.loc);
2292
3135
  }
2293
- if (prevDynamics.length) registerInsertion(prevDynamics, context, dynamicCount + staticCount, true);
2294
- if (lastInsertionChild && lastInsertionChild.operation) lastInsertionChild.operation.last = true;
3136
+ const exp = (0, _vue_compiler_dom.createSimpleExpression)((0, _vue_shared.camelize)(arg.content), false, arg.loc);
3137
+ exp.ast = null;
3138
+ return exp;
2295
3139
  }
2296
- function registerInsertion(dynamics, context, anchor, append) {
2297
- for (const child of dynamics) {
2298
- const logicalIndex = child.logicalIndex;
2299
- if (child.template != null) context.registerOperation({
2300
- type: 9,
2301
- elements: dynamics.map((child) => child.id),
2302
- parent: context.reference(),
2303
- anchor: append ? void 0 : anchor
2304
- });
2305
- else if (child.operation && isBlockOperation(child.operation)) {
2306
- child.operation.parent = context.reference();
2307
- child.operation.anchor = anchor;
2308
- child.operation.logicalIndex = logicalIndex;
2309
- child.operation.append = append;
2310
- }
3140
+ const transformVBind = (dir, node, context) => {
3141
+ const { loc, modifiers } = dir;
3142
+ let { exp } = dir;
3143
+ let arg = dir.arg;
3144
+ const modifiersString = modifiers.map((s) => s.content);
3145
+ if (!exp) exp = normalizeBindShorthand(arg, context);
3146
+ if (!exp.content.trim()) {
3147
+ context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, loc));
3148
+ exp = (0, _vue_compiler_dom.createSimpleExpression)("", true, loc);
2311
3149
  }
2312
- }
3150
+ const isComponent = node.tagType === 1;
3151
+ exp = resolveExpression(exp, isComponent);
3152
+ arg = resolveExpression(arg);
3153
+ if (arg.isStatic && isReservedProp(arg.content)) return;
3154
+ let camel = false;
3155
+ if (modifiersString.includes("camel")) if (arg.isStatic) arg = (0, _vue_shared.extend)({}, arg, { content: (0, _vue_shared.camelize)(arg.content) });
3156
+ else camel = true;
3157
+ return {
3158
+ key: arg,
3159
+ value: exp,
3160
+ loc,
3161
+ runtimeCamelize: camel,
3162
+ modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : void 0
3163
+ };
3164
+ };
2313
3165
  //#endregion
2314
- //#region packages/compiler-vapor/src/transforms/vOnce.ts
2315
- const transformVOnce = (node, context) => {
2316
- if (node.type === 1 && (0, _vue_compiler_dom.findDir)(node, "once", true)) context.inVOnce = true;
3166
+ //#region packages/compiler-vapor/src/transforms/vHtml.ts
3167
+ function ignoreVHtmlChildren(node, context, clear) {
3168
+ if (!node.children.length) return;
3169
+ const dir = (0, _vue_compiler_dom.findDir)(node, "html");
3170
+ if (!dir) return;
3171
+ context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(55, dir.loc));
3172
+ if (clear === "node") node.children.length = 0;
3173
+ else context.childrenTemplate.length = 0;
3174
+ }
3175
+ const transformVHtml = (dir, node, context) => {
3176
+ let { exp, loc } = dir;
3177
+ if (!exp) {
3178
+ context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(54, loc));
3179
+ exp = EMPTY_EXPRESSION;
3180
+ }
3181
+ ignoreVHtmlChildren(node, context, "template");
3182
+ context.registerEffect([exp], {
3183
+ type: 8,
3184
+ element: context.reference(),
3185
+ value: exp,
3186
+ isComponent: node.tagType === 1
3187
+ });
2317
3188
  };
2318
3189
  //#endregion
2319
3190
  //#region packages/compiler-vapor/src/transforms/transformElement.ts
@@ -2321,6 +3192,7 @@ const isReservedProp = /* @__PURE__ */ (0, _vue_shared.makeMap)(",key,ref,ref_fo
2321
3192
  const transformElement = (node, context) => {
2322
3193
  let effectIndex = context.block.effect.length;
2323
3194
  const getEffectIndex = () => effectIndex++;
3195
+ if (node.type === 1 && node.children.length) ignoreVHtmlChildren(node, context, "node");
2324
3196
  let parentSlots;
2325
3197
  if (node.type === 1 && (node.tagType === 1 || context.options.isCustomElement(node.tag))) {
2326
3198
  parentSlots = context.slots;
@@ -2329,13 +3201,14 @@ const transformElement = (node, context) => {
2329
3201
  return function postTransformElement() {
2330
3202
  ({node} = context);
2331
3203
  if (!(node.type === 1 && (node.tagType === 0 || node.tagType === 1))) return;
2332
- const isCustomElement = !!context.options.isCustomElement(node.tag);
2333
- const isComponent = node.tagType === 1 || isCustomElement;
3204
+ const useCreateElement = shouldUseCreateElement(node, context);
3205
+ const isComponent = node.tagType === 1 || useCreateElement;
2334
3206
  const isDynamicComponent = isComponentTag(node.tag);
3207
+ const staticKey = resolveStaticKey(node, context, isComponent);
2335
3208
  const propsResult = buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex);
2336
- const singleRoot = isSingleRoot(context);
2337
- if (isComponent) transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent, isCustomElement);
2338
- else transformNativeElement(node, propsResult, singleRoot, context, getEffectIndex, context.root === context.effectiveParent || canOmitEndTag(node, context));
3209
+ const singleRoot = context.isSingleRoot;
3210
+ if (isComponent) transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement);
3211
+ else transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, context.root === context.effectiveParent || canOmitEndTag(node, context));
2339
3212
  if (parentSlots) context.slots = parentSlots;
2340
3213
  };
2341
3214
  };
@@ -2343,26 +3216,40 @@ function canOmitEndTag(node, context) {
2343
3216
  const { block, parent } = context;
2344
3217
  if (!parent) return false;
2345
3218
  if (block !== parent.block) return true;
3219
+ if (context.templateCloseTags && (context.templateCloseTags.has(node.tag) || (0, _vue_shared.isAlwaysCloseTag)(node.tag) || (0, _vue_shared.isFormattingTag)(node.tag)) || context.templateCloseBlocks && (0, _vue_shared.isBlockTag)(node.tag)) return false;
2346
3220
  if ((0, _vue_shared.isAlwaysCloseTag)(node.tag) && !context.isOnRightmostPath) return false;
2347
3221
  if ((0, _vue_shared.isFormattingTag)(node.tag) || parent.node.type === 1 && node.tag === parent.node.tag) return context.isOnRightmostPath;
2348
- if ((0, _vue_shared.isBlockTag)(node.tag) && context.hasInlineAncestorNeedingClose) return false;
2349
3222
  return context.isLastEffectiveChild;
2350
3223
  }
2351
- function isSingleRoot(context) {
2352
- if (context.inVFor) return false;
2353
- let { parent } = context;
2354
- if (parent && !((0, _vue_compiler_dom.hasSingleChild)(parent.node) || (0, _vue_compiler_dom.isSingleIfBlock)(parent.node))) return false;
2355
- while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2356
- parent = parent.parent;
2357
- if (!((0, _vue_compiler_dom.hasSingleChild)(parent.node) || (0, _vue_compiler_dom.isSingleIfBlock)(parent.node))) return false;
2358
- }
2359
- return context.root === parent;
3224
+ function getChildTemplateCloseState(context) {
3225
+ const { node } = context;
3226
+ if (node.type !== 1 || node.tagType !== 0 || shouldUseCreateElement(node, context)) return;
3227
+ const inSameTemplateAsParent = isInSameTemplateAsParent(context);
3228
+ const inheritedTags = inSameTemplateAsParent ? context.templateCloseTags : void 0;
3229
+ const inheritedBlocks = inSameTemplateAsParent && context.templateCloseBlocks;
3230
+ if (context.root === context.effectiveParent || canOmitEndTag(node, context) || (0, _vue_shared.isVoidTag)(node.tag)) return inheritedTags || inheritedBlocks ? {
3231
+ tags: inheritedTags,
3232
+ blocks: inheritedBlocks
3233
+ } : void 0;
3234
+ const tags = new Set(inheritedTags);
3235
+ tags.add(node.tag);
3236
+ return {
3237
+ tags,
3238
+ blocks: inheritedBlocks || (0, _vue_shared.isInlineTag)(node.tag)
3239
+ };
3240
+ }
3241
+ function isInSameTemplateAsParent(context) {
3242
+ const { parent, node, block } = context;
3243
+ if (!parent || block !== parent.block) return false;
3244
+ const parentNode = parent.node;
3245
+ if (parentNode.type !== 1 || parentNode.tagType !== 0) return false;
3246
+ return !shouldUseCreateElement(parentNode, parent) && (0, _vue_compiler_dom.isValidHTMLNesting)(parentNode.tag, node.tag);
2360
3247
  }
2361
- function transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent, isCustomElement) {
3248
+ function transformComponentElement(node, propsResult, staticKey, singleRoot, context, isDynamicComponent, useCreateElement) {
2362
3249
  const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
2363
3250
  let { tag } = node;
2364
3251
  let asset = true;
2365
- if (!dynamicComponent && !isCustomElement) {
3252
+ if (!dynamicComponent && !useCreateElement) {
2366
3253
  const fromSetup = resolveSetupReference(tag, context);
2367
3254
  if (fromSetup) {
2368
3255
  tag = fromSetup;
@@ -2387,9 +3274,11 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2387
3274
  }
2388
3275
  }
2389
3276
  context.dynamic.flags |= 6;
3277
+ const id = context.reference();
2390
3278
  context.dynamic.operation = {
2391
- type: 11,
2392
- id: context.reference(),
3279
+ type: 12,
3280
+ id,
3281
+ ...context.effectBoundary(),
2393
3282
  tag,
2394
3283
  props: propsResult[0] ? propsResult[1] : [propsResult[1]],
2395
3284
  asset,
@@ -2397,8 +3286,9 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2397
3286
  slots: [...context.slots],
2398
3287
  once: context.inVOnce,
2399
3288
  dynamic: dynamicComponent,
2400
- isCustomElement
3289
+ useCreateElement
2401
3290
  };
3291
+ if (staticKey) context.registerOperation(createSetBlockKey(id, staticKey));
2402
3292
  context.slots = [];
2403
3293
  }
2404
3294
  function resolveDynamicComponent(node) {
@@ -2416,54 +3306,194 @@ function resolveSetupReference(name, context) {
2416
3306
  }
2417
3307
  const dynamicKeys = ["indeterminate"];
2418
3308
  const NEEDS_QUOTES_RE = /[\s"'`=<>]/;
2419
- function transformNativeElement(node, propsResult, singleRoot, context, getEffectIndex, omitEndTag) {
3309
+ const UNSAFE_ATTR_NAME_RE = /[\u0000-\u0020"'<=/>]/;
3310
+ function transformNativeElement(node, propsResult, staticKey, singleRoot, context, getEffectIndex, omitEndTag) {
2420
3311
  const { tag } = node;
2421
3312
  const { scopeId } = context.options;
2422
3313
  let template = "";
2423
3314
  template += `<${tag}`;
2424
3315
  if (scopeId) template += ` ${scopeId}`;
2425
- const dynamicProps = [];
2426
3316
  if (propsResult[0]) {
2427
3317
  const [, dynamicArgs, expressions] = propsResult;
2428
3318
  context.registerEffect(expressions, {
2429
- type: 3,
3319
+ type: 4,
2430
3320
  element: context.reference(),
2431
3321
  props: dynamicArgs,
2432
3322
  tag
2433
3323
  }, getEffectIndex);
2434
3324
  } else {
2435
3325
  let prevWasQuoted = false;
3326
+ const appendTemplateProp = (key, value = "", generated = false) => {
3327
+ if (!prevWasQuoted) template += ` `;
3328
+ template += key;
3329
+ if (value) {
3330
+ const escapedValue = generated ? escapeGeneratedAttrValue(value) : value.replace(/"/g, "&quot;");
3331
+ template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${escapedValue}"` : `=${escapedValue}`;
3332
+ } else prevWasQuoted = false;
3333
+ };
2436
3334
  for (const prop of propsResult[1]) {
2437
3335
  const { key, values } = prop;
2438
- if (context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
3336
+ const canStringifyAttrName = key.isStatic && !UNSAFE_ATTR_NAME_RE.test(key.content);
3337
+ let foldedValue;
3338
+ if (canStringifyAttrName && context.imports.some((imported) => values[0].content.includes(imported.exp.content))) {
2439
3339
  if (!prevWasQuoted) template += ` `;
2440
3340
  template += `${key.content}="${IMPORT_EXP_START}${values[0].content}${IMPORT_EXP_END}"`;
2441
3341
  prevWasQuoted = true;
2442
- } else if (key.isStatic && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
2443
- if (!prevWasQuoted) template += ` `;
3342
+ } else if (canStringifyAttrName && values.length === 1 && (values[0].isStatic || values[0].content === "''") && !dynamicKeys.includes(key.content)) {
2444
3343
  const value = values[0].content === "''" ? "" : values[0].content;
2445
- template += key.content;
2446
- if (value) template += (prevWasQuoted = NEEDS_QUOTES_RE.test(value)) ? `="${value.replace(/"/g, "&quot;")}"` : `=${value}`;
2447
- else prevWasQuoted = false;
2448
- } else {
2449
- dynamicProps.push(key.content);
2450
- context.registerEffect(values, {
2451
- type: 2,
2452
- element: context.reference(),
2453
- prop,
2454
- tag
2455
- }, getEffectIndex);
2456
- }
3344
+ appendTemplateProp(key.content, value);
3345
+ } else if (canStringifyAttrName && !prop.modifier && (0, _vue_shared.isBooleanAttr)(key.content) && (foldedValue = foldBooleanAttrValue(values)) != null) {
3346
+ if (foldedValue) appendTemplateProp(key.content);
3347
+ } else if (canStringifyAttrName && !prop.modifier && hasBoundValue(values) && (foldedValue = key.content === "class" ? foldClassValues(values) : key.content === "style" ? foldStyleValues(values) : void 0) != null) {
3348
+ if (foldedValue) appendTemplateProp(key.content, foldedValue, true);
3349
+ } else context.registerEffect(values, {
3350
+ type: 3,
3351
+ element: context.reference(),
3352
+ prop,
3353
+ tag
3354
+ }, getEffectIndex);
2457
3355
  }
2458
3356
  }
2459
3357
  template += `>` + context.childrenTemplate.join("");
2460
3358
  if (!(0, _vue_shared.isVoidTag)(tag) && !omitEndTag) template += `</${tag}>`;
2461
- if (singleRoot) context.ir.rootTemplateIndexes.add(context.ir.template.size);
3359
+ context.templateRoot = singleRoot;
2462
3360
  if (context.parent && context.parent.node.type === 1 && !(0, _vue_compiler_dom.isValidHTMLNesting)(context.parent.node.tag, tag)) {
2463
3361
  context.reference();
2464
3362
  context.dynamic.template = context.pushTemplate(template);
2465
3363
  context.dynamic.flags |= 6;
2466
3364
  } else context.template += template;
3365
+ if (staticKey) context.registerOperation(createSetBlockKey(context.reference(), staticKey));
3366
+ }
3367
+ function escapeGeneratedAttrValue(value) {
3368
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
3369
+ }
3370
+ function foldBooleanAttrValue(values) {
3371
+ if (values.length !== 1) return;
3372
+ const evaluated = evaluateConstantExpression(values[0]);
3373
+ if (!evaluated) return;
3374
+ const value = evaluated.value;
3375
+ if (value === true || value === false || value == null) return (0, _vue_shared.includeBooleanAttr)(value);
3376
+ }
3377
+ function foldStyleValues(values) {
3378
+ const evaluatedValues = [];
3379
+ for (const value of values) {
3380
+ const evaluated = evaluateConstantExpression(value);
3381
+ if (!evaluated || !isStaticStyleValue(evaluated.value)) return;
3382
+ evaluatedValues.push(evaluated.value);
3383
+ }
3384
+ return (0, _vue_shared.stringifyStyle)((0, _vue_shared.normalizeStyle)(evaluatedValues.length === 1 ? evaluatedValues[0] : evaluatedValues));
3385
+ }
3386
+ function isStaticStyleValue(value) {
3387
+ if (typeof value === "string") return true;
3388
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
3389
+ for (const key in value) {
3390
+ const propValue = value[key];
3391
+ if (!isSafeStylePropertyName(key) || !isSafeStylePropertyValue(propValue)) return false;
3392
+ }
3393
+ return true;
3394
+ }
3395
+ function isSafeStylePropertyName(key) {
3396
+ return !!key && !/[;:]/.test(key);
3397
+ }
3398
+ function isSafeStylePropertyValue(value) {
3399
+ return typeof value === "number" || typeof value === "string" && !value.includes(";");
3400
+ }
3401
+ function hasBoundValue(values) {
3402
+ return values.some((value) => !value.isStatic && value.content !== "''");
3403
+ }
3404
+ function foldClassValues(values) {
3405
+ let templateValue = "";
3406
+ let changed = false;
3407
+ for (const value of values) {
3408
+ const evaluated = evaluateConstantExpression(value);
3409
+ if (evaluated) {
3410
+ const normalized = (0, _vue_shared.normalizeClass)(evaluated.value);
3411
+ if (normalized) templateValue = appendClass(templateValue, normalized);
3412
+ else changed = true;
3413
+ continue;
3414
+ }
3415
+ return;
3416
+ }
3417
+ return changed || templateValue ? templateValue : void 0;
3418
+ }
3419
+ function appendClass(base, value) {
3420
+ return base ? value ? `${base} ${value}` : base : value;
3421
+ }
3422
+ function getObjectPropertyName(prop) {
3423
+ const key = prop.key;
3424
+ if (key.type === "Identifier") return key.name;
3425
+ else if (key.type === "StringLiteral") return key.value;
3426
+ else if (key.type === "NumericLiteral") return String(key.value);
3427
+ }
3428
+ function evaluateConstantExpression(node) {
3429
+ if (node.isStatic) return { value: node.content };
3430
+ const ast = node.ast;
3431
+ if (ast === null) {
3432
+ if (node.content === "true") return { value: true };
3433
+ else if (node.content === "false") return { value: false };
3434
+ else if (node.content === "null") return { value: null };
3435
+ else if (node.content === "undefined") return { value: void 0 };
3436
+ }
3437
+ if (!ast) return;
3438
+ return evaluateConstantAst(ast);
3439
+ }
3440
+ function evaluateConstantAst(node) {
3441
+ switch (node.type) {
3442
+ case "StringLiteral": return { value: node.value };
3443
+ case "NumericLiteral": return { value: node.value };
3444
+ case "BooleanLiteral": return { value: node.value };
3445
+ case "NullLiteral": return { value: null };
3446
+ case "Identifier": return node.name === "undefined" ? { value: void 0 } : void 0;
3447
+ case "UnaryExpression":
3448
+ if (node.operator === "void") return { value: void 0 };
3449
+ else if (node.operator === "-") {
3450
+ const value = evaluateConstantAst(node.argument);
3451
+ return value && typeof value.value === "number" ? { value: -value.value } : void 0;
3452
+ }
3453
+ return;
3454
+ case "TemplateLiteral": return evaluateTemplateLiteral(node);
3455
+ case "ObjectExpression": return evaluateObjectExpression(node);
3456
+ }
3457
+ }
3458
+ function evaluateTemplateLiteral(node) {
3459
+ if (node.type !== "TemplateLiteral") return;
3460
+ let value = "";
3461
+ for (const [index, quasi] of node.quasis.entries()) {
3462
+ value += quasi.value.cooked || "";
3463
+ const expression = node.expressions[index];
3464
+ if (expression) {
3465
+ const evaluated = evaluateConstantAst(expression);
3466
+ if (!evaluated) return;
3467
+ value += evaluated.value;
3468
+ }
3469
+ }
3470
+ return { value };
3471
+ }
3472
+ function evaluateObjectExpression(node) {
3473
+ const value = {};
3474
+ for (const prop of node.properties) {
3475
+ if (prop.type !== "ObjectProperty" || prop.computed) return;
3476
+ const key = getObjectPropertyName(prop);
3477
+ if (key == null) return;
3478
+ const evaluated = evaluateConstantAst(prop.value);
3479
+ if (!evaluated) return;
3480
+ value[key] = evaluated.value;
3481
+ }
3482
+ return { value };
3483
+ }
3484
+ function resolveStaticKey(node, context, isComponent) {
3485
+ const keyProp = findProp$1(node, "key", false, true);
3486
+ if (!keyProp) return;
3487
+ if (keyProp.type === 6) return keyProp.value ? (0, _vue_compiler_dom.createSimpleExpression)(keyProp.value.content, true, keyProp.value.loc) : EMPTY_EXPRESSION;
3488
+ const value = keyProp.exp || normalizeBindShorthand(keyProp.arg, context);
3489
+ if (isStaticExpression(value, context.options.bindingMetadata)) return resolveExpression(value, isComponent);
3490
+ }
3491
+ function createSetBlockKey(element, value) {
3492
+ return {
3493
+ type: 2,
3494
+ element,
3495
+ value
3496
+ };
2467
3497
  }
2468
3498
  function buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex) {
2469
3499
  const props = node.props;
@@ -2477,29 +3507,44 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
2477
3507
  results = [];
2478
3508
  }
2479
3509
  }
3510
+ function pushStaticObjectLiteralProps(props) {
3511
+ if (dynamicArgs.length) {
3512
+ pushMergeArg();
3513
+ dynamicArgs.push(props);
3514
+ } else results.push(...props.map(toDirectiveResult));
3515
+ }
2480
3516
  for (const prop of props) {
2481
3517
  if (prop.type === 7 && !prop.arg) {
2482
3518
  if (prop.name === "bind") {
2483
3519
  if (prop.exp) {
2484
- dynamicExpr.push(prop.exp);
2485
- pushMergeArg();
2486
- dynamicArgs.push({
2487
- kind: 0,
2488
- value: prop.exp
2489
- });
3520
+ const objectLiteralProps = isComponent ? resolveComponentObjectLiteralBindProps(prop.exp, context, props, prop) : resolveNativeObjectLiteralBindProps(prop.exp, context, props, prop);
3521
+ if (objectLiteralProps) if (isComponent) pushStaticObjectLiteralProps(objectLiteralProps);
3522
+ else results.push(...objectLiteralProps.map(toDirectiveResult));
3523
+ else {
3524
+ dynamicExpr.push(prop.exp);
3525
+ pushMergeArg();
3526
+ dynamicArgs.push({
3527
+ kind: 0,
3528
+ value: prop.exp
3529
+ });
3530
+ }
2490
3531
  } else context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, prop.loc));
2491
3532
  continue;
2492
3533
  } else if (prop.name === "on") {
2493
3534
  if (prop.exp) if (isComponent) {
2494
- dynamicExpr.push(prop.exp);
2495
- pushMergeArg();
2496
- dynamicArgs.push({
2497
- kind: 0,
2498
- value: prop.exp,
2499
- handler: true
2500
- });
3535
+ const objectLiteralProps = resolveComponentObjectLiteralOnProps(prop.exp, context, props, prop);
3536
+ if (objectLiteralProps) pushStaticObjectLiteralProps(objectLiteralProps);
3537
+ else {
3538
+ dynamicExpr.push(prop.exp);
3539
+ pushMergeArg();
3540
+ dynamicArgs.push({
3541
+ kind: 0,
3542
+ value: prop.exp,
3543
+ handler: true
3544
+ });
3545
+ }
2501
3546
  } else context.registerEffect([prop.exp], {
2502
- type: 6,
3547
+ type: 7,
2503
3548
  element: context.reference(),
2504
3549
  event: prop.exp
2505
3550
  }, getEffectIndex);
@@ -2527,6 +3572,151 @@ function buildProps(node, context, isComponent, isDynamicComponent, getEffectInd
2527
3572
  }
2528
3573
  return [false, dedupeProperties(results)];
2529
3574
  }
3575
+ function resolveObjectLiteralProps(exp, context, keyTransform, isValidKey) {
3576
+ const ast = exp.ast;
3577
+ if (!ast || ast.type !== "ObjectExpression") return;
3578
+ const props = [];
3579
+ const knownKeys = /* @__PURE__ */ new Set();
3580
+ for (const property of ast.properties) {
3581
+ if (property.type !== "ObjectProperty" || property.computed) return;
3582
+ let key = getObjectPropertyName(property);
3583
+ if (key == null || key === "__proto__") return;
3584
+ if (isValidKey && !isValidKey(key)) return;
3585
+ if (keyTransform) key = keyTransform(key);
3586
+ if (knownKeys.has(key)) return;
3587
+ knownKeys.add(key);
3588
+ props.push({
3589
+ key: (0, _vue_compiler_dom.createSimpleExpression)(key, true),
3590
+ values: [resolveExpression(createObjectBindSubExpression(exp, property.value, context), true)]
3591
+ });
3592
+ }
3593
+ return props;
3594
+ }
3595
+ function resolveComponentObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
3596
+ const props = resolveObjectLiteralProps(exp, context, void 0, isSafeObjectLiteralBindKey);
3597
+ if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3598
+ return props;
3599
+ }
3600
+ function resolveNativeObjectLiteralBindProps(exp, context, nodeProps, currentProp) {
3601
+ const props = resolveObjectLiteralProps(exp, context, void 0, isSafeNativeObjectLiteralBindKey);
3602
+ if (!props || hasNativeObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3603
+ return props;
3604
+ }
3605
+ function resolveComponentObjectLiteralOnProps(exp, context, nodeProps, currentProp) {
3606
+ const props = resolveObjectLiteralProps(exp, context, _vue_shared.toHandlerKey);
3607
+ if (!props || hasComponentObjectLiteralBindConflict(nodeProps, currentProp, props)) return;
3608
+ return props;
3609
+ }
3610
+ function isSafeNativeObjectLiteralBindKey(key) {
3611
+ return key !== "" && !UNSAFE_ATTR_NAME_RE.test(key) && isSafeObjectLiteralBindKey(key) && !(0, _vue_shared.isOn)(key) && key.charCodeAt(0) !== 46 && key.charCodeAt(0) !== 94;
3612
+ }
3613
+ function isSafeObjectLiteralBindKey(key) {
3614
+ return !isReservedProp(key);
3615
+ }
3616
+ function hasComponentObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
3617
+ const keys = createComponentConflictKeySet(objectLiteralProps.map((prop) => prop.key.content));
3618
+ for (const prop of props) {
3619
+ if (prop === currentProp) continue;
3620
+ let key;
3621
+ if (prop.type === 6) key = prop.name;
3622
+ else if (prop.name === "bind") {
3623
+ if (!prop.arg) {
3624
+ const bindKeys = getObjectLiteralKeys(prop.exp);
3625
+ if (bindKeys && hasComponentKeyOverlap(keys, bindKeys)) return true;
3626
+ continue;
3627
+ }
3628
+ key = getStaticBindKey(prop);
3629
+ } else if (prop.name === "on") key = getStaticHandlerKey(prop);
3630
+ else if (prop.name === "model") {
3631
+ if (hasComponentModelKey(keys, prop)) return true;
3632
+ }
3633
+ if (key && hasComponentKey(keys, key)) return true;
3634
+ }
3635
+ return false;
3636
+ }
3637
+ function hasComponentModelKey(keys, prop) {
3638
+ const { arg } = prop;
3639
+ if (arg && (arg.type !== 4 || !arg.isStatic)) return true;
3640
+ const key = arg ? arg.content : "modelValue";
3641
+ return hasComponentKey(keys, key) || hasComponentKey(keys, `onUpdate:${(0, _vue_shared.camelize)(key)}`) || prop.modifiers.length > 0 && hasComponentKey(keys, (0, _vue_shared.getModifierPropName)(key));
3642
+ }
3643
+ function hasNativeObjectLiteralBindConflict(props, currentProp, objectLiteralProps) {
3644
+ const keys = new Set(objectLiteralProps.map((prop) => prop.key.content));
3645
+ for (const prop of props) {
3646
+ if (prop === currentProp) continue;
3647
+ let key;
3648
+ if (prop.type === 6) key = prop.name;
3649
+ else if (prop.name === "bind") {
3650
+ if (!prop.arg) return true;
3651
+ key = getStaticBindKey(prop);
3652
+ if (!key) return true;
3653
+ }
3654
+ if (key && keys.has(key)) return true;
3655
+ }
3656
+ return false;
3657
+ }
3658
+ function getStaticBindKey(prop) {
3659
+ const { arg } = prop;
3660
+ if (!arg || arg.type !== 4 || !arg.isStatic) return;
3661
+ let key = arg.content;
3662
+ if (isReservedProp(key)) return;
3663
+ if (prop.modifiers.some((modifier) => modifier.content === "camel")) key = (0, _vue_shared.camelize)(key);
3664
+ return key;
3665
+ }
3666
+ function getStaticHandlerKey(prop) {
3667
+ const { arg } = prop;
3668
+ if (!arg || arg.type !== 4 || !arg.isStatic) return;
3669
+ let key = arg.content;
3670
+ if (key.startsWith("vue:")) key = `vnode-${key.slice(4)}`;
3671
+ const { nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(`on${key}`, prop.modifiers, null, prop.loc);
3672
+ if (key.toLowerCase() === "click") {
3673
+ if (nonKeyModifiers.includes("middle")) key = "mouseup";
3674
+ if (nonKeyModifiers.includes("right")) key = "contextmenu";
3675
+ }
3676
+ key = (0, _vue_shared.toHandlerKey)((0, _vue_shared.camelize)(key));
3677
+ const optionPostfix = eventOptionModifiers.map(_vue_shared.capitalize).join("");
3678
+ if (optionPostfix) key += optionPostfix;
3679
+ return key;
3680
+ }
3681
+ function getObjectLiteralKeys(exp) {
3682
+ const ast = exp && exp.ast;
3683
+ if (!ast || ast.type !== "ObjectExpression") return;
3684
+ const keys = /* @__PURE__ */ new Set();
3685
+ for (const property of ast.properties) {
3686
+ if (property.type !== "ObjectProperty" || property.computed) return;
3687
+ const key = getObjectPropertyName(property);
3688
+ if (key == null) return;
3689
+ keys.add(key);
3690
+ }
3691
+ return keys;
3692
+ }
3693
+ function createComponentConflictKeySet(keys) {
3694
+ const normalized = /* @__PURE__ */ new Set();
3695
+ for (const key of keys) {
3696
+ normalized.add(key);
3697
+ normalized.add((0, _vue_shared.camelize)(key));
3698
+ }
3699
+ return normalized;
3700
+ }
3701
+ function hasComponentKey(keys, key) {
3702
+ return keys.has(key) || keys.has((0, _vue_shared.camelize)(key));
3703
+ }
3704
+ function hasComponentKeyOverlap(left, right) {
3705
+ for (const key of right) if (hasComponentKey(left, key)) return true;
3706
+ return false;
3707
+ }
3708
+ function createObjectBindSubExpression(source, node, context) {
3709
+ const start = node.start == null ? 0 : node.start - 1;
3710
+ const end = node.end == null ? source.content.length : node.end - 1;
3711
+ const content = source.content.slice(start, end);
3712
+ const expression = (0, _vue_compiler_dom.createSimpleExpression)(content, false, {
3713
+ start: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, start),
3714
+ end: (0, _vue_compiler_dom.advancePositionWithClone)(source.loc.start, source.content, end),
3715
+ source: content
3716
+ });
3717
+ expression.ast = (0, _vue_compiler_dom.isSimpleIdentifier)(content) ? null : (0, _babel_parser.parseExpression)(`(${content})`, getParserOptions(context.options.expressionPlugins));
3718
+ return expression;
3719
+ }
2530
3720
  function transformProp(prop, node, context) {
2531
3721
  let { name } = prop;
2532
3722
  if (prop.type === 6) {
@@ -2543,7 +3733,7 @@ function transformProp(prop, node, context) {
2543
3733
  if (fromSetup) name = fromSetup;
2544
3734
  else context.directive.add(name);
2545
3735
  context.registerOperation({
2546
- type: 13,
3736
+ type: 14,
2547
3737
  element: context.reference(),
2548
3738
  dir: prop,
2549
3739
  name,
@@ -2577,6 +3767,12 @@ function resolveDirectiveResult(prop) {
2577
3767
  values: [prop.value]
2578
3768
  });
2579
3769
  }
3770
+ function toDirectiveResult(prop) {
3771
+ return (0, _vue_shared.extend)({}, prop, {
3772
+ values: void 0,
3773
+ value: prop.values[0]
3774
+ });
3775
+ }
2580
3776
  function mergePropValues(existing, incoming) {
2581
3777
  const newValues = incoming.values;
2582
3778
  existing.values.push(...newValues);
@@ -2584,24 +3780,88 @@ function mergePropValues(existing, incoming) {
2584
3780
  function isComponentTag(tag) {
2585
3781
  return tag === "component" || tag === "Component";
2586
3782
  }
3783
+ function shouldUseCreateElement(node, context) {
3784
+ return context.options.isCustomElement(node.tag) || node.tagType === 0 && node.tag === "template";
3785
+ }
2587
3786
  //#endregion
2588
- //#region packages/compiler-vapor/src/transforms/vHtml.ts
2589
- const transformVHtml = (dir, node, context) => {
2590
- let { exp, loc } = dir;
2591
- if (!exp) {
2592
- context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(54, loc));
2593
- exp = EMPTY_EXPRESSION;
3787
+ //#region packages/compiler-vapor/src/transforms/transformChildren.ts
3788
+ const transformChildren = (node, context) => {
3789
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3790
+ if (!isFragment && node.type !== 1) return;
3791
+ const useCreateElement = node.type === 1 && shouldUseCreateElement(node, context);
3792
+ const childTemplateCloseState = !isFragment && !useCreateElement ? getChildTemplateCloseState(context) : void 0;
3793
+ for (const [i, child] of node.children.entries()) {
3794
+ const childContext = context.create(child, i);
3795
+ const isInSameTemplate = childTemplateCloseState && child.type === 1 && child.tagType === 0 && isInSameTemplateAsParent(childContext);
3796
+ childContext.templateCloseTags = isInSameTemplate ? childTemplateCloseState.tags : void 0;
3797
+ childContext.templateCloseBlocks = isInSameTemplate ? childTemplateCloseState.blocks : false;
3798
+ transformNode(childContext);
3799
+ const childDynamic = childContext.dynamic;
3800
+ if (isFragment) {
3801
+ childContext.reference();
3802
+ childContext.registerTemplate();
3803
+ if (!(childDynamic.flags & 2) || childDynamic.flags & 4) context.block.returns.push(childContext.dynamic.id);
3804
+ } else if (useCreateElement) {
3805
+ if (childContext.template !== "" || childDynamic.template != null || childDynamic.id !== void 0 || childDynamic.operation !== void 0 || childDynamic.hasDynamicChild === true) {
3806
+ childContext.reference();
3807
+ childContext.registerTemplate();
3808
+ childDynamic.flags |= 6;
3809
+ }
3810
+ } else context.childrenTemplate.push(childContext.template);
3811
+ if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) context.dynamic.hasDynamicChild = true;
3812
+ context.dynamic.children[i] = childDynamic;
2594
3813
  }
2595
- if (node.children.length) {
2596
- context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(55, loc));
2597
- context.childrenTemplate.length = 0;
3814
+ if (!isFragment) processDynamicChildren(context);
3815
+ };
3816
+ function processDynamicChildren(context) {
3817
+ let prevDynamics = [];
3818
+ let staticCount = 0;
3819
+ const children = context.dynamic.children;
3820
+ let logicalIndex = 0;
3821
+ for (const [index, child] of children.entries()) {
3822
+ if (child.flags & 4) {
3823
+ child.logicalIndex = logicalIndex;
3824
+ prevDynamics.push(child);
3825
+ logicalIndex++;
3826
+ }
3827
+ if (!(child.flags & 2)) {
3828
+ child.logicalIndex = logicalIndex;
3829
+ if (prevDynamics.length) {
3830
+ if (staticCount) {
3831
+ context.childrenTemplate[index - prevDynamics.length] = `<!>`;
3832
+ prevDynamics[0].flags -= 2;
3833
+ const anchor = prevDynamics[0].anchor = context.increaseId();
3834
+ registerInsertion(prevDynamics, context, anchor);
3835
+ } else registerInsertion(prevDynamics, context, -1);
3836
+ prevDynamics = [];
3837
+ }
3838
+ staticCount++;
3839
+ logicalIndex++;
3840
+ }
2598
3841
  }
2599
- context.registerEffect([exp], {
2600
- type: 7,
2601
- element: context.reference(),
2602
- value: exp,
2603
- isComponent: node.tagType === 1
2604
- });
3842
+ if (prevDynamics.length) registerInsertion(prevDynamics, context, prevDynamics[0].logicalIndex, true);
3843
+ }
3844
+ function registerInsertion(dynamics, context, anchor, append) {
3845
+ for (const child of dynamics) {
3846
+ const logicalIndex = child.logicalIndex;
3847
+ if (child.template != null) context.registerOperation({
3848
+ type: 10,
3849
+ elements: dynamics.map((child) => child.id),
3850
+ parent: context.reference(),
3851
+ anchor: append ? void 0 : anchor
3852
+ });
3853
+ else if (child.operation && isBlockOperation(child.operation)) {
3854
+ child.operation.parent = context.reference();
3855
+ child.operation.anchor = anchor;
3856
+ child.operation.logicalIndex = logicalIndex;
3857
+ child.operation.append = append;
3858
+ }
3859
+ }
3860
+ }
3861
+ //#endregion
3862
+ //#region packages/compiler-vapor/src/transforms/vOnce.ts
3863
+ const transformVOnce = (node, context) => {
3864
+ if (node.type === 1 && (0, _vue_compiler_dom.findDir)(node, "once", true)) context.inVOnce = true;
2605
3865
  };
2606
3866
  //#endregion
2607
3867
  //#region packages/shared/src/makeMap.ts
@@ -2624,6 +3884,147 @@ function makeMap$1(str) {
2624
3884
  */
2625
3885
  const isVoidTag = /* @__PURE__ */ makeMap$1("area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr");
2626
3886
  //#endregion
3887
+ //#region packages/compiler-vapor/src/transforms/transformText.ts
3888
+ const seen = /* @__PURE__ */ new WeakMap();
3889
+ function markNonTemplate(node, context) {
3890
+ let seenNodes = seen.get(context.root);
3891
+ if (!seenNodes) {
3892
+ seenNodes = /* @__PURE__ */ new WeakSet();
3893
+ seen.set(context.root, seenNodes);
3894
+ }
3895
+ seenNodes.add(node);
3896
+ }
3897
+ const transformText = (node, context) => {
3898
+ if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
3899
+ if (seen.get(context.root).has(node)) {
3900
+ context.dynamic.flags |= 2;
3901
+ return;
3902
+ }
3903
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3904
+ if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
3905
+ let hasInterp = false;
3906
+ let isAllTextLike = true;
3907
+ for (const c of node.children) if (c.type === 5) hasInterp = true;
3908
+ else if (c.type !== 2) isAllTextLike = false;
3909
+ if (!isFragment && isAllTextLike && hasInterp) {
3910
+ const elementContext = context;
3911
+ if (shouldUseCreateElement(node, elementContext)) processCreateElementTextContainer(node.children, elementContext);
3912
+ else processTextContainer(node.children, elementContext);
3913
+ } else if (hasInterp) for (let i = 0; i < node.children.length; i++) {
3914
+ const c = node.children[i];
3915
+ const prev = node.children[i - 1];
3916
+ if (c.type === 5 && prev && prev.type === 2) markNonTemplate(prev, context);
3917
+ }
3918
+ } else if (node.type === 5) processInterpolation(context);
3919
+ else if (node.type === 2) {
3920
+ var _context$parent;
3921
+ const parent = (_context$parent = context.parent) === null || _context$parent === void 0 ? void 0 : _context$parent.node;
3922
+ if (parent && parent.type === 1 && shouldUseCreateElement(parent, context.parent) && node.content[0] === "<") {
3923
+ materializeLiteralTextNode((0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc), context);
3924
+ return;
3925
+ }
3926
+ const isRootText = !parent || parent.type === 0 || parent.type === 1 && (parent.tagType === 3 || parent.tagType === 1);
3927
+ context.template += isRootText ? node.content : (0, _vue_shared.escapeHtml)(node.content);
3928
+ }
3929
+ };
3930
+ function processInterpolation(context) {
3931
+ const parentNode = context.parent.node;
3932
+ const values = processTextLikeChildren(collectAdjacentText(context), context);
3933
+ if (values.length === 0 && parentNode.type !== 0) return;
3934
+ const literalValues = values.map((v) => getLiteralExpressionValue(v));
3935
+ if (literalValues.every((v) => v != null) && parentNode.type !== 0) {
3936
+ const text = literalValues.join("");
3937
+ if (parentNode.type === 1 && shouldUseCreateElement(parentNode, context.parent) && text[0] === "<") {
3938
+ materializeLiteralTextNode((0, _vue_compiler_dom.createSimpleExpression)(text, true, context.node.loc), context);
3939
+ return;
3940
+ }
3941
+ const isElementChild = parentNode.type === 1 && parentNode.tagType === 0;
3942
+ context.template += isElementChild ? (0, _vue_shared.escapeHtml)(text) : text;
3943
+ return;
3944
+ }
3945
+ context.template += " ";
3946
+ const id = context.reference();
3947
+ if (values.length === 0) return;
3948
+ context.registerEffect(values, {
3949
+ type: 5,
3950
+ element: id,
3951
+ values
3952
+ });
3953
+ }
3954
+ function collectAdjacentText(context) {
3955
+ const children = context.parent.node.children;
3956
+ const nodes = [];
3957
+ const prev = children[context.index - 1];
3958
+ let index = prev && prev.type === 2 ? context.index - 1 : context.index;
3959
+ for (; index < children.length; index++) {
3960
+ const child = children[index];
3961
+ if (!isTextLike(child)) break;
3962
+ nodes.push(child);
3963
+ }
3964
+ return nodes;
3965
+ }
3966
+ function processTextContainer(children, context) {
3967
+ const values = processTextLikeChildren(children, context);
3968
+ const literals = values.map((value) => getLiteralExpressionValue(value));
3969
+ if (literals.every((l) => l != null)) context.childrenTemplate = literals.map((l) => (0, _vue_shared.escapeHtml)(String(l)));
3970
+ else {
3971
+ context.childrenTemplate = [" "];
3972
+ context.registerOperation({
3973
+ type: 18,
3974
+ parent: context.reference()
3975
+ });
3976
+ context.registerEffect(values, {
3977
+ type: 5,
3978
+ element: context.reference(),
3979
+ values,
3980
+ generated: true
3981
+ });
3982
+ }
3983
+ }
3984
+ function registerSyntheticTextChild(context, template, values) {
3985
+ const id = context.increaseId();
3986
+ context.dynamic.children[context.node.children.length] = {
3987
+ id,
3988
+ flags: 6,
3989
+ children: [],
3990
+ template: context.pushTemplate(template)
3991
+ };
3992
+ context.dynamic.hasDynamicChild = true;
3993
+ if (values && values.length) context.registerEffect(values, {
3994
+ type: 5,
3995
+ element: id,
3996
+ values
3997
+ });
3998
+ return id;
3999
+ }
4000
+ function processCreateElementTextContainer(children, context) {
4001
+ registerSyntheticTextChild(context, "", processTextLikeChildren(children, context));
4002
+ }
4003
+ function materializeLiteralTextNode(value, context) {
4004
+ const id = context.reference();
4005
+ context.dynamic.flags |= 6;
4006
+ context.dynamic.template = context.pushTemplate("");
4007
+ context.registerEffect([value], {
4008
+ type: 5,
4009
+ element: id,
4010
+ values: [value]
4011
+ });
4012
+ }
4013
+ function processTextLikeChildren(nodes, context) {
4014
+ const exps = [];
4015
+ for (const node of nodes) {
4016
+ let exp;
4017
+ markNonTemplate(node, context);
4018
+ if (node.type === 2) exp = (0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc);
4019
+ else exp = node.content;
4020
+ if (exp.content) exps.push(exp);
4021
+ }
4022
+ return exps;
4023
+ }
4024
+ function isTextLike(node) {
4025
+ return node.type === 5 || node.type === 2;
4026
+ }
4027
+ //#endregion
2627
4028
  //#region packages/compiler-vapor/src/transforms/vText.ts
2628
4029
  const transformVText = (dir, node, context) => {
2629
4030
  let { exp, loc } = dir;
@@ -2634,63 +4035,46 @@ const transformVText = (dir, node, context) => {
2634
4035
  if (node.children.length) {
2635
4036
  context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(57, loc));
2636
4037
  context.childrenTemplate.length = 0;
4038
+ for (const child of node.children) markNonTemplate(child, context);
2637
4039
  }
2638
4040
  if (isVoidTag(context.node.tag)) return;
2639
4041
  const literal = getLiteralExpressionValue(exp);
2640
- if (literal != null) context.childrenTemplate = [String(literal)];
2641
- else {
2642
- context.childrenTemplate = [" "];
2643
- const isComponent = node.tagType === 1;
2644
- if (!isComponent) context.registerOperation({
2645
- type: 17,
4042
+ const useCreateElement = shouldUseCreateElement(context.node, context);
4043
+ if (literal != null) if (useCreateElement) {
4044
+ const id = registerSyntheticTextChild(context, "", [exp]);
4045
+ context.registerOperation({
4046
+ type: 10,
4047
+ elements: [id],
2646
4048
  parent: context.reference()
2647
4049
  });
4050
+ } else context.childrenTemplate = [String(literal)];
4051
+ else {
4052
+ const isComponent = node.tagType === 1;
4053
+ let id;
4054
+ if (useCreateElement) {
4055
+ id = registerSyntheticTextChild(context, "");
4056
+ context.registerOperation({
4057
+ type: 10,
4058
+ elements: [id],
4059
+ parent: context.reference()
4060
+ });
4061
+ } else if (!isComponent) {
4062
+ context.childrenTemplate = [" "];
4063
+ context.registerOperation({
4064
+ type: 18,
4065
+ parent: context.reference()
4066
+ });
4067
+ }
2648
4068
  context.registerEffect([exp], {
2649
- type: 4,
2650
- element: context.reference(),
4069
+ type: 5,
4070
+ element: useCreateElement ? id : context.reference(),
2651
4071
  values: [exp],
2652
- generated: true,
4072
+ generated: !useCreateElement,
2653
4073
  isComponent
2654
4074
  });
2655
4075
  }
2656
4076
  };
2657
4077
  //#endregion
2658
- //#region packages/compiler-vapor/src/transforms/vBind.ts
2659
- function normalizeBindShorthand(arg, context) {
2660
- if (arg.type !== 4 || !arg.isStatic) {
2661
- context.options.onError((0, _vue_compiler_dom.createCompilerError)(53, arg.loc));
2662
- return (0, _vue_compiler_dom.createSimpleExpression)("", true, arg.loc);
2663
- }
2664
- const exp = (0, _vue_compiler_dom.createSimpleExpression)((0, _vue_shared.camelize)(arg.content), false, arg.loc);
2665
- exp.ast = null;
2666
- return exp;
2667
- }
2668
- const transformVBind = (dir, node, context) => {
2669
- const { loc, modifiers } = dir;
2670
- let { exp } = dir;
2671
- let arg = dir.arg;
2672
- const modifiersString = modifiers.map((s) => s.content);
2673
- if (!exp) exp = normalizeBindShorthand(arg, context);
2674
- if (!exp.content.trim()) {
2675
- context.options.onError((0, _vue_compiler_dom.createCompilerError)(34, loc));
2676
- exp = (0, _vue_compiler_dom.createSimpleExpression)("", true, loc);
2677
- }
2678
- const isComponent = node.tagType === 1;
2679
- exp = resolveExpression(exp, isComponent);
2680
- arg = resolveExpression(arg);
2681
- if (arg.isStatic && isReservedProp(arg.content)) return;
2682
- let camel = false;
2683
- if (modifiersString.includes("camel")) if (arg.isStatic) arg = (0, _vue_shared.extend)({}, arg, { content: (0, _vue_shared.camelize)(arg.content) });
2684
- else camel = true;
2685
- return {
2686
- key: arg,
2687
- value: exp,
2688
- loc,
2689
- runtimeCamelize: camel,
2690
- modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : void 0
2691
- };
2692
- };
2693
- //#endregion
2694
4078
  //#region packages/compiler-vapor/src/transforms/vOn.ts
2695
4079
  const delegatedEvents = /* @__PURE__ */ (0, _vue_shared.makeMap)("beforeinput,click,dblclick,contextmenu,focusin,focusout,input,keydown,keyup,mousedown,mousemove,mouseout,mouseover,mouseup,pointerdown,pointermove,pointerout,pointerover,pointerup,touchend,touchmove,touchstart");
2696
4080
  const transformVOn = (dir, node, context) => {
@@ -2699,18 +4083,16 @@ const transformVOn = (dir, node, context) => {
2699
4083
  const isSlotOutlet = node.tag === "slot";
2700
4084
  if (!exp && !modifiers.length) context.options.onError((0, _vue_compiler_dom.createCompilerError)(35, loc));
2701
4085
  arg = resolveExpression(arg);
4086
+ if (arg.isStatic && arg.content.startsWith("vue:")) arg = (0, _vue_shared.extend)({}, arg, { content: `vnode-${arg.content.slice(4)}` });
2702
4087
  const { keyModifiers, nonKeyModifiers, eventOptionModifiers } = (0, _vue_compiler_dom.resolveModifiers)(arg.isStatic ? `on${arg.content}` : arg, modifiers, null, loc);
2703
4088
  let keyOverride;
2704
4089
  const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
2705
- if (nonKeyModifiers.includes("middle")) {
2706
- if (keyOverride) {}
2707
- if (isStaticClick) arg = (0, _vue_shared.extend)({}, arg, { content: "mouseup" });
2708
- else if (!arg.isStatic) keyOverride = ["click", "mouseup"];
2709
- }
2710
4090
  if (nonKeyModifiers.includes("right")) {
2711
- if (isStaticClick) arg = (0, _vue_shared.extend)({}, arg, { content: "contextmenu" });
2712
- else if (!arg.isStatic) keyOverride = ["click", "contextmenu"];
4091
+ if (!isStaticClick && !arg.isStatic) keyOverride = ["click", "contextmenu"];
4092
+ } else if (nonKeyModifiers.includes("middle")) {
4093
+ if (!isStaticClick && !arg.isStatic) keyOverride = ["click", "mouseup"];
2713
4094
  }
4095
+ arg = normalizeStaticEventArg(arg, nonKeyModifiers);
2714
4096
  if (keyModifiers.length && (0, _vue_compiler_dom.isStaticExp)(arg) && !(0, _vue_compiler_dom.isKeyboardEvent)(`on${arg.content.toLowerCase()}`)) keyModifiers.length = 0;
2715
4097
  if (isComponent || isSlotOutlet) return {
2716
4098
  key: arg,
@@ -2722,9 +4104,9 @@ const transformVOn = (dir, node, context) => {
2722
4104
  options: eventOptionModifiers
2723
4105
  }
2724
4106
  };
2725
- const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
4107
+ const delegate = context.options.eventDelegation && arg.isStatic && !eventOptionModifiers.length && !hasStopHandlerForStaticEvent(node, arg.content) && delegatedEvents(arg.content);
2726
4108
  const operation = {
2727
- type: 5,
4109
+ type: 6,
2728
4110
  element: context.reference(),
2729
4111
  key: arg,
2730
4112
  value: exp,
@@ -2739,6 +4121,23 @@ const transformVOn = (dir, node, context) => {
2739
4121
  };
2740
4122
  context.registerEffect([arg], operation);
2741
4123
  };
4124
+ function normalizeStaticEventArg(arg, nonKeyModifiers) {
4125
+ if (!arg.isStatic) return arg;
4126
+ let normalized = arg;
4127
+ const isStaticClick = arg.content.toLowerCase() === "click";
4128
+ if (nonKeyModifiers.includes("right") && isStaticClick) normalized = (0, _vue_shared.extend)({}, normalized, { content: "contextmenu" });
4129
+ else if (nonKeyModifiers.includes("middle") && isStaticClick) normalized = (0, _vue_shared.extend)({}, normalized, { content: "mouseup" });
4130
+ return normalized;
4131
+ }
4132
+ function hasStopHandlerForStaticEvent(node, eventName) {
4133
+ return node.props.some((prop) => {
4134
+ if (prop.type !== 7 || prop.name !== "on" || !prop.arg || prop.arg.type !== 4) return false;
4135
+ const arg = resolveExpression(prop.arg);
4136
+ if (!arg.isStatic) return false;
4137
+ const { nonKeyModifiers } = (0, _vue_compiler_dom.resolveModifiers)(`on${arg.content}`, prop.modifiers, null, prop.loc);
4138
+ return nonKeyModifiers.includes("stop") && normalizeStaticEventArg(arg, nonKeyModifiers).content === eventName;
4139
+ });
4140
+ }
2742
4141
  //#endregion
2743
4142
  //#region packages/compiler-vapor/src/transforms/vShow.ts
2744
4143
  const transformVShow = (dir, node, context) => {
@@ -2751,19 +4150,12 @@ const transformVShow = (dir, node, context) => {
2751
4150
  context.options.onError((0, _vue_compiler_dom.createCompilerError)(36, loc));
2752
4151
  return;
2753
4152
  }
2754
- let shouldDeferred = false;
2755
- const parentNode = context.parent && context.parent.node;
2756
- if (parentNode && parentNode.type === 1) {
2757
- shouldDeferred = !!(isTransitionTag(parentNode.tag) && findProp$1(parentNode, "appear", false, true));
2758
- if (shouldDeferred) context.ir.hasDeferredVShow = true;
2759
- }
2760
4153
  context.registerOperation({
2761
- type: 13,
4154
+ type: 14,
2762
4155
  element: context.reference(),
2763
4156
  dir,
2764
4157
  name: "show",
2765
- builtin: true,
2766
- deferred: shouldDeferred
4158
+ builtin: true
2767
4159
  });
2768
4160
  };
2769
4161
  //#endregion
@@ -2780,7 +4172,7 @@ const transformTemplateRef = (node, context) => {
2780
4172
  const id = context.reference();
2781
4173
  const effect = !isConstantExpression(value);
2782
4174
  context.registerEffect([value], {
2783
- type: 8,
4175
+ type: 9,
2784
4176
  element: id,
2785
4177
  value,
2786
4178
  refFor: !!context.inVFor,
@@ -2789,96 +4181,6 @@ const transformTemplateRef = (node, context) => {
2789
4181
  };
2790
4182
  };
2791
4183
  //#endregion
2792
- //#region packages/compiler-vapor/src/transforms/transformText.ts
2793
- const seen = /* @__PURE__ */ new WeakMap();
2794
- function markNonTemplate(node, context) {
2795
- seen.get(context.root).add(node);
2796
- }
2797
- const transformText = (node, context) => {
2798
- if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
2799
- if (seen.get(context.root).has(node)) {
2800
- context.dynamic.flags |= 2;
2801
- return;
2802
- }
2803
- const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
2804
- if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
2805
- let hasInterp = false;
2806
- let isAllTextLike = true;
2807
- for (const c of node.children) if (c.type === 5) hasInterp = true;
2808
- else if (c.type !== 2) isAllTextLike = false;
2809
- if (!isFragment && isAllTextLike && hasInterp) processTextContainer(node.children, context);
2810
- else if (hasInterp) for (let i = 0; i < node.children.length; i++) {
2811
- const c = node.children[i];
2812
- const prev = node.children[i - 1];
2813
- if (c.type === 5 && prev && prev.type === 2) markNonTemplate(prev, context);
2814
- }
2815
- } else if (node.type === 5) processInterpolation(context);
2816
- else if (node.type === 2) {
2817
- var _context$parent;
2818
- const parent = (_context$parent = context.parent) === null || _context$parent === void 0 ? void 0 : _context$parent.node;
2819
- const isRootText = !parent || parent.type === 0 || parent.type === 1 && (parent.tagType === 3 || parent.tagType === 1);
2820
- context.template += isRootText ? node.content : (0, _vue_shared.escapeHtml)(node.content);
2821
- }
2822
- };
2823
- function processInterpolation(context) {
2824
- const parentNode = context.parent.node;
2825
- const children = parentNode.children;
2826
- const nexts = children.slice(context.index);
2827
- const idx = nexts.findIndex((n) => !isTextLike(n));
2828
- const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
2829
- const prev = children[context.index - 1];
2830
- if (prev && prev.type === 2) nodes.unshift(prev);
2831
- const values = processTextLikeChildren(nodes, context);
2832
- if (values.length === 0 && parentNode.type !== 0) return;
2833
- const literalValues = values.map((v) => getLiteralExpressionValue(v));
2834
- if (literalValues.every((v) => v != null) && parentNode.type !== 0) {
2835
- const text = literalValues.join("");
2836
- const isElementChild = parentNode.type === 1 && parentNode.tagType === 0;
2837
- context.template += isElementChild ? (0, _vue_shared.escapeHtml)(text) : text;
2838
- return;
2839
- }
2840
- context.template += " ";
2841
- const id = context.reference();
2842
- if (values.length === 0) return;
2843
- context.registerEffect(values, {
2844
- type: 4,
2845
- element: id,
2846
- values
2847
- });
2848
- }
2849
- function processTextContainer(children, context) {
2850
- const values = processTextLikeChildren(children, context);
2851
- const literals = values.map((value) => getLiteralExpressionValue(value));
2852
- if (literals.every((l) => l != null)) context.childrenTemplate = literals.map((l) => (0, _vue_shared.escapeHtml)(String(l)));
2853
- else {
2854
- context.childrenTemplate = [" "];
2855
- context.registerOperation({
2856
- type: 17,
2857
- parent: context.reference()
2858
- });
2859
- context.registerEffect(values, {
2860
- type: 4,
2861
- element: context.reference(),
2862
- values,
2863
- generated: true
2864
- });
2865
- }
2866
- }
2867
- function processTextLikeChildren(nodes, context) {
2868
- const exps = [];
2869
- for (const node of nodes) {
2870
- let exp;
2871
- markNonTemplate(node, context);
2872
- if (node.type === 2) exp = (0, _vue_compiler_dom.createSimpleExpression)(node.content, true, node.loc);
2873
- else exp = node.content;
2874
- if (exp.content) exps.push(exp);
2875
- }
2876
- return exps;
2877
- }
2878
- function isTextLike(node) {
2879
- return node.type === 5 || node.type === 2;
2880
- }
2881
- //#endregion
2882
4184
  //#region packages/compiler-vapor/src/transforms/vModel.ts
2883
4185
  const transformVModel = (dir, node, context) => {
2884
4186
  const { exp, arg } = dir;
@@ -2933,7 +4235,7 @@ const transformVModel = (dir, node, context) => {
2933
4235
  else checkDuplicatedValue();
2934
4236
  else context.options.onError((0, _vue_compiler_dom.createDOMCompilerError)(58, dir.loc));
2935
4237
  if (modelType) context.registerOperation({
2936
- type: 13,
4238
+ type: 14,
2937
4239
  element: context.reference(),
2938
4240
  dir,
2939
4241
  name: "model",
@@ -2947,9 +4249,17 @@ const transformVModel = (dir, node, context) => {
2947
4249
  };
2948
4250
  //#endregion
2949
4251
  //#region packages/compiler-vapor/src/transforms/transformComment.ts
4252
+ const ignoredComments = /* @__PURE__ */ new WeakMap();
4253
+ function ignoreComment(node, context) {
4254
+ let ignored = ignoredComments.get(context.root);
4255
+ if (!ignored) ignoredComments.set(context.root, ignored = /* @__PURE__ */ new WeakSet());
4256
+ ignored.add(node);
4257
+ }
2950
4258
  const transformComment = (node, context) => {
4259
+ var _ignoredComments$get;
2951
4260
  if (node.type !== 3) return;
2952
- if (getSiblingIf(context)) {
4261
+ if ((_ignoredComments$get = ignoredComments.get(context.root)) === null || _ignoredComments$get === void 0 ? void 0 : _ignoredComments$get.has(node)) context.dynamic.flags |= 2;
4262
+ else if (getSiblingIf(context)) {
2953
4263
  context.comment.push(node);
2954
4264
  context.dynamic.flags |= 2;
2955
4265
  } else context.template += `<!--${(0, _vue_shared.escapeHtml)(node.content)}-->`;
@@ -2980,6 +4290,8 @@ function processIf(node, dir, context) {
2980
4290
  dir.exp = (0, _vue_compiler_dom.createSimpleExpression)(`true`, false, loc);
2981
4291
  }
2982
4292
  context.dynamic.flags |= 2;
4293
+ const forceMultiRoot = shouldForceMultiRoot(context);
4294
+ const allowNoScope = context.block === context.root.block;
2983
4295
  if (dir.name === "if") {
2984
4296
  const id = context.reference();
2985
4297
  context.dynamic.flags |= 4;
@@ -2987,9 +4299,10 @@ function processIf(node, dir, context) {
2987
4299
  return () => {
2988
4300
  onExit();
2989
4301
  context.dynamic.operation = {
2990
- type: 14,
4302
+ type: 15,
2991
4303
  id,
2992
- blockShape: encodeIfBlockShape(branch),
4304
+ ...context.effectBoundary(),
4305
+ blockShape: encodeIfBlockShape(branch, forceMultiRoot, void 0, allowNoScope),
2993
4306
  condition: dir.exp,
2994
4307
  positive: branch,
2995
4308
  index: context.root.nextIfIndex(),
@@ -3002,26 +4315,29 @@ function processIf(node, dir, context) {
3002
4315
  let lastIfNode;
3003
4316
  if (siblings) {
3004
4317
  let i = siblings.length;
3005
- while (i--) if (siblings[i].operation && siblings[i].operation.type === 14) {
4318
+ while (i--) if (siblings[i].operation && siblings[i].operation.type === 15) {
3006
4319
  lastIfNode = siblings[i].operation;
3007
4320
  break;
3008
4321
  }
3009
4322
  }
3010
- if (!siblingIf || !lastIfNode || lastIfNode.type !== 14) {
4323
+ if (!siblingIf || !lastIfNode || lastIfNode.type !== 15) {
3011
4324
  context.options.onError((0, _vue_compiler_dom.createCompilerError)(30, node.loc));
3012
4325
  return;
3013
4326
  }
3014
- while (lastIfNode.negative && lastIfNode.negative.type === 14) lastIfNode = lastIfNode.negative;
4327
+ while (lastIfNode.negative && lastIfNode.negative.type === 15) lastIfNode = lastIfNode.negative;
3015
4328
  if (dir.name === "else-if" && lastIfNode.negative) context.options.onError((0, _vue_compiler_dom.createCompilerError)(30, node.loc));
3016
- if (context.root.comment.length) {
3017
- node = wrapTemplate(node, ["else-if", "else"]);
3018
- context.node = node = (0, _vue_shared.extend)({}, node, { children: [...context.comment, ...node.children] });
4329
+ const comments = context.comment;
4330
+ if (comments.length) {
4331
+ if (!isInTransition(context)) {
4332
+ node = wrapTemplate(node, ["else-if", "else"]);
4333
+ context.node = node = (0, _vue_shared.extend)({}, node, { children: [...comments, ...node.children] });
4334
+ }
4335
+ comments.length = 0;
3019
4336
  }
3020
- context.root.comment = [];
3021
4337
  const [branch, onExit] = createIfBranch(node, context);
3022
4338
  if (dir.name === "else") lastIfNode.negative = branch;
3023
4339
  else lastIfNode.negative = {
3024
- type: 14,
4340
+ type: 15,
3025
4341
  id: -1,
3026
4342
  condition: dir.exp,
3027
4343
  positive: branch,
@@ -3031,8 +4347,8 @@ function processIf(node, dir, context) {
3031
4347
  };
3032
4348
  return () => {
3033
4349
  onExit();
3034
- if (lastIfNode.negative.type === 14) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive);
3035
- lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, lastIfNode.negative);
4350
+ if (lastIfNode.negative.type === 15) lastIfNode.negative.blockShape = encodeIfBlockShape(lastIfNode.negative.positive, forceMultiRoot, void 0, allowNoScope);
4351
+ lastIfNode.blockShape = encodeIfBlockShape(lastIfNode.positive, forceMultiRoot, lastIfNode.negative, allowNoScope);
3036
4352
  };
3037
4353
  }
3038
4354
  }
@@ -3047,12 +4363,41 @@ function createIfBranch(node, context) {
3047
4363
  context.reference();
3048
4364
  return [branch, exitBlock];
3049
4365
  }
3050
- function encodeIfBlockShape(positive, negative) {
3051
- return getBlockShape(positive) | getNegativeBlockShape(negative) << 2;
4366
+ function encodeIfBlockShape(positive, forceMultiRoot = false, negative, allowNoScope = true) {
4367
+ if (forceMultiRoot) return 10;
4368
+ const positiveNoScope = allowNoScope && canSkipIfBranchScope(positive);
4369
+ const negativeNoScope = allowNoScope && negative && negative.type !== 15 && canSkipIfBranchScope(negative);
4370
+ return getBlockShape(positive) | getNegativeIfBranchShape(negative) << 2 | (positiveNoScope ? 32 : 0) | (negativeNoScope ? 64 : 0);
3052
4371
  }
3053
- function getNegativeBlockShape(negative) {
4372
+ function getNegativeIfBranchShape(negative) {
3054
4373
  if (!negative) return 0;
3055
- return negative.type === 14 ? 1 : getBlockShape(negative);
4374
+ return negative.type === 15 ? 1 : getBlockShape(negative);
4375
+ }
4376
+ function canSkipIfBranchScope(block) {
4377
+ if (block.effect.length || block.operation.length) return false;
4378
+ if (!isStaticBranch(block.node)) return false;
4379
+ if (block.returns.length === 0 || block.dynamic.children.length !== block.returns.length) return false;
4380
+ return block.returns.every((id) => {
4381
+ const returned = findReturnedDynamic(block, id);
4382
+ return !!(returned && returned.template != null && !returned.operation && !returned.hasDynamicChild && !(returned.flags & 6));
4383
+ });
4384
+ }
4385
+ function findReturnedDynamic(block, id) {
4386
+ return block.dynamic.children.find((child) => child.id === id);
4387
+ }
4388
+ function isStaticBranch(node) {
4389
+ if (node.type !== 1 || node.tagType !== 3 || node.children.length === 0) return false;
4390
+ return node.children.every((child) => isStaticTemplateNode(child));
4391
+ }
4392
+ function isStaticTemplateNode(node) {
4393
+ if (node.type === 2 || node.type === 3) return true;
4394
+ if (node.type !== 1 || node.tagType !== 0) return false;
4395
+ for (const prop of node.props) if (prop.type === 7 || prop.name === "ref") return false;
4396
+ return node.children.every((child) => isStaticTemplateNode(child));
4397
+ }
4398
+ function shouldForceMultiRoot(context) {
4399
+ const parent = context.parent && context.parent.node;
4400
+ return !!parent && parent.type === 1 && parent.tagType === 3 && parent.props.some((prop) => prop.type === 7 && prop.name === "for");
3056
4401
  }
3057
4402
  //#endregion
3058
4403
  //#region packages/compiler-vapor/src/transforms/vFor.ts
@@ -3082,8 +4427,9 @@ function processFor(node, dir, context) {
3082
4427
  const { parent } = context;
3083
4428
  const isOnlyChild = parent && parent.block.node !== parent.node && parent.node.children.length === 1;
3084
4429
  context.dynamic.operation = {
3085
- type: 15,
4430
+ type: 16,
3086
4431
  id,
4432
+ ...context.effectBoundary(),
3087
4433
  source,
3088
4434
  value,
3089
4435
  key,
@@ -3128,19 +4474,22 @@ const transformSlotOutlet = (node, context) => {
3128
4474
  if (slotProps.length) {
3129
4475
  const [isDynamic, props] = buildProps((0, _vue_shared.extend)({}, node, { props: slotProps }), context, true);
3130
4476
  irProps = isDynamic ? props : [props];
3131
- const runtimeDirective = context.block.operation.find((oper) => oper.type === 13 && oper.element === id);
4477
+ const runtimeDirective = context.block.operation.find((oper) => oper.type === 14 && oper.element === id);
3132
4478
  if (runtimeDirective) context.options.onError((0, _vue_compiler_dom.createCompilerError)(36, runtimeDirective.dir.loc));
3133
4479
  }
3134
4480
  return () => {
3135
4481
  exitBlock && exitBlock();
4482
+ let flags = 0;
4483
+ if (context.options.scopeId && !context.options.slotted) flags |= 1;
4484
+ if (context.inVOnce) flags |= 2;
3136
4485
  context.dynamic.operation = {
3137
- type: 12,
4486
+ type: 13,
3138
4487
  id,
4488
+ ...context.effectBoundary(),
3139
4489
  name: slotName,
3140
4490
  props: irProps,
3141
4491
  fallback,
3142
- noSlotted: !!(context.options.scopeId && !context.options.slotted),
3143
- once: context.inVOnce
4492
+ flags
3144
4493
  };
3145
4494
  };
3146
4495
  };
@@ -3162,7 +4511,7 @@ function createFallback(node, context) {
3162
4511
  //#region packages/compiler-vapor/src/transforms/vSlot.ts
3163
4512
  const transformVSlot = (node, context) => {
3164
4513
  if (node.type !== 1) return;
3165
- const dir = findDir$2(node, "slot", true);
4514
+ const dir = findDir$4(node, "slot", true);
3166
4515
  const { tagType, children } = node;
3167
4516
  const { parent } = context;
3168
4517
  const isComponent = tagType === 1;
@@ -3174,10 +4523,19 @@ const transformVSlot = (node, context) => {
3174
4523
  function transformComponentSlot(node, dir, context) {
3175
4524
  const { children } = node;
3176
4525
  const arg = dir && dir.arg;
4526
+ const hasTemplateSlots = children.some(isSlotTemplateChild);
3177
4527
  const emptyTextNodes = [];
3178
4528
  const nonSlotTemplateChildren = children.filter((n) => {
3179
- if (isNonWhitespaceContent(n)) return !(n.type === 1 && n.props.some(_vue_compiler_dom.isVSlot));
3180
- else emptyTextNodes.push(n);
4529
+ if (isSlotTemplateChild(n)) return false;
4530
+ if (n.type === 3 && hasTemplateSlots) {
4531
+ ignoreComment(n, context);
4532
+ return false;
4533
+ }
4534
+ if (isNonWhitespaceContent(n)) return true;
4535
+ else {
4536
+ emptyTextNodes.push(n);
4537
+ return false;
4538
+ }
3181
4539
  });
3182
4540
  if (!nonSlotTemplateChildren.length) emptyTextNodes.forEach((n) => {
3183
4541
  markNonTemplate(n, context);
@@ -3201,14 +4559,16 @@ function transformComponentSlot(node, dir, context) {
3201
4559
  }
3202
4560
  function transformTemplateSlot(node, dir, context) {
3203
4561
  context.dynamic.flags |= 2;
3204
- const arg = dir.arg && resolveExpression(dir.arg);
3205
- const vFor = findDir$2(node, "for");
3206
- const vIf = findDir$2(node, "if");
3207
- const vElse = findDir$2(node, /^else(-if)?$/, true);
4562
+ const resolvedArg = dir.arg && resolveExpression(dir.arg);
4563
+ let arg = resolvedArg;
4564
+ if (!arg) arg = (0, _vue_compiler_dom.createSimpleExpression)("default", true);
4565
+ const vFor = findDir$4(node, "for");
4566
+ const vIf = findDir$4(node, "if");
4567
+ const vElse = findDir$4(node, /^else(-if)?$/, true);
3208
4568
  const { slots } = context;
3209
4569
  const [block, onExit] = createSlotBlock(node, dir, context);
3210
4570
  if (!vFor && !vIf && !vElse) {
3211
- const slotName = arg ? arg.isStatic && arg.content : "default";
4571
+ const slotName = resolvedArg ? resolvedArg.isStatic && resolvedArg.content : "default";
3212
4572
  if (slotName && hasStaticSlot(slots, slotName)) context.options.onError((0, _vue_compiler_dom.createCompilerError)(38, dir.loc));
3213
4573
  else registerSlot(slots, arg, block);
3214
4574
  } else if (vIf) registerDynamicSlot(slots, {
@@ -3222,7 +4582,7 @@ function transformTemplateSlot(node, dir, context) {
3222
4582
  });
3223
4583
  else if (vElse) {
3224
4584
  const vIfSlot = slots[slots.length - 1];
3225
- if (vIfSlot.slotType === 3) {
4585
+ if (vIfSlot && vIfSlot.slotType === 3) {
3226
4586
  let ifNode = vIfSlot;
3227
4587
  while (ifNode.negative && ifNode.negative.slotType === 3) ifNode = ifNode.negative;
3228
4588
  const negative = vElse.exp ? {
@@ -3284,6 +4644,9 @@ function isNonWhitespaceContent(node) {
3284
4644
  if (node.type !== 2) return true;
3285
4645
  return !!node.content.trim();
3286
4646
  }
4647
+ function isSlotTemplateChild(node) {
4648
+ return node.type === 1 && (0, _vue_compiler_dom.isTemplateNode)(node) && !!findDir$4(node, "slot", true);
4649
+ }
3287
4650
  //#endregion
3288
4651
  //#region packages/compiler-vapor/src/transforms/transformTransition.ts
3289
4652
  const transformTransition = (node, context) => {
@@ -3294,15 +4657,18 @@ const transformTransition = (node, context) => {
3294
4657
  function hasMultipleChildren(node) {
3295
4658
  const children = node.children = node.children.filter((c) => c.type !== 3 && !(c.type === 2 && !c.content.trim()));
3296
4659
  const first = children[0];
3297
- if (children.length === 1 && first.type === 1 && (findDir$2(first, "for") || (0, _vue_compiler_dom.isTemplateNode)(first))) return true;
3298
- const hasElse = (node) => findDir$2(node, "else-if") || findDir$2(node, "else", true);
3299
- if (children.every((c, index) => c.type === 1 && !(0, _vue_compiler_dom.isTemplateNode)(c) && !findDir$2(c, "for") && (index === 0 ? findDir$2(c, "if") : hasElse(c)))) return false;
3300
- return children.length > 1;
4660
+ if (children.length === 1 && first.type === 1) {
4661
+ if (findDir$4(first, "for")) return true;
4662
+ if ((0, _vue_compiler_dom.isTemplateNode)(first)) return hasMultipleChildren(first);
4663
+ }
4664
+ const hasElse = (node) => findDir$4(node, "else-if") || findDir$4(node, "else", true);
4665
+ if (children.length > 0 && children.every((c, index) => c.type === 1 && (!(0, _vue_compiler_dom.isTemplateNode)(c) || !hasMultipleChildren(c)) && !findDir$4(c, "for") && (index === 0 ? findDir$4(c, "if") : hasElse(c)))) return false;
4666
+ return children.length !== 1;
3301
4667
  }
3302
4668
  //#endregion
3303
4669
  //#region packages/compiler-vapor/src/transforms/transformKey.ts
3304
4670
  const transformKey = (node, context) => {
3305
- if (node.type !== 1 || context.inVOnce || findDir$2(node, "for")) return;
4671
+ if (node.type !== 1 || context.inVOnce || findDir$4(node, "for")) return;
3306
4672
  const dir = findProp$1(node, "key", true, true);
3307
4673
  if (!dir || dir.type === 6) return;
3308
4674
  let value;
@@ -3316,8 +4682,9 @@ const transformKey = (node, context) => {
3316
4682
  return () => {
3317
4683
  exitBlock();
3318
4684
  context.dynamic.operation = {
3319
- type: 16,
4685
+ type: 17,
3320
4686
  id,
4687
+ ...context.effectBoundary(),
3321
4688
  value,
3322
4689
  block
3323
4690
  };
@@ -3385,6 +4752,7 @@ exports.DynamicFlag = DynamicFlag;
3385
4752
  exports.IRDynamicPropsKind = IRDynamicPropsKind;
3386
4753
  exports.IRNodeTypes = IRNodeTypes;
3387
4754
  exports.IRSlotType = IRSlotType;
4755
+ exports.TemplateRegistry = TemplateRegistry;
3388
4756
  exports.VaporErrorCodes = VaporErrorCodes;
3389
4757
  exports.VaporErrorMessages = VaporErrorMessages;
3390
4758
  exports.buildCodeFragment = buildCodeFragment;