svelte2tsx 0.7.6 → 0.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -2373,7 +2373,7 @@ const numberOnlyAttributes = new Set([
2373
2373
  * - lowercase DOM attributes
2374
2374
  * - multi-value handling
2375
2375
  */
2376
- function handleAttribute(str, attr, parent, preserveCase, element) {
2376
+ function handleAttribute(str, attr, parent, preserveCase, svelte5Plus, element) {
2377
2377
  if (parent.name === '!DOCTYPE' ||
2378
2378
  ['Style', 'Script'].includes(parent.type) ||
2379
2379
  (attr.name === 'name' && parent.type === 'Slot')) {
@@ -2403,7 +2403,7 @@ function handleAttribute(str, attr, parent, preserveCase, element) {
2403
2403
  element.addAttribute(name, value);
2404
2404
  }
2405
2405
  : (name, value) => {
2406
- if (attr.name.startsWith('--') && attr.value !== true) {
2406
+ if (attr.name.startsWith('--')) {
2407
2407
  // CSS custom properties are not part of the props
2408
2408
  // definition, so wrap them to not get "--xx is invalid prop" errors
2409
2409
  name.unshift('...__sveltets_2_cssProp({');
@@ -2420,7 +2420,8 @@ function handleAttribute(str, attr, parent, preserveCase, element) {
2420
2420
  const transformAttributeCase = (name) => {
2421
2421
  if (!preserveCase &&
2422
2422
  !svgAttributes.find((x) => x == name) &&
2423
- !(element instanceof Element && element.tagName.includes('-'))) {
2423
+ !(element instanceof Element && element.tagName.includes('-')) &&
2424
+ !(svelte5Plus && name.startsWith('on'))) {
2424
2425
  return name.toLowerCase();
2425
2426
  }
2426
2427
  else {
@@ -2629,14 +2630,11 @@ const supportsBindThis = [
2629
2630
  /**
2630
2631
  * Transform bind:xxx into something that conforms to JS/TS
2631
2632
  */
2632
- function handleBinding(str, attr, parent, element, preserveBind) {
2633
+ function handleBinding(str, attr, parent, element, preserveBind, isSvelte5Plus) {
2633
2634
  // bind group on input
2634
2635
  if (element instanceof Element && attr.name == 'group' && parent.name == 'input') {
2635
2636
  // add reassignment to force TS to widen the type of the declaration (in case it's never reassigned anywhere else)
2636
- const expressionStr = str.original.substring(attr.expression.start, getEnd(attr.expression));
2637
- element.appendToStartEnd([
2638
- surroundWithIgnoreComments(`() => ${expressionStr} = __sveltets_2_any(null);`)
2639
- ]);
2637
+ appendOneWayBinding(attr, ' = __sveltets_2_any(null)', element);
2640
2638
  return;
2641
2639
  }
2642
2640
  // bind this
@@ -2688,8 +2686,18 @@ function handleBinding(str, attr, parent, element, preserveBind) {
2688
2686
  const value = isShorthand
2689
2687
  ? preserveBind && element instanceof Element
2690
2688
  ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2691
- : undefined
2692
- : [rangeWithTrailingPropertyAccess(str.original, attr.expression)];
2689
+ : isSvelte5Plus
2690
+ ? [
2691
+ `__sveltets_2_binding(${str.original.substring(attr.expression.start, attr.expression.end)})`
2692
+ ]
2693
+ : undefined
2694
+ : element instanceof Element || !isSvelte5Plus
2695
+ ? [rangeWithTrailingPropertyAccess(str.original, attr.expression)]
2696
+ : [
2697
+ '__sveltets_2_binding(',
2698
+ rangeWithTrailingPropertyAccess(str.original, attr.expression),
2699
+ ')'
2700
+ ];
2693
2701
  if (element instanceof Element) {
2694
2702
  element.addAttribute(name, value);
2695
2703
  }
@@ -2906,7 +2914,7 @@ function handleKey(str, keyBlock) {
2906
2914
  * @param node
2907
2915
  * @param element
2908
2916
  */
2909
- function handleLet(str, node, parent, preserveCase, element) {
2917
+ function handleLet(str, node, parent, preserveCase, svelte5Plus, element) {
2910
2918
  if (element instanceof InlineComponent) {
2911
2919
  // let:xx belongs to either the default slot or a named slot,
2912
2920
  // which is determined in Attribute.ts
@@ -2934,7 +2942,7 @@ function handleLet(str, node, parent, preserveCase, element) {
2934
2942
  }
2935
2943
  ]
2936
2944
  : true
2937
- }, parent, preserveCase, element);
2945
+ }, parent, preserveCase, svelte5Plus, element);
2938
2946
  }
2939
2947
  }
2940
2948
  }
@@ -3090,25 +3098,22 @@ function handleTransitionDirective(str, attr, element) {
3090
3098
  * ```
3091
3099
  */
3092
3100
  function handleSnippet(str, snippetBlock, component) {
3093
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
3101
+ var _a, _b, _c, _d, _e, _f;
3094
3102
  const isImplicitProp = component !== undefined;
3095
3103
  const endSnippet = str.original.lastIndexOf('{', snippetBlock.end - 1);
3096
3104
  // Return something to silence the "snippet type not assignable to return type void" error
3097
- str.overwrite(endSnippet, snippetBlock.end, `return __sveltets_2_any(0)}${isImplicitProp ? '' : ';'}`, {
3105
+ str.overwrite(endSnippet, snippetBlock.end, `};return __sveltets_2_any(0)}${isImplicitProp ? '' : ';'}`, {
3098
3106
  contentOnly: true
3099
3107
  });
3100
3108
  const startEnd = str.original.indexOf('}',
3101
3109
  // context was the first iteration in a .next release, remove at some point
3102
- ((_a = snippetBlock.context) === null || _a === void 0 ? void 0 : _a.end) ||
3103
- ((_c = (_b = snippetBlock.parameters) === null || _b === void 0 ? void 0 : _b.at(-1)) === null || _c === void 0 ? void 0 : _c.end) ||
3104
- snippetBlock.expression.end) + 1;
3110
+ ((_b = (_a = snippetBlock.parameters) === null || _a === void 0 ? void 0 : _a.at(-1)) === null || _b === void 0 ? void 0 : _b.end) || snippetBlock.expression.end) + 1;
3105
3111
  if (isImplicitProp) {
3106
3112
  str.overwrite(snippetBlock.start, snippetBlock.expression.start, '', { contentOnly: true });
3107
3113
  const transforms = ['('];
3108
- if (snippetBlock.context || ((_d = snippetBlock.parameters) === null || _d === void 0 ? void 0 : _d.length)) {
3109
- // context was the first iteration in a .next release, remove at some point
3110
- const start = ((_e = snippetBlock.context) === null || _e === void 0 ? void 0 : _e.start) || ((_f = snippetBlock.parameters) === null || _f === void 0 ? void 0 : _f[0].start);
3111
- const end = ((_g = snippetBlock.context) === null || _g === void 0 ? void 0 : _g.end) || snippetBlock.parameters.at(-1).end;
3114
+ if ((_c = snippetBlock.parameters) === null || _c === void 0 ? void 0 : _c.length) {
3115
+ const start = (_d = snippetBlock.parameters) === null || _d === void 0 ? void 0 : _d[0].start;
3116
+ const end = snippetBlock.parameters.at(-1).end;
3112
3117
  transforms.push([start, end]);
3113
3118
  str.overwrite(snippetBlock.expression.end, start, '', {
3114
3119
  contentOnly: true
@@ -3118,20 +3123,13 @@ function handleSnippet(str, snippetBlock, component) {
3118
3123
  else {
3119
3124
  str.overwrite(snippetBlock.expression.end, startEnd, '', { contentOnly: true });
3120
3125
  }
3121
- transforms.push(') => {');
3126
+ transforms.push(') => {async () => {'); // inner async function for potential #await blocks
3122
3127
  transforms.push([startEnd, snippetBlock.end]);
3123
3128
  component.addProp([[snippetBlock.expression.start, snippetBlock.expression.end]], transforms);
3124
3129
  }
3125
3130
  else {
3126
3131
  let generic = '';
3127
- // context was the first iteration in a .next release, remove at some point
3128
- if (snippetBlock.context) {
3129
- generic = snippetBlock.context.typeAnnotation
3130
- ? `<${str.original.slice(snippetBlock.context.typeAnnotation.start + 1, snippetBlock.context.typeAnnotation.end)}>`
3131
- : // slap any on to it to silence "implicit any" errors; JSDoc people can't add types to snippets
3132
- '<any>';
3133
- }
3134
- else if ((_h = snippetBlock.parameters) === null || _h === void 0 ? void 0 : _h.length) {
3132
+ if ((_e = snippetBlock.parameters) === null || _e === void 0 ? void 0 : _e.length) {
3135
3133
  generic = `<[${snippetBlock.parameters
3136
3134
  .map((p) => p.typeAnnotation
3137
3135
  ? str.original.slice(p.typeAnnotation.start + 1, p.typeAnnotation.end)
@@ -3145,16 +3143,12 @@ function handleSnippet(str, snippetBlock, component) {
3145
3143
  [snippetBlock.expression.start, snippetBlock.expression.end],
3146
3144
  typeAnnotation + ' = ('
3147
3145
  ];
3148
- // context was the first iteration in a .next release, remove at some point
3149
- if (snippetBlock.context) {
3150
- transforms.push([snippetBlock.context.start, snippetBlock.context.end]);
3151
- }
3152
- else if ((_j = snippetBlock.parameters) === null || _j === void 0 ? void 0 : _j.length) {
3146
+ if ((_f = snippetBlock.parameters) === null || _f === void 0 ? void 0 : _f.length) {
3153
3147
  const start = snippetBlock.parameters[0].start;
3154
3148
  const end = snippetBlock.parameters.at(-1).end;
3155
3149
  transforms.push([start, end]);
3156
3150
  }
3157
- transforms.push(') => {');
3151
+ transforms.push(') => {async () => {'); // inner async function for potential #await blocks
3158
3152
  transform(str, snippetBlock.start, startEnd, startEnd, transforms);
3159
3153
  }
3160
3154
  }
@@ -3197,22 +3191,10 @@ function handleImplicitChildren(componentNode, component) {
3197
3191
  * `{@render foo(x)}` --> `;foo(x);`
3198
3192
  */
3199
3193
  function handleRenderTag(str, renderTag) {
3200
- var _a;
3201
3194
  str.overwrite(renderTag.start, renderTag.expression.start, ';__sveltets_2_ensureSnippet(', {
3202
3195
  contentOnly: true
3203
3196
  });
3204
- // argument was present until https://github.com/sveltejs/svelte/pull/9988 / https://github.com/sveltejs/svelte/pull/10656,
3205
- // remove and only keep last else block at some point
3206
- const arg = renderTag.argument || ((_a = renderTag.arguments) === null || _a === void 0 ? void 0 : _a[renderTag.arguments.length - 1]);
3207
- if (arg) {
3208
- str.overwrite(withTrailingPropertyAccess(str.original, arg.end), renderTag.end, '));');
3209
- }
3210
- else if ('argument' in renderTag || 'arguments' in renderTag) {
3211
- str.overwrite(withTrailingPropertyAccess(str.original, renderTag.expression.end), renderTag.end, '());');
3212
- }
3213
- else {
3214
- str.overwrite(withTrailingPropertyAccess(str.original, renderTag.expression.end), renderTag.end, ');');
3215
- }
3197
+ str.overwrite(withTrailingPropertyAccess(str.original, renderTag.expression.end), renderTag.end, ');');
3216
3198
  }
3217
3199
 
3218
3200
  function stripDoctype(str) {
@@ -3311,7 +3293,7 @@ function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {
3311
3293
  handleComment(str, node);
3312
3294
  break;
3313
3295
  case 'Binding':
3314
- handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML');
3296
+ handleBinding(str, node, parent, element, options.typingsNamespace === 'svelteHTML', options.svelte5Plus);
3315
3297
  break;
3316
3298
  case 'Class':
3317
3299
  handleClassDirective(str, node, element);
@@ -3329,7 +3311,7 @@ function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {
3329
3311
  handleAnimateDirective(str, node, element);
3330
3312
  break;
3331
3313
  case 'Attribute':
3332
- handleAttribute(str, node, parent, options.preserveAttributeCase, element);
3314
+ handleAttribute(str, node, parent, options.preserveAttributeCase, options.svelte5Plus, element);
3333
3315
  break;
3334
3316
  case 'Spread':
3335
3317
  handleSpread(node, element);
@@ -3338,7 +3320,7 @@ function convertHtmlxToJsx(str, ast, onWalk = null, onLeave = null, options = {
3338
3320
  handleEventHandler(str, node, element);
3339
3321
  break;
3340
3322
  case 'Let':
3341
- handleLet(str, node, parent, options.preserveAttributeCase, element);
3323
+ handleLet(str, node, parent, options.preserveAttributeCase, options.svelte5Plus, element);
3342
3324
  break;
3343
3325
  case 'Text':
3344
3326
  handleText(str, node, parent);
@@ -4411,15 +4393,20 @@ class ExportedNames {
4411
4393
  * Uses the `$$Props` type
4412
4394
  */
4413
4395
  this.uses$$Props = false;
4396
+ /**
4397
+ * Component contains globals that have a rune name
4398
+ */
4399
+ this.hasRunesGlobals = false;
4414
4400
  /**
4415
4401
  * The `$props()` rune's type info as a string, if it exists.
4416
4402
  * If using TS, this returns the generic string, if using JS, returns the `@type {..}` string.
4417
4403
  */
4418
4404
  this.$props = {
4419
4405
  comment: '',
4420
- generic: '',
4421
- mayHaveChildrenProp: false
4406
+ type: '',
4407
+ bindings: []
4422
4408
  };
4409
+ /** Map of all props and exports. Exposing it publicly is no longer necessary for runes mode */
4423
4410
  this.exports = new Map();
4424
4411
  this.possibleExports = new Map();
4425
4412
  this.doneDeclarationTransformation = new Set();
@@ -4494,42 +4481,40 @@ class ExportedNames {
4494
4481
  }
4495
4482
  handle$propsRune(node) {
4496
4483
  var _a, _b;
4497
- // Check if the $props() rune has a children prop
4484
+ // Check if the $props() rune uses $bindable()
4498
4485
  if (ts.isObjectBindingPattern(node.name)) {
4499
4486
  for (const element of node.name.elements) {
4500
- if (!ts.isIdentifier(element.name) ||
4501
- (element.propertyName && !ts.isIdentifier(element.propertyName)) ||
4502
- !!element.dotDotDotToken) {
4503
- // not statically analyzable, so we assume it may have children
4504
- this.$props.mayHaveChildrenProp = true;
4505
- }
4506
- else {
4487
+ if (ts.isIdentifier(element.name) &&
4488
+ (!element.propertyName || ts.isIdentifier(element.propertyName)) &&
4489
+ !element.dotDotDotToken) {
4507
4490
  const name = element.propertyName
4508
4491
  ? element.propertyName.text
4509
4492
  : element.name.text;
4510
- if (name === 'children') {
4511
- this.$props.mayHaveChildrenProp = true;
4493
+ if (element.initializer) {
4494
+ const call = element.initializer;
4495
+ if (ts.isCallExpression(call) && ts.isIdentifier(call.expression)) {
4496
+ if (call.expression.text === '$bindable') {
4497
+ this.$props.bindings.push(name);
4498
+ }
4499
+ }
4512
4500
  }
4513
4501
  }
4514
4502
  }
4515
4503
  }
4516
- else {
4517
- this.$props.mayHaveChildrenProp = true;
4518
- }
4519
4504
  if (((_a = node.initializer.typeArguments) === null || _a === void 0 ? void 0 : _a.length) > 0 || node.type) {
4520
4505
  const generic_arg = ((_b = node.initializer.typeArguments) === null || _b === void 0 ? void 0 : _b[0]) || node.type;
4521
4506
  const generic = generic_arg.getText();
4522
4507
  if (!generic.includes('{')) {
4523
- this.$props.generic = generic;
4508
+ this.$props.type = generic;
4524
4509
  }
4525
4510
  else {
4526
4511
  // Create a virtual type alias for the unnamed generic and reuse it for the props return type
4527
4512
  // so that rename, find references etc works seamlessly across components
4528
- this.$props.generic = '$$ComponentProps';
4529
- preprendStr(this.str, generic_arg.pos + this.astOffset, `;type ${this.$props.generic} = `);
4513
+ this.$props.type = '$$ComponentProps';
4514
+ preprendStr(this.str, generic_arg.pos + this.astOffset, `;type ${this.$props.type} = `);
4530
4515
  this.str.appendLeft(generic_arg.end + this.astOffset, ';');
4531
4516
  this.str.move(generic_arg.pos + this.astOffset, generic_arg.end + this.astOffset, node.parent.pos + this.astOffset);
4532
- this.str.appendRight(generic_arg.end + this.astOffset, this.$props.generic);
4517
+ this.str.appendRight(generic_arg.end + this.astOffset, this.$props.type);
4533
4518
  }
4534
4519
  }
4535
4520
  else {
@@ -4582,9 +4567,6 @@ class ExportedNames {
4582
4567
  let props = [];
4583
4568
  const isKitRouteFile = internalHelpers.isKitRouteFile(this.basename);
4584
4569
  const isKitLayoutFile = isKitRouteFile && this.basename.includes('layout');
4585
- if (isKitRouteFile) {
4586
- this.$props.mayHaveChildrenProp = isKitLayoutFile;
4587
- }
4588
4570
  if (ts.isObjectBindingPattern(node.name)) {
4589
4571
  for (const element of node.name.elements) {
4590
4572
  if (!ts.isIdentifier(element.name) ||
@@ -4645,10 +4627,10 @@ class ExportedNames {
4645
4627
  // Create a virtual type alias for the unnamed generic and reuse it for the props return type
4646
4628
  // so that rename, find references etc works seamlessly across components
4647
4629
  if (this.isTsFile) {
4648
- this.$props.generic = '$$ComponentProps';
4630
+ this.$props.type = '$$ComponentProps';
4649
4631
  if (props.length > 0 || withUnknown) {
4650
4632
  preprendStr(this.str, node.parent.pos + this.astOffset, surroundWithIgnoreComments(`;type $$ComponentProps = ${propsStr};`));
4651
- preprendStr(this.str, node.name.end + this.astOffset, `: ${this.$props.generic}`);
4633
+ preprendStr(this.str, node.name.end + this.astOffset, `: ${this.$props.type}`);
4652
4634
  }
4653
4635
  }
4654
4636
  else {
@@ -4762,14 +4744,22 @@ class ExportedNames {
4762
4744
  }
4763
4745
  this.getters.add(node.text);
4764
4746
  }
4765
- createClassGetters() {
4766
- return Array.from(this.getters)
4767
- .map((name) =>
4768
- // getters are const/classes/functions, which are always defined.
4769
- // We have to remove the `| undefined` from the type here because it was necessary to
4770
- // be added in a previous step so people are not expected to provide these as props.
4771
- `\n get ${name}() { return __sveltets_2_nonNullable(this.$$prop_def.${name}) }`)
4772
- .join('');
4747
+ createClassGetters(generics = '') {
4748
+ if (this.usesRunes()) {
4749
+ // In runes mode, exports are no longer part of props
4750
+ return Array.from(this.getters)
4751
+ .map((name) => `\n get ${name}() { return render${generics}().exports.${name} }`)
4752
+ .join('');
4753
+ }
4754
+ else {
4755
+ return Array.from(this.getters)
4756
+ .map((name) =>
4757
+ // getters are const/classes/functions, which are always defined.
4758
+ // We have to remove the `| undefined` from the type here because it was necessary to
4759
+ // be added in a previous step so people are not expected to provide these as props.
4760
+ `\n get ${name}() { return __sveltets_2_nonNullable(this.$$prop_def.${name}) }`)
4761
+ .join('');
4762
+ }
4773
4763
  }
4774
4764
  createClassAccessors() {
4775
4765
  const accessors = [];
@@ -4809,14 +4799,6 @@ class ExportedNames {
4809
4799
  });
4810
4800
  }
4811
4801
  }
4812
- addImplicitChildrenExport(hasParams) {
4813
- if (this.exports.has('children'))
4814
- return;
4815
- this.exports.set('children', {
4816
- isLet: true,
4817
- implicitChildren: hasParams ? 'has_params' : 'empty'
4818
- });
4819
- }
4820
4802
  /**
4821
4803
  * Adds export to map
4822
4804
  */
@@ -4873,34 +4855,46 @@ class ExportedNames {
4873
4855
  /**
4874
4856
  * Creates a string from the collected props
4875
4857
  *
4876
- * @param isTsFile Whether this is a TypeScript file or not.
4877
4858
  * @param uses$$propsOr$$restProps whether the file references the $$props or $$restProps variable
4878
4859
  */
4879
4860
  createPropsStr(uses$$propsOr$$restProps) {
4880
4861
  const names = Array.from(this.exports.entries());
4881
- if (this.$props.generic) {
4882
- const others = names.filter(([, { isLet, implicitChildren }]) => !isLet || !!implicitChildren);
4862
+ if (this.$props.type) {
4883
4863
  return ('{} as any as ' +
4884
- this.$props.generic +
4885
- (others.length
4886
- ? ' & { ' + this.createReturnElementsType(others).join(',') + ' }'
4887
- : ''));
4864
+ (this.$props.bindings.length
4865
+ ? `__sveltets_2_Bindings<${this.$props.type}, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4866
+ : this.$props.type));
4888
4867
  }
4889
4868
  if (this.$props.comment) {
4890
- // Try our best to incorporate createReturnElementsType here
4891
- const others = names.filter(([, { isLet, implicitChildren }]) => !isLet || !!implicitChildren);
4869
+ let result = this.$props.comment + '({})';
4870
+ // Try our best to incorporate __sveltets_2_Bindings here
4892
4871
  let idx = this.$props.comment.indexOf('@type');
4893
- if (idx !== -1 && /[\s{]/.test(this.$props.comment[idx + 5]) && others.length > 0) {
4872
+ if (idx !== -1 && /[\s{]/.test(this.$props.comment[idx + 5])) {
4894
4873
  idx = this.$props.comment.indexOf('{', idx);
4895
- if (idx !== -1) {
4896
- idx++;
4897
- return (this.$props.comment.slice(0, idx) +
4898
- `{${this.createReturnElementsType(others, false)}} & ` +
4899
- this.$props.comment.slice(idx) +
4900
- '({})');
4874
+ const end = this.$props.comment.lastIndexOf('}');
4875
+ if (idx !== -1 && end !== -1 && idx < end) {
4876
+ const has_bindings = this.$props.bindings.length;
4877
+ if (has_bindings) {
4878
+ idx++;
4879
+ result =
4880
+ this.$props.comment.slice(0, idx) +
4881
+ (has_bindings ? '__sveltets_2_Bindings<' : '') +
4882
+ this.$props.comment.slice(idx, end) +
4883
+ (has_bindings
4884
+ ? `, ${this.$props.bindings.map((b) => `"${b}"`).join('|')}>`
4885
+ : '') +
4886
+ this.$props.comment.slice(end) +
4887
+ '({})';
4888
+ }
4901
4889
  }
4902
4890
  }
4903
- return this.$props.comment + '({})';
4891
+ return result;
4892
+ }
4893
+ if (this.usesRunes()) {
4894
+ // Necessary, because {} roughly equals to any
4895
+ return this.isTsFile
4896
+ ? '{} as Record<string, never>'
4897
+ : '/** @type {Record<string, never>} */ ({})';
4904
4898
  }
4905
4899
  if (this.uses$$Props) {
4906
4900
  const lets = names.filter(([, { isLet }]) => isLet);
@@ -4937,25 +4931,34 @@ class ExportedNames {
4937
4931
  const returnElementsType = this.createReturnElementsType(names);
4938
4932
  return `{${returnElements.join(' , ')}} as {${returnElementsType.join(', ')}}`;
4939
4933
  }
4934
+ /**
4935
+ * In runes mode, exports are no longer part of props because you cannot `bind:` to them,
4936
+ * which is why we need a separate return type for them.
4937
+ */
4938
+ createExportsStr() {
4939
+ const names = Array.from(this.exports.entries());
4940
+ const others = names.filter(([, { isLet }]) => !isLet);
4941
+ if (this.usesRunes() && others.length > 0) {
4942
+ if (this.isTsFile) {
4943
+ return (', exports: {} as any as { ' +
4944
+ this.createReturnElementsType(others, undefined, true).join(',') +
4945
+ ' }');
4946
+ }
4947
+ else {
4948
+ return `, exports: /** @type {${this.createReturnElementsType(others, false, true)}} */ ({})`;
4949
+ }
4950
+ }
4951
+ return '';
4952
+ }
4940
4953
  createReturnElements(names, dontAddTypeDef) {
4941
4954
  return names.map(([key, value]) => {
4942
- if (value.implicitChildren) {
4943
- return `children: ${value.implicitChildren === 'empty'
4944
- ? '__sveltets_2_snippet()'
4945
- : '$$implicit_children'}`;
4946
- }
4947
4955
  // Important to not use shorthand props for rename functionality
4948
4956
  return `${dontAddTypeDef && value.doc ? `\n${value.doc}` : ''}${value.identifierText || key}: ${key}`;
4949
4957
  });
4950
4958
  }
4951
- createReturnElementsType(names, addDoc = true) {
4959
+ createReturnElementsType(names, addDoc = true, forceRequired = false) {
4952
4960
  return names.map(([key, value]) => {
4953
- if (value.implicitChildren) {
4954
- return `children?: ${value.implicitChildren === 'empty'
4955
- ? `import('svelte').Snippet`
4956
- : 'typeof $$implicit_children'}`;
4957
- }
4958
- const identifier = `${value.doc && addDoc ? `\n${value.doc}` : ''}${value.identifierText || key}${value.required ? '' : '?'}`;
4961
+ const identifier = `${value.doc && addDoc ? `\n${value.doc}` : ''}${value.identifierText || key}${value.required || forceRequired ? '' : '?'}`;
4959
4962
  if (!value.type) {
4960
4963
  return `${identifier}: typeof ${key}`;
4961
4964
  }
@@ -4963,15 +4966,27 @@ class ExportedNames {
4963
4966
  });
4964
4967
  }
4965
4968
  createOptionalPropsArray() {
4966
- return Array.from(this.exports.entries())
4967
- .filter(([_, entry]) => !entry.required)
4968
- .map(([name, entry]) => `'${entry.identifierText || name}'`);
4969
+ if (this.usesRunes()) {
4970
+ return [];
4971
+ }
4972
+ else {
4973
+ return Array.from(this.exports.entries())
4974
+ .filter(([_, entry]) => !entry.required)
4975
+ .map(([name, entry]) => `'${entry.identifierText || name}'`);
4976
+ }
4969
4977
  }
4970
4978
  getExportsMap() {
4971
4979
  return this.exports;
4972
4980
  }
4973
- usesChildrenIn$propsRune() {
4974
- return this.$props.mayHaveChildrenProp;
4981
+ hasPropsRune() {
4982
+ return this.$props.type || this.$props.comment;
4983
+ }
4984
+ checkGlobalsForRunes(globals) {
4985
+ const runes = ['$state', '$derived', '$effect']; // no need to check for props, already handled through other means in here
4986
+ this.hasRunesGlobals = globals.some((global) => runes.includes(global));
4987
+ }
4988
+ usesRunes() {
4989
+ return this.hasRunesGlobals || this.hasPropsRune();
4975
4990
  }
4976
4991
  }
4977
4992
 
@@ -5107,7 +5122,7 @@ function handleScopeAndResolveLetVarForSlot({ letNode, component, slotName, temp
5107
5122
  /**
5108
5123
  * Tracks all store-usages as well as all variable declarations and imports in the component.
5109
5124
  *
5110
- * In the modification-step at the end, all variable declartaions and imports which
5125
+ * In the modification-step at the end, all variable declarations and imports which
5111
5126
  * were used as stores are appended with `let $xx = __sveltets_2_store_get(xx)` to create the store variables.
5112
5127
  */
5113
5128
  class ImplicitStoreValues {
@@ -5136,6 +5151,13 @@ class ImplicitStoreValues {
5136
5151
  getAccessedStores() {
5137
5152
  return [...this.accessedStores.keys()];
5138
5153
  }
5154
+ getGlobals() {
5155
+ const globals = new Set(this.accessedStores);
5156
+ this.variableDeclarations.forEach((node) => extractIdentifiers(node.name).forEach((id) => globals.delete(id.text)));
5157
+ this.reactiveDeclarations.forEach((node) => getNamesFromLabeledStatement(node).forEach((name) => globals.delete(name)));
5158
+ this.importStatements.forEach(({ name }) => name && globals.delete(name.getText()));
5159
+ return [...globals].map((name) => `$${name}`);
5160
+ }
5139
5161
  attachStoreValueDeclarationToDecl(node, astOffset, str) {
5140
5162
  const storeNames = extractIdentifiers(node.name)
5141
5163
  .map((id) => id.text)
@@ -6259,13 +6281,22 @@ class __sveltets_Render${genericsDef} {
6259
6281
  const [PropsName] = addTypeExport(str, className, 'Props');
6260
6282
  const [EventsName] = addTypeExport(str, className, 'Events');
6261
6283
  const [SlotsName] = addTypeExport(str, className, 'Slots');
6284
+ /**
6285
+ * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6286
+ * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6287
+ */
6288
+ let customConstructor = '';
6289
+ if (exportedNames.hasPropsRune()) {
6290
+ customConstructor = `\n constructor(options: import('svelte').ComponentConstructorOptions<__sveltets_2_PropsWithChildren<${returnType('props')}, ${returnType('slots')}>>) { super(options); }`;
6291
+ }
6262
6292
  if (mode === 'dts') {
6263
6293
  statement +=
6264
6294
  `export type ${PropsName}${genericsDef} = ${returnType('props')};\n` +
6265
6295
  `export type ${EventsName}${genericsDef} = ${returnType('events')};\n` +
6266
6296
  `export type ${SlotsName}${genericsDef} = ${returnType('slots')};\n` +
6267
6297
  `\n${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends ${svelteComponentClass}<${PropsName}${genericsRef}, ${EventsName}${genericsRef}, ${SlotsName}${genericsRef}> {` +
6268
- exportedNames.createClassGetters() +
6298
+ customConstructor +
6299
+ exportedNames.createClassGetters(genericsRef) +
6269
6300
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6270
6301
  '\n}';
6271
6302
  }
@@ -6273,7 +6304,8 @@ class __sveltets_Render${genericsDef} {
6273
6304
  statement +=
6274
6305
  `\n\nimport { ${svelteComponentClass} as __SvelteComponentTyped__ } from "svelte" \n` +
6275
6306
  `${doc}export default class${className ? ` ${className}` : ''}${genericsDef} extends __SvelteComponentTyped__<${returnType('props')}, ${returnType('events')}, ${returnType('slots')}> {` +
6276
- exportedNames.createClassGetters() +
6307
+ customConstructor +
6308
+ exportedNames.createClassGetters(genericsRef) +
6277
6309
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6278
6310
  '\n}';
6279
6311
  }
@@ -6283,6 +6315,14 @@ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, expo
6283
6315
  const propDef = props(isTsFile, canHaveAnyProp, exportedNames, events(strictEvents, 'render()'));
6284
6316
  const doc = componentDocumentation.getFormatted();
6285
6317
  const className = fileName && classNameFromFilename(fileName, mode !== 'dts');
6318
+ /**
6319
+ * In Svelte 5 runes mode we add a custom constructor to override the default one which implicitly makes all properties bindable.
6320
+ * Remove this once Svelte typings no longer do that (Svelte 6 or 7)
6321
+ */
6322
+ let customConstructor = '';
6323
+ if (exportedNames.hasPropsRune()) {
6324
+ customConstructor = `\n constructor(options = __sveltets_2_runes_constructor(${propDef})) { super(options); }`;
6325
+ }
6286
6326
  let statement;
6287
6327
  if (mode === 'dts' && isTsFile) {
6288
6328
  const svelteComponentClass = noSvelteComponentTyped
@@ -6297,6 +6337,7 @@ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, expo
6297
6337
  EventsExport +
6298
6338
  SlotsExport +
6299
6339
  `\n${doc}export default class${className ? ` ${className}` : ''} extends ${svelteComponentClass}<${PropsName}, ${EventsName}, ${SlotsName}> {` +
6340
+ customConstructor +
6300
6341
  exportedNames.createClassGetters() +
6301
6342
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6302
6343
  '\n}';
@@ -6308,6 +6349,7 @@ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, expo
6308
6349
  `/** @typedef {typeof __propDef.events} ${className}Events */\n` +
6309
6350
  `/** @typedef {typeof __propDef.slots} ${className}Slots */\n` +
6310
6351
  `\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6352
+ customConstructor +
6311
6353
  exportedNames.createClassGetters() +
6312
6354
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6313
6355
  '\n}';
@@ -6315,6 +6357,7 @@ function addSimpleComponentExport({ strictEvents, isTsFile, canHaveAnyProp, expo
6315
6357
  else {
6316
6358
  statement =
6317
6359
  `\n\n${doc}export default class${className ? ` ${className}` : ''} extends __sveltets_2_createSvelte2TsxComponent(${propDef}) {` +
6360
+ customConstructor +
6318
6361
  exportedNames.createClassGetters() +
6319
6362
  (usesAccessors ? exportedNames.createClassAccessors() : '') +
6320
6363
  '\n}';
@@ -6395,7 +6438,7 @@ function classNameFromFilename(filename, appendSuffix) {
6395
6438
  }
6396
6439
  }
6397
6440
 
6398
- function createRenderFunction({ str, scriptTag, scriptDestination, rootSnippets, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, svelte5Plus, mode }) {
6441
+ function createRenderFunction({ str, scriptTag, scriptDestination, rootSnippets, slots, events, exportedNames, uses$$props, uses$$restProps, uses$$slots, uses$$SlotsInterface, generics, mode }) {
6399
6442
  const htmlx = str.original;
6400
6443
  let propsDecl = '';
6401
6444
  if (uses$$props) {
@@ -6457,17 +6500,8 @@ function createRenderFunction({ str, scriptTag, scriptDestination, rootSnippets,
6457
6500
  })
6458
6501
  .join(', ') +
6459
6502
  '}';
6460
- const needsImplicitChildrenProp = svelte5Plus &&
6461
- !exportedNames.usesChildrenIn$propsRune() &&
6462
- slots.has('default') &&
6463
- !exportedNames.getExportsMap().has('default');
6464
- if (needsImplicitChildrenProp) {
6465
- exportedNames.addImplicitChildrenExport(slots.get('default').size > 0);
6466
- }
6467
- const returnString = `${needsImplicitChildrenProp && slots.get('default').size > 0
6468
- ? `\nlet $$implicit_children = __sveltets_2_snippet({${slotAttributesToString(slots.get('default'))}});`
6469
- : ''}` +
6470
- `\nreturn { props: ${exportedNames.createPropsStr(uses$$props || uses$$restProps)}` +
6503
+ const returnString = `\nreturn { props: ${exportedNames.createPropsStr(uses$$props || uses$$restProps)}` +
6504
+ exportedNames.createExportsStr() +
6471
6505
  `, slots: ${slotsAsDef}` +
6472
6506
  `, events: ${events.toDefString()} }}`;
6473
6507
  // wrap template with callback
@@ -6738,6 +6772,9 @@ function svelte2tsx(svelte, options = { parse: compiler.parse }) {
6738
6772
  uses$$slots = uses$$slots || res.uses$$slots;
6739
6773
  ({ exportedNames, events, generics, uses$$SlotsInterface } = res);
6740
6774
  }
6775
+ if (svelte5Plus) {
6776
+ exportedNames.checkGlobalsForRunes(implicitStoreValues.getGlobals());
6777
+ }
6741
6778
  //wrap the script tag and template content in a function returning the slot and exports
6742
6779
  createRenderFunction({
6743
6780
  str,