@swiftuijs/twill 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +8 -3
  2. package/bin/run.mjs +2 -2
  3. package/dist/branches.d.ts +7 -1
  4. package/dist/cli.js +7 -8
  5. package/dist/{compilation-cache-7SugqJ4n.js → compilation-cache-BrV71YKt.js} +2 -3
  6. package/dist/{compilation-cache-7SugqJ4n.js.map → compilation-cache-BrV71YKt.js.map} +1 -1
  7. package/dist/{compiler-CbNSBUI2.js → compiler-DI0H4d1R.js} +178 -66
  8. package/dist/compiler-DI0H4d1R.js.map +1 -0
  9. package/dist/compiler.d.ts +2 -0
  10. package/dist/config-la_KkjCS.js +1 -0
  11. package/dist/config.js +2 -2
  12. package/dist/{configuration-BVMf6Q_j.js → configuration-ppqhmuy4.js} +7 -5
  13. package/dist/configuration-ppqhmuy4.js.map +1 -0
  14. package/dist/configuration.d.ts +1 -1
  15. package/dist/declarations-DXtb1AHP.js +131 -0
  16. package/dist/declarations-DXtb1AHP.js.map +1 -0
  17. package/dist/declarations.js +1 -132
  18. package/dist/doctor-BHwU_YBw.js +200 -0
  19. package/dist/doctor-BHwU_YBw.js.map +1 -0
  20. package/dist/doctor.js +1 -202
  21. package/dist/editor.d.ts +1 -0
  22. package/dist/editor.js +31 -5
  23. package/dist/editor.js.map +1 -1
  24. package/dist/esbuild.js +2 -3
  25. package/dist/{extensions-B1xTkoYP.js → extensions-7ixttcoK.js} +2 -3
  26. package/dist/{extensions-B1xTkoYP.js.map → extensions-7ixttcoK.js.map} +1 -1
  27. package/dist/{files-BW9geU0_.js → files-CgwJJ992.js} +3 -4
  28. package/dist/{files-BW9geU0_.js.map → files-CgwJJ992.js.map} +1 -1
  29. package/dist/index.js +2 -2
  30. package/dist/{loader-compiler-D1teTrXw.js → loader-compiler.js} +4 -5
  31. package/dist/loader-compiler.js.map +1 -0
  32. package/dist/loader-registration-BO43rvVU.js +14 -0
  33. package/dist/loader-registration-BO43rvVU.js.map +1 -0
  34. package/dist/loader-registration.d.ts +4 -0
  35. package/dist/loader-registration.js +1 -0
  36. package/dist/loader-state-DB7sONR_.js +60 -0
  37. package/dist/loader-state-DB7sONR_.js.map +1 -0
  38. package/dist/loader-state.d.ts +34 -0
  39. package/dist/loader-sync.d.ts +3 -0
  40. package/dist/loader-sync.js +27 -0
  41. package/dist/loader-sync.js.map +1 -0
  42. package/dist/loader.d.ts +2 -4
  43. package/dist/loader.js +10 -48
  44. package/dist/loader.js.map +1 -1
  45. package/dist/{plugin-BHfiQ2L-.js → plugin-DDOHhv7Z.js} +6 -7
  46. package/dist/{plugin-BHfiQ2L-.js.map → plugin-DDOHhv7Z.js.map} +1 -1
  47. package/dist/project-DYXf2Kgt.js +442 -0
  48. package/dist/project-DYXf2Kgt.js.map +1 -0
  49. package/dist/project.js +2 -443
  50. package/dist/register.js +3 -4
  51. package/dist/register.js.map +1 -1
  52. package/dist/rollup.js +2 -3
  53. package/dist/rspack.js +2 -3
  54. package/dist/syntax.js +2 -3
  55. package/dist/{transpile-D8P8Lsbx.js → transpile--6CFGUm0.js} +3 -4
  56. package/dist/{transpile-D8P8Lsbx.js.map → transpile--6CFGUm0.js.map} +1 -1
  57. package/dist/typescript-plugin.cjs +252 -128
  58. package/dist/typescript-plugin.cjs.map +1 -1
  59. package/dist/vite-D0Ct4uy4.js +6 -0
  60. package/dist/vite-D0Ct4uy4.js.map +1 -0
  61. package/dist/vite-react.js +2 -3
  62. package/dist/vite.js +1 -7
  63. package/dist/webpack.js +2 -3
  64. package/package.json +3 -3
  65. package/schemas/twill.schema.json +6 -0
  66. package/dist/compiler-CbNSBUI2.js.map +0 -1
  67. package/dist/configuration-BVMf6Q_j.js.map +0 -1
  68. package/dist/declarations.js.map +0 -1
  69. package/dist/doctor.js.map +0 -1
  70. package/dist/loader-compiler-D1teTrXw.js.map +0 -1
  71. package/dist/project.js.map +0 -1
  72. package/dist/vite.js.map +0 -1
@@ -2,14 +2,14 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#region \0rolldown/runtime.js
5
+ // \0rolldown/runtime.js
6
6
  var __create = Object.create;
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
9
  var __getOwnPropNames = Object.getOwnPropertyNames;
10
10
  var __getProtoOf = Object.getPrototypeOf;
11
11
  var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
12
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod, mod.exports), cb = null), mod.exports);
13
13
  var __exportAll = (all, no_symbols) => {
14
14
  let target = {};
15
15
  for (var name in all) __defProp(target, name, {
@@ -33,13 +33,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  value: mod,
34
34
  enumerable: true
35
35
  }) : target, mod));
36
- //#endregion
37
36
  let node_fs = require("node:fs");
38
37
  let node_path = require("node:path");
39
38
  let typescript = require("typescript");
40
39
  typescript = __toESM(typescript, 1);
41
40
  let node_crypto = require("node:crypto");
42
- //#region ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
41
+ // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
43
42
  var comma = ",".charCodeAt(0);
44
43
  var semicolon = ";".charCodeAt(0);
45
44
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -223,8 +222,7 @@ function encode(decoded) {
223
222
  }
224
223
  return writer.flush();
225
224
  }
226
- //#endregion
227
- //#region ../../node_modules/.pnpm/magic-string@1.4.2/node_modules/magic-string/dist/index.mjs
225
+ // ../../node_modules/.pnpm/magic-string@1.4.2/node_modules/magic-string/dist/index.mjs
228
226
  var BitSet = class BitSet {
229
227
  constructor(arg) {
230
228
  this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
@@ -1658,8 +1656,7 @@ var MagicString = class MagicString {
1658
1656
  return this._replaceRegexp(searchValue, replacement);
1659
1657
  }
1660
1658
  };
1661
- //#endregion
1662
- //#region ../../node_modules/.pnpm/acorn@8.18.0/node_modules/acorn/dist/acorn.mjs
1659
+ // ../../node_modules/.pnpm/acorn@8.18.0/node_modules/acorn/dist/acorn.mjs
1663
1660
  var acorn_exports = /* @__PURE__ */ __exportAll({
1664
1661
  Node: () => Node,
1665
1662
  Parser: () => Parser,
@@ -6836,8 +6833,7 @@ function parseExpressionAt(input, pos, options) {
6836
6833
  function tokenizer(input, options) {
6837
6834
  return Parser.tokenizer(input, options);
6838
6835
  }
6839
- //#endregion
6840
- //#region ../../node_modules/.pnpm/acorn-typescript@1.4.13_acorn@8.18.0/node_modules/acorn-typescript/lib/index.mjs
6836
+ // ../../node_modules/.pnpm/acorn-typescript@1.4.13_acorn@8.18.0/node_modules/acorn-typescript/lib/index.mjs
6841
6837
  function a(t, e) {
6842
6838
  for (var s = 0; s < e.length; s++) {
6843
6839
  var i = e[s];
@@ -9204,8 +9200,7 @@ function D(e) {
9204
9200
  }(s);
9205
9201
  };
9206
9202
  }
9207
- //#endregion
9208
- //#region ../../node_modules/.pnpm/acorn-jsx@5.3.2_acorn@8.18.0/node_modules/acorn-jsx/xhtml.js
9203
+ // ../../node_modules/.pnpm/acorn-jsx@5.3.2_acorn@8.18.0/node_modules/acorn-jsx/xhtml.js
9209
9204
  var require_xhtml = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9210
9205
  module.exports = {
9211
9206
  quot: "\"",
@@ -9463,12 +9458,11 @@ var require_xhtml = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9463
9458
  diams: "♦"
9464
9459
  };
9465
9460
  }));
9466
- //#endregion
9467
- //#region ../../node_modules/.pnpm/acorn@8.18.0/node_modules/acorn/dist/acorn.js
9468
- var require_acorn = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9461
+ // ../../node_modules/.pnpm/acorn@8.18.0/node_modules/acorn/dist/acorn.js
9462
+ var require_acorn = /* @__PURE__ */ __commonJSMin(((exports, module, this$1) => {
9469
9463
  (function(global, factory) {
9470
9464
  typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.acorn = {}));
9471
- })(exports, (function(exports$2) {
9465
+ })(this$1, (function(exports) {
9472
9466
  "use strict";
9473
9467
  var astralIdentifierCodes = [
9474
9468
  509,
@@ -14602,32 +14596,31 @@ var require_acorn = /* @__PURE__ */ __commonJSMin(((exports, module) => {
14602
14596
  function tokenizer(input, options) {
14603
14597
  return Parser.tokenizer(input, options);
14604
14598
  }
14605
- exports$2.Node = Node;
14606
- exports$2.Parser = Parser;
14607
- exports$2.Position = Position;
14608
- exports$2.SourceLocation = SourceLocation;
14609
- exports$2.TokContext = TokContext;
14610
- exports$2.Token = Token;
14611
- exports$2.TokenType = TokenType;
14612
- exports$2.defaultOptions = defaultOptions;
14613
- exports$2.getLineInfo = getLineInfo;
14614
- exports$2.isIdentifierChar = isIdentifierChar;
14615
- exports$2.isIdentifierStart = isIdentifierStart;
14616
- exports$2.isNewLine = isNewLine;
14617
- exports$2.keywordTypes = keywords;
14618
- exports$2.lineBreak = lineBreak;
14619
- exports$2.lineBreakG = lineBreakG;
14620
- exports$2.nonASCIIwhitespace = nonASCIIwhitespace;
14621
- exports$2.parse = parse;
14622
- exports$2.parseExpressionAt = parseExpressionAt;
14623
- exports$2.tokContexts = types;
14624
- exports$2.tokTypes = types$1;
14625
- exports$2.tokenizer = tokenizer;
14626
- exports$2.version = version;
14599
+ exports.Node = Node;
14600
+ exports.Parser = Parser;
14601
+ exports.Position = Position;
14602
+ exports.SourceLocation = SourceLocation;
14603
+ exports.TokContext = TokContext;
14604
+ exports.Token = Token;
14605
+ exports.TokenType = TokenType;
14606
+ exports.defaultOptions = defaultOptions;
14607
+ exports.getLineInfo = getLineInfo;
14608
+ exports.isIdentifierChar = isIdentifierChar;
14609
+ exports.isIdentifierStart = isIdentifierStart;
14610
+ exports.isNewLine = isNewLine;
14611
+ exports.keywordTypes = keywords;
14612
+ exports.lineBreak = lineBreak;
14613
+ exports.lineBreakG = lineBreakG;
14614
+ exports.nonASCIIwhitespace = nonASCIIwhitespace;
14615
+ exports.parse = parse;
14616
+ exports.parseExpressionAt = parseExpressionAt;
14617
+ exports.tokContexts = types;
14618
+ exports.tokTypes = types$1;
14619
+ exports.tokenizer = tokenizer;
14620
+ exports.version = version;
14627
14621
  }));
14628
14622
  }));
14629
- //#endregion
14630
- //#region src/parser.js
14623
+ // src/parser.js
14631
14624
  var import_acorn_jsx = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
14632
14625
  var XHTMLEntities = require_xhtml();
14633
14626
  var hexNumber = /^[\da-fA-F]+$/;
@@ -14989,9 +14982,12 @@ function guardAt(input, offset, implicitMember = false) {
14989
14982
  const lexer = Parser.tokenizer(input.slice(offset), { ecmaVersion: "latest" });
14990
14983
  const stack = [];
14991
14984
  let first = true;
14985
+ let missingElse = false;
14986
+ let afterNonNull = false;
14992
14987
  try {
14993
14988
  for (;;) {
14994
- const label = lexer.getToken().type.label;
14989
+ const token = lexer.getToken();
14990
+ const label = token.type.label;
14995
14991
  if (first && [
14996
14992
  "=",
14997
14993
  ".",
@@ -15005,6 +15001,22 @@ function guardAt(input, offset, implicitMember = false) {
15005
15001
  "in",
15006
15002
  "instanceof"
15007
15003
  ].includes(label) && !(implicitMember && label === ".")) return false;
15004
+ if (first || afterNonNull) {
15005
+ missingElse = !/[\r\n\u2028\u2029]/.test(input.slice(offset, offset + token.start)) && (token.type === types$1.name && !["as", "satisfies"].includes(token.value) || [
15006
+ "const",
15007
+ "num",
15008
+ "string",
15009
+ "true",
15010
+ "false",
15011
+ "null",
15012
+ "this",
15013
+ "new",
15014
+ "typeof",
15015
+ "void",
15016
+ "delete"
15017
+ ].includes(label) || token.type === types$1.prefix && token.value === "~" || implicitMember && first && label === ".");
15018
+ afterNonNull = token.type === types$1.prefix && token.value === "!";
15019
+ }
15008
15020
  if (!stack.length && [
15009
15021
  "if",
15010
15022
  "for",
@@ -15015,15 +15027,12 @@ function guardAt(input, offset, implicitMember = false) {
15015
15027
  "throw",
15016
15028
  "var",
15017
15029
  "export"
15018
- ].includes(label)) return false;
15019
- if (!first && !stack.length && label === "const") return false;
15030
+ ].includes(label)) return missingElse ? "missingElse" : false;
15031
+ if (!first && !stack.length && label === "const") return missingElse ? "missingElse" : false;
15020
15032
  first = false;
15021
15033
  if (!stack.length && label === "else") return true;
15022
- if (!stack.length && [
15023
- "eof",
15024
- ";",
15025
- "}"
15026
- ].includes(label)) return false;
15034
+ if (label === "eof") return !stack.length && missingElse ? "missingElse" : false;
15035
+ if (!stack.length && [";", "}"].includes(label)) return missingElse ? "missingElse" : false;
15027
15036
  if ([
15028
15037
  "(",
15029
15038
  "[",
@@ -15260,7 +15269,9 @@ function parserFor(language) {
15260
15269
  node.cleanup = cleanup;
15261
15270
  return this.finishNode(node, "DeferStatement");
15262
15271
  }
15263
- if (!this.isContextual("guard") || !guardAt(this.input, this.end, !!this.implicitClosure)) {
15272
+ const guard = this.isContextual("guard") && guardAt(this.input, this.end, !!this.implicitClosure);
15273
+ if (guard === "missingElse") this.raise(this.start, "Missing 'else' in guard statement. Put 'else' before the failure block: 'guard condition else { return ...; }'.");
15274
+ if (!guard) {
15264
15275
  const statement = super.parseStatement(context, ...args);
15265
15276
  if (context && statement.type === "TwillEnumDeclaration") this.raise(statement.start, "An associated-value enum requires a block; add braces around this body.");
15266
15277
  return statement;
@@ -15269,6 +15280,7 @@ function parserFor(language) {
15269
15280
  node.singleStatement = !!context;
15270
15281
  this.next();
15271
15282
  node.binding = null;
15283
+ if (this.type === types$1._else) this.raise(this.start, "Guard needs a condition or 'const' binding before 'else'.");
15272
15284
  if (this.type === types$1._const) {
15273
15285
  if (context) this.raise(node.start, "A guard binding requires a block; add braces around this body.");
15274
15286
  const declaration = this.startNode();
@@ -15278,8 +15290,9 @@ function parserFor(language) {
15278
15290
  if (node.binding.declarations.length !== 1) this.raise(node.start, "guard const requires one binding declaration.");
15279
15291
  } else node.test = this.parseExpression();
15280
15292
  node.elseStart = this.start;
15281
- this.expect(types$1._else);
15282
- if (this.type !== types$1.braceL) this.unexpected();
15293
+ if (this.type !== types$1._else) this.raise(this.start, "Expected 'else' after the guard condition or binding.");
15294
+ this.next();
15295
+ if (this.type !== types$1.braceL) this.raise(this.start, "Guard 'else' must be followed by a block, for example 'else { return ...; }'.");
15283
15296
  node.failure = this.parseBlock();
15284
15297
  if (!exits(node.failure)) this.raise(node.failure.start, "Every guard else path must exit with return, throw, break or continue.");
15285
15298
  return this.finishNode(node, "GuardStatement");
@@ -15664,13 +15677,11 @@ function parse$1(source, language = "ts", sourceType = "module") {
15664
15677
  }))
15665
15678
  };
15666
15679
  }
15667
- //#endregion
15668
- //#region src/defer-helper.ts
15680
+ // src/defer-helper.ts
15669
15681
  function syncDeferBody(names) {
15670
15682
  return "\n let " + names.failed + " = false,\n " + names.failure + ";\n while (" + names.stack + "?.length) {\n const " + names.cleanup + " = " + names.stack + ".pop();\n if (" + names.cleanup + ") {\n try {\n " + names.cleanup + "();\n } catch (" + names.error + ") {\n " + names.failed + " = true;\n " + names.failure + " = " + names.error + ";\n }\n }\n }\n if (" + names.failed + ") throw " + names.failure + ";\n";
15671
15683
  }
15672
- //#endregion
15673
- //#region src/defer.ts
15684
+ // src/defer.ts
15674
15685
  var functions = /* @__PURE__ */ new Set([
15675
15686
  "FunctionDeclaration",
15676
15687
  "FunctionExpression",
@@ -15846,8 +15857,7 @@ function lowerDefers(source, ast, code, language, usedNames, contentStarts, comm
15846
15857
  code.prependLeft(start, `\nimport { runDefers as ${sharedHelper} } from '@swiftuijs/twill-runtime/helpers/v1';\n`);
15847
15858
  }
15848
15859
  }
15849
- //#endregion
15850
- //#region src/branches.ts
15860
+ // src/branches.ts
15851
15861
  function suspension(node) {
15852
15862
  if (["AwaitExpression", "YieldExpression"].includes(node.type)) return node;
15853
15863
  if ([
@@ -15867,10 +15877,53 @@ function suspension(node) {
15867
15877
  }
15868
15878
  }
15869
15879
  }
15880
+ function directEval(node) {
15881
+ if ([
15882
+ "FunctionDeclaration",
15883
+ "FunctionExpression",
15884
+ "ArrowFunctionExpression"
15885
+ ].includes(node.type)) return false;
15886
+ if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "eval" && !node.optional) return true;
15887
+ return Object.entries(node).some(([key, value]) => ![
15888
+ "loc",
15889
+ "trailing",
15890
+ "tag"
15891
+ ].includes(key) && (Array.isArray(value) ? value : [value]).some((child) => child?.type && directEval(child)));
15892
+ }
15893
+ /** Preserve the existing expression boundary for direct eval and suspension. */
15894
+ function canInlineSwitchExpression(node) {
15895
+ return !directEval(node) && !suspension(node);
15896
+ }
15897
+ /** Reuse authored blocks only when no direct eval (including a captured one)
15898
+ * can observe the added temporary's broader lifetime/temporal dead zone.
15899
+ * Memoize shared parser nodes so this analysis stays linear in the AST size. */
15900
+ function reusableStatements(ast, usedNames) {
15901
+ const reusable = /* @__PURE__ */ new Set();
15902
+ const observed = /* @__PURE__ */ new Map();
15903
+ const visit = (node) => {
15904
+ const known = observed.get(node);
15905
+ if (known !== void 0) return known;
15906
+ if (node.type === "Identifier" || node.type === "JSXIdentifier") usedNames.add(node.name);
15907
+ let observable = node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "eval";
15908
+ for (const [key, value] of Object.entries(node)) {
15909
+ if (["loc", "trailing"].includes(key)) continue;
15910
+ for (const child of Array.isArray(value) ? value : [value]) if (child?.type && visit(child)) observable = true;
15911
+ }
15912
+ if (!observable && node.type === "BlockStatement") {
15913
+ for (const statement of node.body) if (statement.type === "TwillIfBinding" || (statement.argument ?? statement.expression)?.type === "TwillSwitchExpression") reusable.add(statement);
15914
+ }
15915
+ observed.set(node, observable);
15916
+ return observable;
15917
+ };
15918
+ visit(ast);
15919
+ return reusable;
15920
+ }
15870
15921
  /** Native switches with per-arm scopes. Direct returns and standalone variable
15871
15922
  * initializers need no extra function; other expressions keep a lexical IIFE. */
15872
- function lowerSwitchExpressions(source, ast, switches, code, language, usedNames, comments, fail) {
15923
+ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames, comments, fail, implicitReturns = [], reusable = /* @__PURE__ */ new Set()) {
15873
15924
  const returns = /* @__PURE__ */ new Set();
15925
+ const implicit = new Set(implicitReturns);
15926
+ const sharedScopes = /* @__PURE__ */ new Set();
15874
15927
  const initializers = /* @__PURE__ */ new Map();
15875
15928
  const leadingDoc = (start) => {
15876
15929
  let low = 0, high = comments.length;
@@ -15882,19 +15935,6 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
15882
15935
  const comment = comments[low - 1];
15883
15936
  return comment && /^\s*$/.test(source.slice(comment.end, start)) ? comment : void 0;
15884
15937
  };
15885
- const directEval = (node) => {
15886
- if ([
15887
- "FunctionDeclaration",
15888
- "FunctionExpression",
15889
- "ArrowFunctionExpression"
15890
- ].includes(node.type)) return false;
15891
- if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "eval" && !node.optional) return true;
15892
- return Object.entries(node).some(([key, value]) => ![
15893
- "loc",
15894
- "trailing",
15895
- "tag"
15896
- ].includes(key) && (Array.isArray(value) ? value : [value]).some((child) => child?.type && directEval(child)));
15897
- };
15898
15938
  const grouping = (start, end, initializer = false) => {
15899
15939
  const parentheses = [];
15900
15940
  const tokens = Parser.tokenizer(source.slice(start, end), { ecmaVersion: "latest" });
@@ -15907,6 +15947,15 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
15907
15947
  for (const token of parentheses) code.remove(start + token.start, start + token.end);
15908
15948
  };
15909
15949
  const visit = (node, parent) => {
15950
+ if (node.type === "BlockStatement") for (const statement of node.body) {
15951
+ const value = statement.type === "ReturnStatement" ? statement.argument : statement.expression;
15952
+ if (value?.type === "TwillSwitchExpression" && (node.body.length === 1 || reusable.has(statement)) && (statement.type === "ReturnStatement" || implicit.has(value))) sharedScopes.add(value);
15953
+ }
15954
+ if (node.type === "ExpressionStatement" && implicit.has(node.expression)) {
15955
+ grouping(node.start, node.expression.start);
15956
+ grouping(node.expression.end, node.end);
15957
+ if (source[node.end - 1] === ";") code.remove(node.end - 1, node.end);
15958
+ }
15910
15959
  if (node.type === "VariableDeclaration" && node.declarations.length === 1) {
15911
15960
  const declaration = node.declarations[0];
15912
15961
  if (declaration.id.type === "Identifier" && declaration.init?.type === "TwillSwitchExpression" && [
@@ -15928,6 +15977,7 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
15928
15977
  if (node.type === "ReturnStatement" && node.argument?.type === "TwillSwitchExpression") {
15929
15978
  returns.add(node.argument);
15930
15979
  code.remove(node.start, node.start + 6);
15980
+ if (source[node.end - 1] === ";") code.remove(node.end - 1, node.end);
15931
15981
  for (const [start, end] of [[node.start + 6, node.argument.start], [node.argument.end, node.end]]) grouping(start, end);
15932
15982
  }
15933
15983
  for (const [key, value] of Object.entries(node)) {
@@ -15950,8 +16000,8 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
15950
16000
  return name;
15951
16001
  };
15952
16002
  for (const node of switches) {
15953
- const direct = returns.has(node);
15954
- const suspended = !direct && suspension(node);
16003
+ const direct = returns.has(node) || implicit.has(node);
16004
+ const suspended = !returns.has(node) && suspension(node);
15955
16005
  if (suspended) fail(suspended, `await/yield inside a ${node.keyword} expression requires a direct return. Bind the subject first, or await the whole result explicitly.`);
15956
16006
  const initializer = initializers.get(node);
15957
16007
  const result = initializer ? fresh("Result") : void 0;
@@ -15970,7 +16020,10 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
15970
16020
  const valuePrefix = result ? `${result} = (` : "return ";
15971
16021
  const valueSuffix = result ? `); break ${exit};` : ";";
15972
16022
  const kind = node.cases.some((branch) => branch.enumPattern) ? fresh("Kind") : void 0;
15973
- if (!initializer) code.appendLeft(node.start, `${direct ? "{" : "(() => {"}const ${subject} = `);
16023
+ if (!initializer) {
16024
+ const opening = direct ? sharedScopes.has(node) ? "" : "{" : "(() => {";
16025
+ code.appendLeft(node.start, `${opening}const ${subject} = `);
16026
+ }
15974
16027
  code.remove(node.parenStart, node.parenStart + 1);
15975
16028
  if (node.keyword === "match") {
15976
16029
  const tokens = Parser.tokenizer(source.slice(node.discriminant.end, node.parenEnd), { ecmaVersion: "latest" });
@@ -16027,13 +16080,13 @@ function lowerSwitchExpressions(source, ast, switches, code, language, usedNames
16027
16080
  }
16028
16081
  }
16029
16082
  const hasDefault = node.cases.some((branch) => !branch.pattern && !branch.enumPattern && branch.test === null);
16030
- const check = !hasDefault && language.startsWith("ts") ? ` ${kind ? `(0 as unknown as typeof ${kind})` : subject} satisfies never;` : "";
16031
- const failure = hasDefault ? "" : `${check} throw new TypeError('Non-exhaustive switch expression');`;
16032
- code.overwrite(node.end - 1, node.end, `}${failure}${direct || initializer ? "}" : "})()"}`, { contentOnly: true });
16083
+ const check = !hasDefault && language.startsWith("ts") ? fresh("Check") : void 0;
16084
+ const failure = hasDefault ? "" : `${check ? ` type ${check}<T extends never = typeof ${kind ?? subject}> = T & never;` : ""} throw new TypeError('Non-exhaustive switch expression'${check ? ` as ${check}` : ""});`;
16085
+ const closing = initializer || direct && !sharedScopes.has(node) ? "}" : direct ? "" : "})()";
16086
+ code.overwrite(node.end - 1, node.end, `}${failure}${closing}`, { contentOnly: true });
16033
16087
  }
16034
16088
  }
16035
- //#endregion
16036
- //#region ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
16089
+ // ../../node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
16037
16090
  var schemeRegex = /^[\w+.-]+:\/\//;
16038
16091
  /**
16039
16092
  * Matches the parts of a URL:
@@ -16196,8 +16249,7 @@ function resolve$4(input, base) {
16196
16249
  default: return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
16197
16250
  }
16198
16251
  }
16199
- //#endregion
16200
- //#region ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
16252
+ // ../../node_modules/.pnpm/@jridgewell+trace-mapping@0.3.31/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs
16201
16253
  function stripFilename(path) {
16202
16254
  if (!path) return "";
16203
16255
  const index = path.lastIndexOf("/");
@@ -16435,8 +16487,7 @@ function generatedPosition$1(map, source, line, column, bias, all) {
16435
16487
  const segment = segments[index];
16436
16488
  return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]);
16437
16489
  }
16438
- //#endregion
16439
- //#region src/enums.ts
16490
+ // src/enums.ts
16440
16491
  /** Find free type references, respecting generic function/mapped/infer binders. */
16441
16492
  function references(node, names, found = /* @__PURE__ */ new Set(), bound = /* @__PURE__ */ new Set()) {
16442
16493
  const local = new Set(bound);
@@ -16615,14 +16666,12 @@ function mapEnumCopies(source, generated, map, insertions) {
16615
16666
  }));
16616
16667
  return copies;
16617
16668
  }
16618
- //#endregion
16619
- //#region src/extensions.ts
16669
+ // src/extensions.ts
16620
16670
  var extensions = [".twill", ".twillx"];
16621
16671
  function isTwillFile(id) {
16622
16672
  return extensions.some((extension) => id.split(/[?#]/, 1)[0].endsWith(extension));
16623
16673
  }
16624
- //#endregion
16625
- //#region src/compiler.ts
16674
+ // src/compiler.ts
16626
16675
  function inferLanguage(filename) {
16627
16676
  if (/\.(?:twillx|tsx)$/.test(filename)) return "tsx";
16628
16677
  if (/\.jsx$/.test(filename)) return "jsx";
@@ -16647,6 +16696,25 @@ var TwillSyntaxError = class extends SyntaxError {
16647
16696
  this.frame = `${source.split(/\r\n|[\r\n\u2028\u2029]/)[line - 1] ?? ""}\n${" ".repeat(column)}^`;
16648
16697
  }
16649
16698
  };
16699
+ function closureExpression(body) {
16700
+ if (body.length !== 1) return;
16701
+ return body[0].type === "ReturnStatement" ? body[0].argument : body[0].expression;
16702
+ }
16703
+ function conciseExpression(body) {
16704
+ const expression = closureExpression(body);
16705
+ return !!expression && (expression.type !== "TwillSwitchExpression" || !canInlineSwitchExpression(expression));
16706
+ }
16707
+ function expressionGrouping(expression, source, start) {
16708
+ while ([
16709
+ "TSAsExpression",
16710
+ "TSSatisfiesExpression",
16711
+ "TSNonNullExpression"
16712
+ ].includes(expression.type)) expression = expression.expression;
16713
+ if (!["ObjectExpression", "SequenceExpression"].includes(expression.type)) return "";
16714
+ const tokens = Parser.tokenizer(source.slice(start, expression.start), { ecmaVersion: "latest" });
16715
+ for (let token = tokens.getToken(); token.type !== types$1.eof; token = tokens.getToken()) if (token.type === types$1.parenL) return "";
16716
+ return "(";
16717
+ }
16650
16718
  function walk(node, visit) {
16651
16719
  visit(node);
16652
16720
  for (const key of Object.keys(node)) {
@@ -16676,7 +16744,9 @@ function transform(source, options = {}) {
16676
16744
  const code = new MagicString(source);
16677
16745
  const enumInsertions = parsed.enums.length ? lowerEnums(source, parsed.ast, parsed.enums, code) : [];
16678
16746
  const usedNames = /* @__PURE__ */ new Set();
16679
- if (parsed.guards.filter((guard) => guard.binding && guard.binding.declarations[0].id.type !== "Identifier").length || parsed.ifBindings.length || parsed.switches.length || parsed.defers.length || parsed.closures.some((closure) => closure.implicitMembers.length) || /\.twillx$/.test(filename.split(/[?#]/, 1)[0])) walk(parsed.ast, (node) => {
16747
+ const reusable = parsed.ifBindings.length || parsed.switches.length ? reusableStatements(parsed.ast, usedNames) : /* @__PURE__ */ new Set();
16748
+ const patternGuards = parsed.guards.filter((guard) => guard.binding && guard.binding.declarations[0].id.type !== "Identifier");
16749
+ if (!parsed.ifBindings.length && !parsed.switches.length && (patternGuards.length || parsed.defers.length || parsed.closures.some((closure) => closure.implicitMembers.length) || /\.twillx$/.test(filename.split(/[?#]/, 1)[0]))) walk(parsed.ast, (node) => {
16680
16750
  if (node.type === "Identifier" || node.type === "JSXIdentifier") usedNames.add(node.name);
16681
16751
  });
16682
16752
  let guardCounter = 0;
@@ -16689,12 +16759,13 @@ function transform(source, options = {}) {
16689
16759
  while (usedNames.has(temporary));
16690
16760
  usedNames.add(temporary);
16691
16761
  const patternEnd = binding.typeAnnotation?.start ?? binding.end;
16692
- code.overwrite(statement.start, binding.start, `{const ${temporary}`);
16762
+ const reuseScope = reusable.has(statement);
16763
+ code.overwrite(statement.start, binding.start, `${reuseScope ? "" : "{"}const ${temporary}`);
16693
16764
  code.move(binding.start, patternEnd, statement.consequent.start + 1);
16694
16765
  code.prependRight(binding.start, "const ");
16695
16766
  code.appendLeft(patternEnd, ` = ${temporary};`);
16696
16767
  code.prependLeft(statement.consequent.start, `; if (${temporary} !== null && ${temporary} !== void 0) `);
16697
- code.appendLeft(statement.end, "}");
16768
+ if (!reuseScope) code.appendLeft(statement.end, "}");
16698
16769
  }
16699
16770
  for (const guard of parsed.guards) {
16700
16771
  if (guard.singleStatement) {
@@ -16703,22 +16774,24 @@ function transform(source, options = {}) {
16703
16774
  }
16704
16775
  if (guard.binding) {
16705
16776
  const binding = guard.binding.declarations[0].id;
16706
- if (binding.type === "Identifier") code.remove(guard.start, guard.start + 5);
16707
- else {
16777
+ let name;
16778
+ if (binding.type === "Identifier") {
16779
+ name = binding.name;
16780
+ code.remove(guard.start, guard.start + 5);
16781
+ } else {
16708
16782
  let temporary;
16709
16783
  do
16710
16784
  temporary = `__twillGuard${guardCounter++}`;
16711
16785
  while (usedNames.has(temporary));
16712
16786
  usedNames.add(temporary);
16787
+ name = temporary;
16713
16788
  const patternEnd = binding.typeAnnotation?.start ?? binding.end;
16714
16789
  code.overwrite(guard.start, binding.start, `const ${temporary}`);
16715
16790
  code.move(binding.start, patternEnd, guard.end);
16716
16791
  code.prependRight(binding.start, "; const ");
16717
16792
  code.appendLeft(patternEnd, ` = ${temporary};`);
16718
- code.overwrite(guard.elseStart, guard.elseStart + 4, `; if (${temporary} == null)`);
16719
- continue;
16720
16793
  }
16721
- code.overwrite(guard.elseStart, guard.elseStart + 4, `; if (${binding.name} == null)`);
16794
+ code.overwrite(guard.elseStart, guard.elseStart + 4, `; if (${name} === null || ${name} === void 0)`);
16722
16795
  } else {
16723
16796
  code.overwrite(guard.start, guard.start + 5, "if (!(");
16724
16797
  code.overwrite(guard.elseStart, guard.elseStart + 4, "))");
@@ -16749,7 +16822,9 @@ function transform(source, options = {}) {
16749
16822
  name = `__twillArg${implicitCounter++}`;
16750
16823
  while (usedNames.has(name));
16751
16824
  usedNames.add(name);
16752
- code.overwrite(metadata.node.start, metadata.node.start + 1, `(${name}) => {`);
16825
+ const body = metadata.node.body.body;
16826
+ const opening = (options.implicitReturn !== false || body[0]?.type === "ReturnStatement") && conciseExpression(body) ? expressionGrouping(closureExpression(body), source, metadata.header?.end ?? metadata.node.start + 1) : "{";
16827
+ code.overwrite(metadata.node.start, metadata.node.start + 1, `(${name}) => ${opening}`);
16753
16828
  for (const offset of metadata.implicitMembers) code.appendLeft(offset, name);
16754
16829
  }
16755
16830
  const pragma = [...parsed.comments.filter((comment) => comment.start < (parsed.ast.body[0]?.start ?? source.length)).map((comment) => comment.value).join("\n").matchAll(/@jsxImportSource\s+(\S+)/g)].at(-1)?.[1];
@@ -16777,9 +16852,13 @@ function transform(source, options = {}) {
16777
16852
  return edits.toString();
16778
16853
  };
16779
16854
  let counter = 0;
16855
+ const directReturns = [];
16780
16856
  for (const node of parsed.calls) {
16781
16857
  const { callEnd, hadParens, originalArgs, closures } = node.trailing;
16782
16858
  const component = componentCalls.has(node);
16859
+ const slotObject = vue && (options.vueDefaultSlot !== "function" || closures.length > 1);
16860
+ let nativeChild = false;
16861
+ let bareChild = false;
16783
16862
  if (component) {
16784
16863
  if (originalArgs.length > 1 || originalArgs[0]?.type === "SpreadElement" || node.optional || node.callee.optional) throw new TwillSyntaxError(source, filename, {
16785
16864
  message: "Component syntax accepts one props object and children; optional calls use ordinary callbacks.",
@@ -16804,8 +16883,13 @@ function transform(source, options = {}) {
16804
16883
  labels.add(name);
16805
16884
  }
16806
16885
  }
16807
- const opening = vue ? ">{({default: " : ">{(";
16808
16886
  const tagEnd = node.typeParameters?.end ?? node.callee.end;
16887
+ const child = closures[0];
16888
+ const expression = child.body.body[0]?.expression;
16889
+ nativeChild = !vue && !metadataByNode.get(child).header && child.body.body.length === 1 && (expression?.type === "JSXElement" || expression?.type === "JSXFragment") && source.slice(child.start + 1, expression.start).trim() === "" && /^\s*;?\s*$/.test(source.slice(expression.end, child.end - 1)) && source.slice(callEnd, child.start).trim() === "" && (!hadParens || originalArgs.length > 0 || /^\s*\(\s*\)$/.test(source.slice(tagEnd, callEnd)));
16890
+ bareChild = !vue && (!!metadataByNode.get(child).header || child.body.body.length === 1 && expression !== void 0 && expression.type !== "SequenceExpression");
16891
+ let opening = nativeChild ? ">" : bareChild ? ">{" : ">{(";
16892
+ if (vue) opening = slotObject ? ">{{default: " : ">{";
16809
16893
  code.appendLeft(node.callee.start, "(<");
16810
16894
  const props = originalArgs[0];
16811
16895
  if (!vue && props?.type === "ObjectExpression" && props.properties.every((property) => property.type === "SpreadElement" || property.kind === "init" && !property.method && !property.computed && (property.key.name ?? property.key.value) !== "__proto__" && /^[A-Za-z_$][\w$.:-]*$/.test(String(property.key.name ?? property.key.value)))) {
@@ -16852,7 +16936,7 @@ function transform(source, options = {}) {
16852
16936
  const tokens = Parser.tokenizer(gap, { ecmaVersion: "latest" });
16853
16937
  const first = tokens.getToken();
16854
16938
  const last = tokens.getToken();
16855
- code.overwrite(tagEnd, callEnd, opening + gap.slice(first.end, last.start));
16939
+ code.overwrite(tagEnd, callEnd, opening + (nativeChild ? "" : gap.slice(first.end, last.start)));
16856
16940
  } else code.appendLeft(callEnd, opening);
16857
16941
  } else if (hadParens) {
16858
16942
  const tailStart = originalArgs.at(-1)?.end ?? callEnd - 1;
@@ -16875,24 +16959,40 @@ function transform(source, options = {}) {
16875
16959
  "DeferStatement",
16876
16960
  "EmptyStatement"
16877
16961
  ].includes(statement.type)) && body.filter((statement) => statement.type !== "EmptyStatement").at(-1) === expressions[0];
16962
+ const explicitReturn = !content && body.length === 1 && body[0].type === "ReturnStatement" && body[0].argument;
16963
+ const returnsValue = explicitReturn || singleContent || options.implicitReturn !== false && body.length === 1 && body[0].type === "ExpressionStatement";
16964
+ const conciseBody = returnsValue && conciseExpression(body);
16965
+ const grouping = conciseBody ? expressionGrouping(closureExpression(body), source, metadata.header?.end ?? closure.start + 1) : "{";
16878
16966
  if (singleContent && body.length === 1 && !vue) {
16879
16967
  directChild = true;
16880
- code.remove(closure.start, closure.start + 1);
16881
- code.remove(closure.end - 1, closure.end);
16882
16968
  const statement = expressions[0];
16883
- if (source[statement.end - 1] === ";") code.remove(statement.end - 1, statement.end);
16969
+ if (nativeChild) {
16970
+ code.remove(callEnd, statement.expression.start);
16971
+ code.overwrite(statement.expression.end, closure.end, "", { contentOnly: true });
16972
+ } else {
16973
+ code.remove(closure.start, closure.start + 1);
16974
+ code.overwrite(closure.end - 1, closure.end, "", { contentOnly: true });
16975
+ if (source[statement.end - 1] === ";") code.remove(statement.end - 1, statement.end);
16976
+ }
16884
16977
  continue;
16885
16978
  }
16886
16979
  if (metadata.label) {
16887
16980
  const label = source.slice(metadata.label.start, metadata.label.end).replace(/\s*:\s*$/, "");
16888
- code.overwrite(metadata.label.start, closure.start, component && vue ? `, [${JSON.stringify(label)}]: ` : ", ");
16981
+ code.overwrite(metadata.label.start, closure.start, component && vue ? `, ${label === "__proto__" ? `[${JSON.stringify(label)}]` : JSON.stringify(label)}: ` : ", ");
16889
16982
  }
16890
16983
  if (metadata.header) {
16891
16984
  const header = metadata.header;
16892
16985
  code.overwrite(closure.start, closure.start + 1, header.parenthesized || metadata.async ? "" : "(");
16893
16986
  if (metadata.async && !header.parenthesized) code.appendLeft(header.asyncEnd, " (");
16894
- code.overwrite(header.inStart, header.end, `${header.parenthesized ? "" : ") "}=> {`);
16895
- } else if (!metadata.implicitMembers.length) code.overwrite(closure.start, closure.start + 1, "() => {");
16987
+ code.overwrite(header.inStart, header.end, `${header.parenthesized ? "" : ") "}=> ${grouping}`);
16988
+ } else if (!metadata.implicitMembers.length) code.overwrite(closure.start, closure.start + 1, `() => ${grouping}`);
16989
+ if (conciseBody) {
16990
+ const statement = body[0];
16991
+ if (explicitReturn) code.remove(statement.start, statement.start + 6);
16992
+ if (source[statement.end - 1] === ";") code.remove(statement.end - 1, statement.end);
16993
+ code.overwrite(closure.end - 1, closure.end, grouping ? ")" : "", { contentOnly: true });
16994
+ continue;
16995
+ }
16896
16996
  if (content && !singleContent) {
16897
16997
  let collector;
16898
16998
  do
@@ -16945,13 +17045,16 @@ function transform(source, options = {}) {
16945
17045
  body.forEach(collect);
16946
17046
  code.prependLeft(bodyStart, `const ${collector} = [];`);
16947
17047
  code.prependLeft(closure.end - 1, vue ? `;return ${collector};` : `;return ${collector}.length === 1 ? ${collector}[0] : ${collector};`);
16948
- } else if (singleContent || options.implicitReturn !== false && body.length === 1 && body[0].type === "ExpressionStatement") {
17048
+ } else if (returnsValue && !explicitReturn) {
16949
17049
  const statement = singleContent ? expressions[0] : body[0];
16950
- code.prependLeft(statement.start, "return (");
16951
- code.appendLeft(source[statement.end - 1] === ";" ? statement.end - 1 : statement.end, ")");
17050
+ if (statement.expression.type === "TwillSwitchExpression" && canInlineSwitchExpression(statement.expression)) directReturns.push(statement.expression);
17051
+ else {
17052
+ code.prependLeft(statement.start, "return (");
17053
+ code.appendLeft(source[statement.end - 1] === ";" ? statement.end - 1 : statement.end, ")");
17054
+ }
16952
17055
  }
16953
17056
  }
16954
- if (component) code.prependLeft(closures.at(-1).end, (vue ? "})}" : directChild || metadataByNode.get(closures[0]).header ? ")}" : ")()}") + `</${calleeName(node.callee)}>)`);
17057
+ if (component) code.prependLeft(closures.at(-1).end, (vue ? slotObject ? "}}" : "}" : nativeChild ? "" : bareChild ? "}" : directChild ? ")}" : ")()}") + `</${calleeName(node.callee)}>)`);
16955
17058
  else code.appendLeft(closures.at(-1).end, ")");
16956
17059
  }
16957
17060
  if (parsed.switches.length) lowerSwitchExpressions(source, parsed.ast, parsed.switches, code, options.language ?? inferLanguage(filename), usedNames, parsed.comments, (node, message) => {
@@ -16960,7 +17063,7 @@ function transform(source, options = {}) {
16960
17063
  pos: node.start,
16961
17064
  loc: node.loc.start
16962
17065
  });
16963
- });
17066
+ }, directReturns, reusable);
16964
17067
  for (const end of attributeClosings) code.appendLeft(end, "}");
16965
17068
  if (parsed.defers.length) {
16966
17069
  const starts = /* @__PURE__ */ new Map();
@@ -17019,8 +17122,7 @@ function generatedPosition(result, line, column) {
17019
17122
  bias: 1
17020
17123
  });
17021
17124
  }
17022
- //#endregion
17023
- //#region src/compilation-cache.ts
17125
+ // src/compilation-cache.ts
17024
17126
  var digest = (source) => (0, node_crypto.createHash)("sha256").update(source).digest("hex");
17025
17127
  function observe(path, kind) {
17026
17128
  try {
@@ -17030,8 +17132,7 @@ function observe(path, kind) {
17030
17132
  return ["ENOENT", "ENOTDIR"].includes(error.code ?? "") ? "absent" : "unavailable";
17031
17133
  }
17032
17134
  }
17033
- //#endregion
17034
- //#region src/configuration.ts
17135
+ // src/configuration.ts
17035
17136
  var jsxConfigs = /* @__PURE__ */ new Map();
17036
17137
  function record(observations, path, kind) {
17037
17138
  path = (0, node_path.resolve)(path);
@@ -17117,22 +17218,24 @@ function readConfig(root, configFile, observations) {
17117
17218
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${filename}: expected an object`);
17118
17219
  if (value.implicitReturn !== void 0 && typeof value.implicitReturn !== "boolean") throw new Error(`${filename}: implicitReturn must be a boolean`);
17119
17220
  if (value.runtime !== void 0 && !["inline", "external"].includes(value.runtime)) throw new Error(`${filename}: runtime must be inline or external`);
17221
+ if (value.vueDefaultSlot !== void 0 && !["object", "function"].includes(value.vueDefaultSlot)) throw new Error(`${filename}: vueDefaultSlot must be object or function`);
17120
17222
  for (const key of Object.keys(value)) if (![
17121
17223
  "implicitReturn",
17122
17224
  "runtime",
17225
+ "vueDefaultSlot",
17123
17226
  "$schema"
17124
17227
  ].includes(key)) throw new Error(`${filename}: unknown option ${key}`);
17125
17228
  return {
17126
17229
  implicitReturn: value.implicitReturn,
17127
17230
  jsxImportSource,
17128
- ...value.runtime === void 0 ? {} : { runtime: value.runtime }
17231
+ ...value.runtime === void 0 ? {} : { runtime: value.runtime },
17232
+ ...value.vueDefaultSlot === void 0 ? {} : { vueDefaultSlot: value.vueDefaultSlot }
17129
17233
  };
17130
17234
  }
17131
17235
  function loadConfig(root = process.cwd(), configFile) {
17132
17236
  return readConfig(root, configFile);
17133
17237
  }
17134
- //#endregion
17135
- //#region ../../node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs
17238
+ // ../../node_modules/.pnpm/@jridgewell+gen-mapping@0.3.13/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs
17136
17239
  var SetArray = class {
17137
17240
  constructor() {
17138
17241
  this._indexes = { __proto__: null };
@@ -17270,8 +17373,7 @@ function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIn
17270
17373
  if (prev.length === 1) return false;
17271
17374
  return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME);
17272
17375
  }
17273
- //#endregion
17274
- //#region ../../node_modules/.pnpm/@ampproject+remapping@2.3.0/node_modules/@ampproject/remapping/dist/remapping.mjs
17376
+ // ../../node_modules/.pnpm/@ampproject+remapping@2.3.0/node_modules/@ampproject/remapping/dist/remapping.mjs
17275
17377
  var SOURCELESS_MAPPING = /* #__PURE__ */ SegmentObject("", -1, -1, "", null, false);
17276
17378
  var EMPTY_SOURCES = [];
17277
17379
  function SegmentObject(source, line, column, name, content, ignore) {
@@ -17428,8 +17530,7 @@ function remapping(input, loader, options) {
17428
17530
  };
17429
17531
  return new SourceMap(traceMappings(buildSourceMapTree(input, loader)), opts);
17430
17532
  }
17431
- //#endregion
17432
- //#region src/recovery.ts
17533
+ // src/recovery.ts
17433
17534
  /** Editor-only recovery; build and CLI compilation always use strict parsing. */
17434
17535
  function recoverTransform(source, options, onSyntaxError) {
17435
17536
  const repaired = new MagicString(source);
@@ -17512,8 +17613,7 @@ function recoverTransform(source, options, onSyntaxError) {
17512
17613
  function isDependency(filename) {
17513
17614
  return /(?:^|[\\/])node_modules[\\/]/.test(filename);
17514
17615
  }
17515
- //#endregion
17516
- //#region src/project.ts
17616
+ // src/project.ts
17517
17617
  function lineStarts(text) {
17518
17618
  const starts = [0];
17519
17619
  const breaks = /\n/g;
@@ -17865,13 +17965,13 @@ var TwillProject = class {
17865
17965
  this.service.dispose();
17866
17966
  }
17867
17967
  };
17868
- //#endregion
17869
- //#region src/editor.ts
17968
+ // src/editor.ts
17870
17969
  /** Shared semantic requests and conservative source edits for both editor hosts. */
17871
17970
  var TwillEditor = class {
17872
17971
  project;
17873
17972
  attributeCache = /* @__PURE__ */ new WeakMap();
17874
17973
  descriptorCache = /* @__PURE__ */ new WeakMap();
17974
+ internalBindingCache = /* @__PURE__ */ new WeakMap();
17875
17975
  constructor(project) {
17876
17976
  this.project = project;
17877
17977
  }
@@ -17922,11 +18022,37 @@ var TwillEditor = class {
17922
18022
  }
17923
18023
  completions(filename, position, preferences = {}) {
17924
18024
  let { offset, props } = this.completionLocation(filename, position);
17925
- const info = this.project.service.getCompletionsAtPosition(virtualFilename(filename), offset, {
18025
+ let info = this.project.service.getCompletionsAtPosition(virtualFilename(filename), offset, {
17926
18026
  includeCompletionsForModuleExports: true,
17927
18027
  includeCompletionsWithInsertText: true,
17928
18028
  ...preferences
17929
18029
  });
18030
+ if (info && !info.isMemberCompletion && isTwillFile(sourceFilename(filename)) && this.project.transformed(filename)?.changed) {
18031
+ const file = this.sourceFile(filename);
18032
+ if (file) {
18033
+ let internal = this.internalBindingCache.get(file);
18034
+ if (!internal) {
18035
+ internal = /* @__PURE__ */ new Set();
18036
+ const visit = (node) => {
18037
+ if (typescript.default.isIdentifier(node) && node.text.startsWith("__twill")) {
18038
+ const parent = node.parent;
18039
+ if ((typescript.default.isVariableDeclaration(parent) || typescript.default.isBindingElement(parent) || typescript.default.isParameter(parent) || typescript.default.isTypeAliasDeclaration(parent) || typescript.default.isFunctionDeclaration(parent)) && parent.name === node && !this.mapSpan(filename, {
18040
+ start: node.getStart(),
18041
+ length: node.getWidth()
18042
+ })) internal.add(node.text);
18043
+ }
18044
+ typescript.default.forEachChild(node, visit);
18045
+ };
18046
+ visit(file);
18047
+ this.internalBindingCache.set(file, internal);
18048
+ }
18049
+ const hidden = internal;
18050
+ if (hidden.size) info = {
18051
+ ...info,
18052
+ entries: info.entries.filter((entry) => !hidden.has(entry.name))
18053
+ };
18054
+ }
18055
+ }
17930
18056
  if (props && !info?.isMemberCompletion) props = void 0;
17931
18057
  return {
17932
18058
  offset,
@@ -18191,8 +18317,7 @@ var TwillEditor = class {
18191
18317
  });
18192
18318
  }
18193
18319
  };
18194
- //#endregion
18195
- //#region src/typescript-plugin.ts
18320
+ // src/typescript-plugin.ts
18196
18321
  /** Semantic bridge for native TS/JS documents in configured mixed projects. */
18197
18322
  function init(_modules) {
18198
18323
  const contexts = /* @__PURE__ */ new Map();
@@ -18435,7 +18560,6 @@ function init(_modules) {
18435
18560
  }
18436
18561
  };
18437
18562
  }
18438
- //#endregion
18439
18563
  exports.default = init;
18440
18564
  module.exports = module.exports.default;
18441
18565