rip-lang 3.16.3 → 3.17.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.
package/docs/dist/rip.js CHANGED
@@ -4844,12 +4844,236 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4844
4844
  } catch {}
4845
4845
  }
4846
4846
 
4847
+ // src/error.js
4848
+ class RipError extends Error {
4849
+ constructor(message, {
4850
+ code = null,
4851
+ file = null,
4852
+ line = null,
4853
+ column = null,
4854
+ length = 1,
4855
+ source = null,
4856
+ suggestion = null,
4857
+ phase = null
4858
+ } = {}) {
4859
+ super(message);
4860
+ this.name = "RipError";
4861
+ this.code = code;
4862
+ this.file = file;
4863
+ this.line = line;
4864
+ this.column = column;
4865
+ this.length = length;
4866
+ this.source = source;
4867
+ this.suggestion = suggestion;
4868
+ this.phase = phase;
4869
+ }
4870
+ static fromLexer(err, source, file) {
4871
+ let loc = err.location || {};
4872
+ return new RipError(err.message, {
4873
+ code: "E_SYNTAX",
4874
+ file,
4875
+ line: loc.first_line ?? null,
4876
+ column: loc.first_column ?? null,
4877
+ length: loc.last_column != null && loc.first_column != null ? loc.last_column - loc.first_column + 1 : 1,
4878
+ source,
4879
+ phase: "lexer"
4880
+ });
4881
+ }
4882
+ static fromParser(err, source, file) {
4883
+ let h = err.hash || {};
4884
+ let loc = h.loc || {};
4885
+ let line = h.line ?? loc.r ?? null;
4886
+ let column = loc.first_column ?? loc.c ?? null;
4887
+ let suggestion = null;
4888
+ if (h.expected?.length) {
4889
+ let first5 = h.expected.slice(0, 5).map((e) => e.replace(/'/g, ""));
4890
+ suggestion = `Expected ${first5.join(", ")}`;
4891
+ if (h.expected.length > 5)
4892
+ suggestion += `, ... (${h.expected.length} total)`;
4893
+ }
4894
+ let token = h.token || "token";
4895
+ let expectedSet = new Set((h.expected || []).map((e) => e.replace(/'/g, "")));
4896
+ let TERNARY_ENDERS = new Set([
4897
+ "TERMINATOR",
4898
+ ",",
4899
+ ")",
4900
+ "]",
4901
+ "OUTDENT",
4902
+ "CALL_END",
4903
+ "INDEX_END",
4904
+ "PARAM_END",
4905
+ "EOF"
4906
+ ]);
4907
+ if (expectedSet.has(":") && (expectedSet.has("POST_IF") || expectedSet.has("POST_UNLESS") || expectedSet.has("FOR") || expectedSet.has("WHILE")) && TERNARY_ENDERS.has(token)) {
4908
+ suggestion = "Binary `x ? y` was removed — use `x ?? y` for nullish coalescing, or a full ternary `x ? y : z`";
4909
+ }
4910
+ let near = h.text ? ` near '${h.text}'` : "";
4911
+ let message = `Unexpected ${token}${near}`;
4912
+ return new RipError(message, {
4913
+ code: "E_PARSE",
4914
+ file,
4915
+ line,
4916
+ column,
4917
+ length: h.text?.length || 1,
4918
+ source,
4919
+ suggestion,
4920
+ phase: "parser"
4921
+ });
4922
+ }
4923
+ static fromSExpr(message, sexpr, source, file, suggestion) {
4924
+ let loc = sexpr?.loc || {};
4925
+ return new RipError(message, {
4926
+ code: "E_CODEGEN",
4927
+ file,
4928
+ line: loc.r ?? null,
4929
+ column: loc.c ?? null,
4930
+ length: loc.n ?? 1,
4931
+ source,
4932
+ suggestion,
4933
+ phase: "codegen"
4934
+ });
4935
+ }
4936
+ get locationString() {
4937
+ let parts = [];
4938
+ if (this.file)
4939
+ parts.push(this.file);
4940
+ if (this.line != null) {
4941
+ parts.push(`${this.line + 1}:${(this.column ?? 0) + 1}`);
4942
+ }
4943
+ return parts.join(":");
4944
+ }
4945
+ format({ color = true } = {}) {
4946
+ let c = color ? {
4947
+ red: "\x1B[31m",
4948
+ yellow: "\x1B[33m",
4949
+ cyan: "\x1B[36m",
4950
+ dim: "\x1B[2m",
4951
+ bold: "\x1B[1m",
4952
+ reset: "\x1B[0m"
4953
+ } : { red: "", yellow: "", cyan: "", dim: "", bold: "", reset: "" };
4954
+ let lines = [];
4955
+ let loc = this.locationString;
4956
+ let header = loc ? `${c.cyan}${loc}${c.reset} ` : "";
4957
+ lines.push(`${header}${c.red}${c.bold}error${c.reset}${c.bold}: ${this.message}${c.reset}`);
4958
+ let snippet = this._snippet();
4959
+ if (snippet) {
4960
+ lines.push("");
4961
+ for (let s of snippet) {
4962
+ if (s.type === "source") {
4963
+ lines.push(`${c.dim}${s.gutter}${c.reset}${s.text}`);
4964
+ } else if (s.type === "caret") {
4965
+ lines.push(`${c.dim}${s.gutter}${c.reset}${c.red}${c.bold}${s.text}${c.reset}`);
4966
+ }
4967
+ }
4968
+ }
4969
+ if (this.suggestion) {
4970
+ lines.push("");
4971
+ lines.push(`${c.yellow}hint${c.reset}: ${this.suggestion}`);
4972
+ }
4973
+ return lines.join(`
4974
+ `);
4975
+ }
4976
+ formatHTML() {
4977
+ let lines = [];
4978
+ lines.push('<div class="rip-error">');
4979
+ lines.push("<style>");
4980
+ lines.push(`.rip-error { font-family: ui-monospace, "SF Mono", Menlo, Monaco, monospace; font-size: 13px; line-height: 1.5; padding: 16px 20px; background: #1e1e2e; color: #cdd6f4; border-radius: 8px; overflow-x: auto; }`);
4981
+ lines.push(`.rip-error .re-header { color: #f38ba8; font-weight: 600; }`);
4982
+ lines.push(`.rip-error .re-loc { color: #89b4fa; }`);
4983
+ lines.push(`.rip-error .re-gutter { color: #585b70; user-select: none; }`);
4984
+ lines.push(`.rip-error .re-caret { color: #f38ba8; font-weight: 700; }`);
4985
+ lines.push(`.rip-error .re-hint { color: #f9e2af; }`);
4986
+ lines.push(`.rip-error .re-snippet { margin: 8px 0; }`);
4987
+ lines.push("</style>");
4988
+ let loc = this.locationString;
4989
+ let locSpan = loc ? `<span class="re-loc">${esc(loc)}</span> ` : "";
4990
+ lines.push(`<div class="re-header">${locSpan}error: ${esc(this.message)}</div>`);
4991
+ let snippet = this._snippet();
4992
+ if (snippet) {
4993
+ lines.push('<pre class="re-snippet">');
4994
+ for (let s of snippet) {
4995
+ if (s.type === "source") {
4996
+ lines.push(`<span class="re-gutter">${esc(s.gutter)}</span>${esc(s.text)}`);
4997
+ } else if (s.type === "caret") {
4998
+ lines.push(`<span class="re-gutter">${esc(s.gutter)}</span><span class="re-caret">${esc(s.text)}</span>`);
4999
+ }
5000
+ }
5001
+ lines.push("</pre>");
5002
+ }
5003
+ if (this.suggestion) {
5004
+ lines.push(`<div class="re-hint">hint: ${esc(this.suggestion)}</div>`);
5005
+ }
5006
+ lines.push("</div>");
5007
+ return lines.join(`
5008
+ `);
5009
+ }
5010
+ _snippet() {
5011
+ if (this.source == null || this.line == null)
5012
+ return null;
5013
+ let sourceLines = this.source.split(`
5014
+ `);
5015
+ let errLine = this.line;
5016
+ if (errLine < 0 || errLine >= sourceLines.length)
5017
+ return null;
5018
+ let contextRadius = 2;
5019
+ let start = Math.max(0, errLine - contextRadius);
5020
+ let end = Math.min(sourceLines.length - 1, errLine + contextRadius);
5021
+ let gutterWidth = String(end + 1).length;
5022
+ let result = [];
5023
+ for (let i = start;i <= end; i++) {
5024
+ let lineNum = String(i + 1).padStart(gutterWidth);
5025
+ let gutter = ` ${lineNum} │ `;
5026
+ result.push({ type: "source", gutter, text: sourceLines[i] });
5027
+ if (i === errLine && this.column != null) {
5028
+ let pad = " ".repeat(this.column);
5029
+ let caretLen = Math.max(1, Math.min(this.length || 1, sourceLines[i].length - this.column));
5030
+ let carets = "^".repeat(caretLen);
5031
+ let emptyGutter = " ".repeat(gutterWidth + 2) + "│ ";
5032
+ result.push({ type: "caret", gutter: emptyGutter, text: `${pad}${carets}` });
5033
+ }
5034
+ }
5035
+ return result;
5036
+ }
5037
+ }
5038
+ function isLexerError(err) {
5039
+ return err instanceof SyntaxError && err.location != null;
5040
+ }
5041
+ function isParserError(err) {
5042
+ return !(err instanceof SyntaxError) && err.hash != null;
5043
+ }
5044
+ function toRipError(err, source, file) {
5045
+ if (err instanceof RipError) {
5046
+ if (file && !err.file)
5047
+ err.file = file;
5048
+ if (source && !err.source)
5049
+ err.source = source;
5050
+ return err;
5051
+ }
5052
+ if (isLexerError(err))
5053
+ return RipError.fromLexer(err, source, file);
5054
+ if (isParserError(err))
5055
+ return RipError.fromParser(err, source, file);
5056
+ return new RipError(err.message, { file, source, phase: "unknown" });
5057
+ }
5058
+ function formatError(err, { source, file, color = true } = {}) {
5059
+ let re = err instanceof RipError ? err : toRipError(err, source, file);
5060
+ return re.format({ color });
5061
+ }
5062
+ function formatErrorHTML(err, { source, file } = {}) {
5063
+ let re = err instanceof RipError ? err : toRipError(err, source, file);
5064
+ return re.formatHTML();
5065
+ }
5066
+ function esc(s) {
5067
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5068
+ }
5069
+
4847
5070
  // src/types.js
4848
5071
  function installTypeSupport(Lexer) {
4849
5072
  let proto = Lexer.prototype;
4850
5073
  proto.rewriteTypes = function() {
4851
5074
  let tokens = this.tokens;
4852
5075
  let typeRefNames = this.typeRefNames = new Set;
5076
+ reclassifyColonTypes(tokens);
4853
5077
  let gen = (tag, val, origin) => {
4854
5078
  let t = [tag, val];
4855
5079
  t.pre = 0;
@@ -4898,7 +5122,19 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4898
5122
  let prevToken = tokens2[i - 1];
4899
5123
  if (!prevToken)
4900
5124
  return 1;
4901
- let typeTokens = collectTypeExpression(tokens2, i + 1);
5125
+ let isArrowReturn = prevToken[0] === "PARAM_END";
5126
+ let typeTokens = collectTypeExpression(tokens2, i + 1, { stopAtFatArrow: isArrowReturn });
5127
+ if (isArrowReturn && looksLikeBareFunctionType(typeTokens)) {
5128
+ let loc = tokens2[i + 1]?.loc;
5129
+ throw new RipError("A function-type return on an arrow must be parenthesized", {
5130
+ code: "E_SYNTAX",
5131
+ phase: "lexer",
5132
+ line: loc?.r ?? null,
5133
+ column: loc?.c ?? null,
5134
+ length: loc?.n ?? 1,
5135
+ suggestion: "wrap the whole function type in parens — " + "`(x):: ((a: T) => R) => body`, not `(x):: (a: T) => R => body`"
5136
+ });
5137
+ }
4902
5138
  let typeStr = buildTypeString(typeTokens);
4903
5139
  let target = prevToken;
4904
5140
  let propName = "type";
@@ -5064,26 +5300,444 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
5064
5300
  }
5065
5301
  }
5066
5302
  }
5067
- if (!hasTypes)
5303
+ if (!hasTypes)
5304
+ continue;
5305
+ let overloadTokens = tokens.slice(i, j + 1);
5306
+ let exported = i >= 1 && tokens[i - 1]?.[0] === "EXPORT";
5307
+ let spliceFrom = exported ? i - 1 : i;
5308
+ let spliceCount = j + 1 - spliceFrom;
5309
+ let marker = gen("TYPE_DECL", nameToken[1], nameToken);
5310
+ marker.data = {
5311
+ name: nameToken[1],
5312
+ kind: "overload",
5313
+ overloadTokens,
5314
+ exported
5315
+ };
5316
+ if (nameToken.data?.typeParams)
5317
+ marker.data.typeParams = nameToken.data.typeParams;
5318
+ tokens.splice(spliceFrom, spliceCount, marker);
5319
+ }
5320
+ };
5321
+ }
5322
+ function looksLikeBareFunctionType(typeTokens) {
5323
+ const isOpen = (t) => t === "(" || t === "PARAM_START" || t === "CALL_START";
5324
+ const isClose = (t) => t === ")" || t === "PARAM_END" || t === "CALL_END";
5325
+ if (typeTokens.length < 2 || !isOpen(typeTokens[0][0]))
5326
+ return false;
5327
+ let depth = 0;
5328
+ for (let k = 0;k < typeTokens.length; k++) {
5329
+ const tag = typeTokens[k][0];
5330
+ if (isOpen(tag))
5331
+ depth++;
5332
+ else if (isClose(tag)) {
5333
+ if (--depth === 0 && k !== typeTokens.length - 1)
5334
+ return false;
5335
+ }
5336
+ }
5337
+ if (depth !== 0)
5338
+ return false;
5339
+ if (typeTokens.length === 2)
5340
+ return true;
5341
+ let d = 0, pendingTernary = false;
5342
+ for (const t of typeTokens) {
5343
+ const tag = t[0];
5344
+ if (isOpen(tag) || tag === "[" || tag === "{" || tag === "INDEX_START")
5345
+ d++;
5346
+ else if (isClose(tag) || tag === "]" || tag === "}" || tag === "INDEX_END")
5347
+ d--;
5348
+ else if (d === 1 && tag === "TERNARY")
5349
+ pendingTernary = true;
5350
+ else if (d === 1 && tag === ":") {
5351
+ if (pendingTernary)
5352
+ pendingTernary = false;
5353
+ else
5354
+ return true;
5355
+ }
5356
+ }
5357
+ return false;
5358
+ }
5359
+ function isCompleteTypeExpr(tokens, a, b) {
5360
+ if (b <= a)
5361
+ return false;
5362
+ const SEP = new Set(["|", "&", ",", ":", "?", ".", "...", "=>"]);
5363
+ let par = 0, brk = 0, brc = 0, gen = 0, atomEnd = false;
5364
+ for (let j = a;j < b; j++) {
5365
+ const t = tokens[j][0], v = tokens[j][1];
5366
+ if (t === "(" || t === "PARAM_START") {
5367
+ par++;
5368
+ atomEnd = false;
5369
+ continue;
5370
+ }
5371
+ if (t === ")" || t === "PARAM_END") {
5372
+ if (--par < 0)
5373
+ return false;
5374
+ atomEnd = true;
5375
+ continue;
5376
+ }
5377
+ if (t === "[" || t === "INDEX_START") {
5378
+ brk++;
5379
+ atomEnd = false;
5380
+ continue;
5381
+ }
5382
+ if (t === "]" || t === "INDEX_END") {
5383
+ if (--brk < 0)
5384
+ return false;
5385
+ atomEnd = true;
5386
+ continue;
5387
+ }
5388
+ if (t === "{") {
5389
+ brc++;
5390
+ atomEnd = false;
5391
+ continue;
5392
+ }
5393
+ if (t === "}") {
5394
+ if (--brc < 0)
5395
+ return false;
5396
+ atomEnd = true;
5397
+ continue;
5398
+ }
5399
+ if (t === "COMPARE") {
5400
+ if (v === "<") {
5401
+ gen++;
5402
+ atomEnd = false;
5403
+ continue;
5404
+ }
5405
+ if (v === ">") {
5406
+ if (gen <= 0)
5407
+ return false;
5408
+ gen--;
5409
+ atomEnd = true;
5410
+ continue;
5411
+ }
5412
+ return false;
5413
+ }
5414
+ if (t === "SHIFT") {
5415
+ if (v === ">>") {
5416
+ if (gen < 2)
5417
+ return false;
5418
+ gen -= 2;
5419
+ atomEnd = true;
5420
+ continue;
5421
+ }
5422
+ return false;
5423
+ }
5424
+ if (t === "=") {
5425
+ if (gen > 0) {
5426
+ atomEnd = false;
5427
+ continue;
5428
+ }
5429
+ return false;
5430
+ }
5431
+ if (SEP.has(t)) {
5432
+ atomEnd = false;
5433
+ continue;
5434
+ }
5435
+ if (t === "IDENTIFIER" || t === "PROPERTY" || t === "NUMBER" || t === "STRING" || t === "NULL" || t === "UNDEFINED" || t === "BOOL") {
5436
+ if (atomEnd)
5437
+ return false;
5438
+ atomEnd = true;
5439
+ continue;
5440
+ }
5441
+ return false;
5442
+ }
5443
+ return par === 0 && brk === 0 && brc === 0 && gen === 0 && atomEnd;
5444
+ }
5445
+ function assignedLaterInBlock(tokens, start, name) {
5446
+ const ASSIGN = new Set(["=", "REACTIVE_ASSIGN", "COMPUTED_ASSIGN", "READONLY_ASSIGN"]);
5447
+ let indent = 0, bracket = 0, closureDepth = 0;
5448
+ const closureAt = [];
5449
+ for (let j = start;j < tokens.length; j++) {
5450
+ const g = tokens[j][0];
5451
+ if (g === "INDENT") {
5452
+ indent++;
5453
+ const p = tokens[j - 1]?.[0];
5454
+ if (p === "->" || p === "=>") {
5455
+ closureAt.push(indent);
5456
+ closureDepth++;
5457
+ }
5458
+ continue;
5459
+ }
5460
+ if (g === "OUTDENT") {
5461
+ if (indent === 0)
5462
+ return false;
5463
+ if (closureAt[closureAt.length - 1] === indent) {
5464
+ closureAt.pop();
5465
+ closureDepth--;
5466
+ }
5467
+ indent--;
5468
+ continue;
5469
+ }
5470
+ if (g === "(" || g === "CALL_START" || g === "PARAM_START" || g === "[" || g === "INDEX_START" || g === "{") {
5471
+ bracket++;
5472
+ continue;
5473
+ }
5474
+ if (g === ")" || g === "CALL_END" || g === "PARAM_END" || g === "]" || g === "INDEX_END" || g === "}") {
5475
+ bracket--;
5476
+ continue;
5477
+ }
5478
+ if (closureDepth === 0 && bracket === 0 && (g === "IDENTIFIER" || g === "PROPERTY") && tokens[j][1] === name && ASSIGN.has(tokens[j + 1]?.[0]))
5479
+ return true;
5480
+ }
5481
+ return false;
5482
+ }
5483
+ function reclassifyColonTypes(tokens) {
5484
+ const isOpen = (t) => t === "(" || t === "CALL_START" || t === "PARAM_START" || t === "{" || t === "[" || t === "INDEX_START";
5485
+ const isClose = (t) => t === ")" || t === "CALL_END" || t === "PARAM_END" || t === "}" || t === "]" || t === "INDEX_END";
5486
+ const isDefParamStart = (i) => {
5487
+ let j = i - 1;
5488
+ const g0 = tokens[j]?.[0], v0 = tokens[j]?.[1];
5489
+ if (g0 === "COMPARE" && v0 === ">" || g0 === "SHIFT" && v0 === ">>") {
5490
+ let depth = g0 === "SHIFT" ? 2 : 1;
5491
+ j--;
5492
+ while (j >= 0 && depth > 0) {
5493
+ const g = tokens[j][0], v = tokens[j][1];
5494
+ if (g === "COMPARE" && v === ">")
5495
+ depth++;
5496
+ else if (g === "SHIFT" && v === ">>")
5497
+ depth += 2;
5498
+ else if (g === "COMPARE" && v === "<")
5499
+ depth--;
5500
+ else if (g === "SHIFT" && v === "<<")
5501
+ depth -= 2;
5502
+ j--;
5503
+ }
5504
+ }
5505
+ if (tokens[j]?.[0] !== "IDENTIFIER" && tokens[j]?.[0] !== "PROPERTY")
5506
+ return false;
5507
+ return tokens[j - 1]?.[0] === "DEF";
5508
+ };
5509
+ const STMT_START = new Set(["TERMINATOR", "INDENT", "OUTDENT", "EXPORT"]);
5510
+ const BINDING_OPS = new Set(["=", "REACTIVE_ASSIGN", "COMPUTED_ASSIGN", "READONLY_ASSIGN"]);
5511
+ const atStatementStart = (t) => !t || STMT_START.has(t[0]);
5512
+ const declBindsBeforeArrow = (start) => {
5513
+ let depth = 0;
5514
+ for (let j = start;j < tokens.length; j++) {
5515
+ const g = tokens[j][0];
5516
+ if (isOpen(g))
5517
+ depth++;
5518
+ else if (isClose(g))
5519
+ depth--;
5520
+ else if (depth === 0) {
5521
+ if (g === "->" || g === "=>")
5522
+ return false;
5523
+ if (BINDING_OPS.has(g))
5524
+ return true;
5525
+ if ((g === "EFFECT" || g === "GATE") && j > start)
5526
+ return true;
5527
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5528
+ return false;
5529
+ }
5530
+ }
5531
+ return false;
5532
+ };
5533
+ const valueIsMethod = (start) => {
5534
+ let depth = 0;
5535
+ for (let j = start;j < tokens.length; j++) {
5536
+ const g = tokens[j][0];
5537
+ if (isOpen(g))
5538
+ depth++;
5539
+ else if (isClose(g))
5540
+ depth--;
5541
+ else if (depth === 0) {
5542
+ if (g === "->" || g === "=>")
5543
+ return true;
5544
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5545
+ return false;
5546
+ }
5547
+ }
5548
+ return false;
5549
+ };
5550
+ let pendingBody = false;
5551
+ const indentStack = [];
5552
+ const inTypedBody = () => indentStack.length > 0 && indentStack[indentStack.length - 1];
5553
+ const nameAtStatementStart = (i) => {
5554
+ const p = tokens[i - 1]?.[0];
5555
+ if (p !== "PROPERTY" && p !== "IDENTIFIER")
5556
+ return false;
5557
+ if (tokens[i - 2]?.[0] === "@")
5558
+ return atStatementStart(tokens[i - 3]);
5559
+ return atStatementStart(tokens[i - 2]);
5560
+ };
5561
+ let inType = false, typeStartDepth = 0;
5562
+ const enterType = () => {
5563
+ inType = true;
5564
+ typeStartDepth = stack.length;
5565
+ };
5566
+ let prevSiblingKV = false, curLineKV = false;
5567
+ const stack = [];
5568
+ for (let i = 0;i < tokens.length; i++) {
5569
+ const tag = tokens[i][0];
5570
+ if (tag === "CLASS" || tag === "COMPONENT") {
5571
+ pendingBody = true;
5572
+ continue;
5573
+ }
5574
+ if (tag === "INDENT") {
5575
+ indentStack.push(pendingBody);
5576
+ pendingBody = false;
5577
+ prevSiblingKV = curLineKV = false;
5578
+ if (inType && stack.length <= typeStartDepth)
5579
+ inType = false;
5580
+ continue;
5581
+ }
5582
+ if (tag === "OUTDENT") {
5583
+ indentStack.pop();
5584
+ prevSiblingKV = curLineKV = false;
5585
+ if (inType && stack.length <= typeStartDepth)
5586
+ inType = false;
5587
+ continue;
5588
+ }
5589
+ if (isOpen(tag)) {
5590
+ let kind = "other";
5591
+ if (!inType) {
5592
+ if (tag === "PARAM_START")
5593
+ kind = "param";
5594
+ else if ((tag === "CALL_START" || tag === "(") && isDefParamStart(i))
5595
+ kind = "defparam";
5596
+ }
5597
+ stack.push({ kind, sawEq: false, sawType: false });
5598
+ continue;
5599
+ }
5600
+ if (isClose(tag)) {
5601
+ const f2 = stack.pop();
5602
+ if (f2?.kind === "defparam") {
5603
+ (tokens[i].data ??= {}).isDefParamEnd = true;
5604
+ }
5605
+ if (inType && stack.length < typeStartDepth)
5606
+ inType = false;
5607
+ continue;
5608
+ }
5609
+ if (tag === "TYPE_ANNOTATION") {
5610
+ if (!inType)
5611
+ enterType();
5612
+ continue;
5613
+ }
5614
+ if (inType) {
5615
+ if (stack.length <= typeStartDepth && (tag === "=" || tag === "," || tag === "TERMINATOR" || tag === "->" || BINDING_OPS.has(tag))) {
5616
+ inType = false;
5617
+ } else {
5618
+ continue;
5619
+ }
5620
+ }
5621
+ if (tag === "TERMINATOR" && stack.length === 0) {
5622
+ prevSiblingKV = curLineKV;
5623
+ curLineKV = false;
5624
+ }
5625
+ if (tag === ":") {
5626
+ const prev = tokens[i - 1];
5627
+ const prevTag = prev?.[0];
5628
+ if (stack.length === 0 && (prevTag === "IDENTIFIER" || prevTag === "PROPERTY") && atStatementStart(tokens[i - 2]))
5629
+ curLineKV = true;
5630
+ if (prevTag === "PARAM_END" || (prevTag === ")" || prevTag === "CALL_END") && prev.data?.isDefParamEnd) {
5631
+ tokens[i][0] = "TYPE_ANNOTATION";
5632
+ enterType();
5633
+ continue;
5634
+ }
5635
+ if ((prevTag === "IDENTIFIER" || prevTag === "PROPERTY") && tokens[i - 2]?.[0] === "DEF") {
5636
+ if (prevTag === "PROPERTY")
5637
+ prev[0] = "IDENTIFIER";
5638
+ tokens[i][0] = "TYPE_ANNOTATION";
5639
+ enterType();
5640
+ continue;
5641
+ }
5642
+ if (stack.length === 0 && nameAtStatementStart(i) && declBindsBeforeArrow(i + 1)) {
5643
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5644
+ prev[0] = "IDENTIFIER";
5645
+ tokens[i][0] = "TYPE_ANNOTATION";
5646
+ enterType();
5647
+ continue;
5648
+ }
5649
+ if (stack.length === 0 && nameAtStatementStart(i)) {
5650
+ let depth = 0;
5651
+ for (let j = i + 1;j < tokens.length; j++) {
5652
+ const g = tokens[j][0];
5653
+ if (isOpen(g))
5654
+ depth++;
5655
+ else if (isClose(g)) {
5656
+ if (depth === 0)
5657
+ break;
5658
+ depth--;
5659
+ } else if (depth === 0) {
5660
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5661
+ break;
5662
+ if (g === "=" && isCompleteTypeExpr(tokens, i + 1, j)) {
5663
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5664
+ prev[0] = "IDENTIFIER";
5665
+ tokens[i][0] = "TYPE_ANNOTATION";
5666
+ enterType();
5667
+ break;
5668
+ }
5669
+ }
5670
+ }
5671
+ if (tokens[i][0] === "TYPE_ANNOTATION")
5672
+ continue;
5673
+ }
5674
+ if (inTypedBody() && stack.length === 0 && nameAtStatementStart(i) && !valueIsMethod(i + 1)) {
5675
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5676
+ prev[0] = "IDENTIFIER";
5677
+ tokens[i][0] = "TYPE_ANNOTATION";
5678
+ enterType();
5679
+ continue;
5680
+ }
5681
+ if (stack.length === 0 && nameAtStatementStart(i) && tokens[i - 2]?.[0] !== "@") {
5682
+ let depth = 0, end = -1;
5683
+ for (let j = i + 1;j < tokens.length; j++) {
5684
+ const g = tokens[j][0];
5685
+ if (isOpen(g))
5686
+ depth++;
5687
+ else if (isClose(g)) {
5688
+ if (depth === 0)
5689
+ break;
5690
+ depth--;
5691
+ } else if (depth === 0) {
5692
+ if (g === "TERMINATOR") {
5693
+ end = j;
5694
+ break;
5695
+ }
5696
+ if (g === "INDENT" || g === "OUTDENT" || g === "=" || BINDING_OPS.has(g))
5697
+ break;
5698
+ }
5699
+ }
5700
+ const nk = tokens[end + 1];
5701
+ const nextKV = nk && (nk[0] === "IDENTIFIER" || nk[0] === "PROPERTY") && tokens[end + 2]?.[0] === ":";
5702
+ if (end > i + 1 && nk && nk[0] !== "OUTDENT" && !prevSiblingKV && !nextKV && isCompleteTypeExpr(tokens, i + 1, end) && assignedLaterInBlock(tokens, end + 1, prev[1])) {
5703
+ if (prevTag === "PROPERTY")
5704
+ prev[0] = "IDENTIFIER";
5705
+ tokens[i][0] = "TYPE_ANNOTATION";
5706
+ enterType();
5707
+ continue;
5708
+ }
5709
+ }
5710
+ }
5711
+ const f = stack[stack.length - 1];
5712
+ if (f && (f.kind === "param" || f.kind === "defparam")) {
5713
+ if (tag === ",") {
5714
+ f.sawEq = false;
5715
+ f.sawType = false;
5068
5716
  continue;
5069
- let overloadTokens = tokens.slice(i, j + 1);
5070
- let exported = i >= 1 && tokens[i - 1]?.[0] === "EXPORT";
5071
- let spliceFrom = exported ? i - 1 : i;
5072
- let spliceCount = j + 1 - spliceFrom;
5073
- let marker = gen("TYPE_DECL", nameToken[1], nameToken);
5074
- marker.data = {
5075
- name: nameToken[1],
5076
- kind: "overload",
5077
- overloadTokens,
5078
- exported
5079
- };
5080
- if (nameToken.data?.typeParams)
5081
- marker.data.typeParams = nameToken.data.typeParams;
5082
- tokens.splice(spliceFrom, spliceCount, marker);
5717
+ }
5718
+ if (tag === "=") {
5719
+ f.sawEq = true;
5720
+ continue;
5721
+ }
5722
+ if (tag === ":" && !f.sawEq && !f.sawType) {
5723
+ const prev = tokens[i - 1];
5724
+ const prevTag = prev?.[0];
5725
+ if (prevTag === "PROPERTY" || prevTag === "IDENTIFIER") {
5726
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5727
+ prev[0] = "IDENTIFIER";
5728
+ tokens[i][0] = "TYPE_ANNOTATION";
5729
+ f.sawType = true;
5730
+ enterType();
5731
+ } else if (prevTag === "}" || prevTag === "]" || prevTag === "INDEX_END") {
5732
+ tokens[i][0] = "TYPE_ANNOTATION";
5733
+ f.sawType = true;
5734
+ enterType();
5735
+ }
5736
+ }
5083
5737
  }
5084
- };
5738
+ }
5085
5739
  }
5086
- function collectTypeExpression(tokens, j) {
5740
+ function collectTypeExpression(tokens, j, opts = {}) {
5087
5741
  let typeTokens = [];
5088
5742
  let depth = 0;
5089
5743
  let bracketStack = [];
@@ -5122,6 +5776,8 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
5122
5776
  break;
5123
5777
  }
5124
5778
  if (depth === 0) {
5779
+ if (opts.stopAtFatArrow && tTag === "=>")
5780
+ break;
5125
5781
  if (tTag === "INDENT" && typeTokens.length > 0 && typeTokens[typeTokens.length - 1][0] === "=>") {
5126
5782
  j++;
5127
5783
  let nest = 1;
@@ -6224,6 +6880,11 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6224
6880
  depth--;
6225
6881
  if (depth === 0 && tk[0] === "TYPE_ANNOTATION")
6226
6882
  return false;
6883
+ if (depth === 0 && tk[0] === ":") {
6884
+ let pv = this.tokens[k - 1];
6885
+ if (pv && (pv[0] === ")" || pv[0] === "PARAM_END" || pv[0] === "CALL_END"))
6886
+ return false;
6887
+ }
6227
6888
  if (depth === 0 && tk[0] === "IDENTIFIER" && tk[1] === "type")
6228
6889
  return false;
6229
6890
  if (tk[0] === "INTERFACE")
@@ -6753,7 +7414,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6753
7414
  } else if (tg === "(" || tg === "[" || tg === "{" || tg === "CALL_START" || tg === "PARAM_START" || tg === "INDEX_START" || tg === "COMPARE" && tk[1] === "<") {
6754
7415
  depth--;
6755
7416
  } else if (depth === 0) {
6756
- if (tg === "TYPE_ANNOTATION") {
7417
+ if (tg === "TYPE_ANNOTATION" || tg === ":") {
6757
7418
  if (j > 0 && this.tokens[j - 1][0] === ")")
6758
7419
  found = j - 1;
6759
7420
  break;
@@ -6766,6 +7427,22 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6766
7427
  if (found < 0)
6767
7428
  return this.tagDoIife();
6768
7429
  closeIdx = found;
7430
+ } else {
7431
+ let d = 0, op = -1;
7432
+ for (let k = closeIdx;k >= 0; k--) {
7433
+ let tg = this.tokens[k][0];
7434
+ if (tg === ")" || tg === "CALL_END" || tg === "PARAM_END")
7435
+ d++;
7436
+ else if (tg === "(" || tg === "CALL_START" || tg === "PARAM_START") {
7437
+ if (--d === 0) {
7438
+ op = k;
7439
+ break;
7440
+ }
7441
+ }
7442
+ }
7443
+ if (op > 1 && this.tokens[op - 1][0] === "TYPE_ANNOTATION" && this.tokens[op - 2]?.[0] === ")") {
7444
+ closeIdx = op - 2;
7445
+ }
6769
7446
  }
6770
7447
  let i = closeIdx;
6771
7448
  let stack = [];
@@ -11315,229 +11992,6 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11315
11992
  return name;
11316
11993
  }
11317
11994
 
11318
- // src/error.js
11319
- class RipError extends Error {
11320
- constructor(message, {
11321
- code = null,
11322
- file = null,
11323
- line = null,
11324
- column = null,
11325
- length = 1,
11326
- source = null,
11327
- suggestion = null,
11328
- phase = null
11329
- } = {}) {
11330
- super(message);
11331
- this.name = "RipError";
11332
- this.code = code;
11333
- this.file = file;
11334
- this.line = line;
11335
- this.column = column;
11336
- this.length = length;
11337
- this.source = source;
11338
- this.suggestion = suggestion;
11339
- this.phase = phase;
11340
- }
11341
- static fromLexer(err, source, file) {
11342
- let loc = err.location || {};
11343
- return new RipError(err.message, {
11344
- code: "E_SYNTAX",
11345
- file,
11346
- line: loc.first_line ?? null,
11347
- column: loc.first_column ?? null,
11348
- length: loc.last_column != null && loc.first_column != null ? loc.last_column - loc.first_column + 1 : 1,
11349
- source,
11350
- phase: "lexer"
11351
- });
11352
- }
11353
- static fromParser(err, source, file) {
11354
- let h = err.hash || {};
11355
- let loc = h.loc || {};
11356
- let line = h.line ?? loc.r ?? null;
11357
- let column = loc.first_column ?? loc.c ?? null;
11358
- let suggestion = null;
11359
- if (h.expected?.length) {
11360
- let first5 = h.expected.slice(0, 5).map((e) => e.replace(/'/g, ""));
11361
- suggestion = `Expected ${first5.join(", ")}`;
11362
- if (h.expected.length > 5)
11363
- suggestion += `, ... (${h.expected.length} total)`;
11364
- }
11365
- let token = h.token || "token";
11366
- let expectedSet = new Set((h.expected || []).map((e) => e.replace(/'/g, "")));
11367
- let TERNARY_ENDERS = new Set([
11368
- "TERMINATOR",
11369
- ",",
11370
- ")",
11371
- "]",
11372
- "OUTDENT",
11373
- "CALL_END",
11374
- "INDEX_END",
11375
- "PARAM_END",
11376
- "EOF"
11377
- ]);
11378
- if (expectedSet.has(":") && (expectedSet.has("POST_IF") || expectedSet.has("POST_UNLESS") || expectedSet.has("FOR") || expectedSet.has("WHILE")) && TERNARY_ENDERS.has(token)) {
11379
- suggestion = "Binary `x ? y` was removed — use `x ?? y` for nullish coalescing, or a full ternary `x ? y : z`";
11380
- }
11381
- let near = h.text ? ` near '${h.text}'` : "";
11382
- let message = `Unexpected ${token}${near}`;
11383
- return new RipError(message, {
11384
- code: "E_PARSE",
11385
- file,
11386
- line,
11387
- column,
11388
- length: h.text?.length || 1,
11389
- source,
11390
- suggestion,
11391
- phase: "parser"
11392
- });
11393
- }
11394
- static fromSExpr(message, sexpr, source, file, suggestion) {
11395
- let loc = sexpr?.loc || {};
11396
- return new RipError(message, {
11397
- code: "E_CODEGEN",
11398
- file,
11399
- line: loc.r ?? null,
11400
- column: loc.c ?? null,
11401
- length: loc.n ?? 1,
11402
- source,
11403
- suggestion,
11404
- phase: "codegen"
11405
- });
11406
- }
11407
- get locationString() {
11408
- let parts = [];
11409
- if (this.file)
11410
- parts.push(this.file);
11411
- if (this.line != null) {
11412
- parts.push(`${this.line + 1}:${(this.column ?? 0) + 1}`);
11413
- }
11414
- return parts.join(":");
11415
- }
11416
- format({ color = true } = {}) {
11417
- let c = color ? {
11418
- red: "\x1B[31m",
11419
- yellow: "\x1B[33m",
11420
- cyan: "\x1B[36m",
11421
- dim: "\x1B[2m",
11422
- bold: "\x1B[1m",
11423
- reset: "\x1B[0m"
11424
- } : { red: "", yellow: "", cyan: "", dim: "", bold: "", reset: "" };
11425
- let lines = [];
11426
- let loc = this.locationString;
11427
- let header = loc ? `${c.cyan}${loc}${c.reset} ` : "";
11428
- lines.push(`${header}${c.red}${c.bold}error${c.reset}${c.bold}: ${this.message}${c.reset}`);
11429
- let snippet = this._snippet();
11430
- if (snippet) {
11431
- lines.push("");
11432
- for (let s of snippet) {
11433
- if (s.type === "source") {
11434
- lines.push(`${c.dim}${s.gutter}${c.reset}${s.text}`);
11435
- } else if (s.type === "caret") {
11436
- lines.push(`${c.dim}${s.gutter}${c.reset}${c.red}${c.bold}${s.text}${c.reset}`);
11437
- }
11438
- }
11439
- }
11440
- if (this.suggestion) {
11441
- lines.push("");
11442
- lines.push(`${c.yellow}hint${c.reset}: ${this.suggestion}`);
11443
- }
11444
- return lines.join(`
11445
- `);
11446
- }
11447
- formatHTML() {
11448
- let lines = [];
11449
- lines.push('<div class="rip-error">');
11450
- lines.push("<style>");
11451
- lines.push(`.rip-error { font-family: ui-monospace, "SF Mono", Menlo, Monaco, monospace; font-size: 13px; line-height: 1.5; padding: 16px 20px; background: #1e1e2e; color: #cdd6f4; border-radius: 8px; overflow-x: auto; }`);
11452
- lines.push(`.rip-error .re-header { color: #f38ba8; font-weight: 600; }`);
11453
- lines.push(`.rip-error .re-loc { color: #89b4fa; }`);
11454
- lines.push(`.rip-error .re-gutter { color: #585b70; user-select: none; }`);
11455
- lines.push(`.rip-error .re-caret { color: #f38ba8; font-weight: 700; }`);
11456
- lines.push(`.rip-error .re-hint { color: #f9e2af; }`);
11457
- lines.push(`.rip-error .re-snippet { margin: 8px 0; }`);
11458
- lines.push("</style>");
11459
- let loc = this.locationString;
11460
- let locSpan = loc ? `<span class="re-loc">${esc(loc)}</span> ` : "";
11461
- lines.push(`<div class="re-header">${locSpan}error: ${esc(this.message)}</div>`);
11462
- let snippet = this._snippet();
11463
- if (snippet) {
11464
- lines.push('<pre class="re-snippet">');
11465
- for (let s of snippet) {
11466
- if (s.type === "source") {
11467
- lines.push(`<span class="re-gutter">${esc(s.gutter)}</span>${esc(s.text)}`);
11468
- } else if (s.type === "caret") {
11469
- lines.push(`<span class="re-gutter">${esc(s.gutter)}</span><span class="re-caret">${esc(s.text)}</span>`);
11470
- }
11471
- }
11472
- lines.push("</pre>");
11473
- }
11474
- if (this.suggestion) {
11475
- lines.push(`<div class="re-hint">hint: ${esc(this.suggestion)}</div>`);
11476
- }
11477
- lines.push("</div>");
11478
- return lines.join(`
11479
- `);
11480
- }
11481
- _snippet() {
11482
- if (this.source == null || this.line == null)
11483
- return null;
11484
- let sourceLines = this.source.split(`
11485
- `);
11486
- let errLine = this.line;
11487
- if (errLine < 0 || errLine >= sourceLines.length)
11488
- return null;
11489
- let contextRadius = 2;
11490
- let start = Math.max(0, errLine - contextRadius);
11491
- let end = Math.min(sourceLines.length - 1, errLine + contextRadius);
11492
- let gutterWidth = String(end + 1).length;
11493
- let result = [];
11494
- for (let i = start;i <= end; i++) {
11495
- let lineNum = String(i + 1).padStart(gutterWidth);
11496
- let gutter = ` ${lineNum} │ `;
11497
- result.push({ type: "source", gutter, text: sourceLines[i] });
11498
- if (i === errLine && this.column != null) {
11499
- let pad = " ".repeat(this.column);
11500
- let caretLen = Math.max(1, Math.min(this.length || 1, sourceLines[i].length - this.column));
11501
- let carets = "^".repeat(caretLen);
11502
- let emptyGutter = " ".repeat(gutterWidth + 2) + "│ ";
11503
- result.push({ type: "caret", gutter: emptyGutter, text: `${pad}${carets}` });
11504
- }
11505
- }
11506
- return result;
11507
- }
11508
- }
11509
- function isLexerError(err) {
11510
- return err instanceof SyntaxError && err.location != null;
11511
- }
11512
- function isParserError(err) {
11513
- return !(err instanceof SyntaxError) && err.hash != null;
11514
- }
11515
- function toRipError(err, source, file) {
11516
- if (err instanceof RipError) {
11517
- if (file && !err.file)
11518
- err.file = file;
11519
- if (source && !err.source)
11520
- err.source = source;
11521
- return err;
11522
- }
11523
- if (isLexerError(err))
11524
- return RipError.fromLexer(err, source, file);
11525
- if (isParserError(err))
11526
- return RipError.fromParser(err, source, file);
11527
- return new RipError(err.message, { file, source, phase: "unknown" });
11528
- }
11529
- function formatError(err, { source, file, color = true } = {}) {
11530
- let re = err instanceof RipError ? err : toRipError(err, source, file);
11531
- return re.format({ color });
11532
- }
11533
- function formatErrorHTML(err, { source, file } = {}) {
11534
- let re = err instanceof RipError ? err : toRipError(err, source, file);
11535
- return re.formatHTML();
11536
- }
11537
- function esc(s) {
11538
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
11539
- }
11540
-
11541
11995
  // src/compiler.js
11542
11996
  var _typesEmitter = null;
11543
11997
  var meta = (node, key) => node instanceof String ? node[key] : undefined;
@@ -13011,10 +13465,10 @@ function _setDataSection() {
13011
13465
  let ret = this.inlineReturnType(name);
13012
13466
  return `${isAsync ? "async " : ""}function${isGen ? "*" : ""} ${cleanName}(${paramList})${ret} ${bodyCode}`;
13013
13467
  }
13014
- inlineReturnType(name) {
13468
+ inlineReturnType(node) {
13015
13469
  if (!this.options.inlineTypes)
13016
13470
  return "";
13017
- let rt = meta(name, "returnType");
13471
+ let rt = meta(node, "returnType");
13018
13472
  return rt ? `: ${ripToTs(rt)}` : "";
13019
13473
  }
13020
13474
  emitThinArrow(head, rest, context, sexpr) {
@@ -13026,7 +13480,8 @@ function _setDataSection() {
13026
13480
  let bodyCode = this.emitFunctionBody(body, params, sideEffectOnly);
13027
13481
  let isAsync = this.containsAwait(body);
13028
13482
  let isGen = this.containsYield(body);
13029
- let fn = `${isAsync ? "async " : ""}function${isGen ? "*" : ""}(${paramList}) ${bodyCode}`;
13483
+ let ret = this.inlineReturnType(sexpr?.[0]);
13484
+ let fn = `${isAsync ? "async " : ""}function${isGen ? "*" : ""}(${paramList})${ret} ${bodyCode}`;
13030
13485
  return context === "value" ? `(${fn})` : fn;
13031
13486
  }
13032
13487
  emitFatArrow(head, rest, context, sexpr) {
@@ -13035,7 +13490,8 @@ function _setDataSection() {
13035
13490
  params = ["it"];
13036
13491
  let sideEffectOnly = sexpr.isVoid || false;
13037
13492
  let paramList = this.emitParamList(params);
13038
- let isSingle = params.length === 1 && typeof params[0] === "string" && !paramList.includes("=") && !paramList.includes("...") && !paramList.includes("[") && !paramList.includes("{");
13493
+ let ret = this.inlineReturnType(sexpr?.[0]);
13494
+ let isSingle = !ret && params.length === 1 && typeof params[0] === "string" && !paramList.includes("=") && !paramList.includes("...") && !paramList.includes("[") && !paramList.includes("{");
13039
13495
  let paramSyntax = isSingle ? paramList : `(${paramList})`;
13040
13496
  let isAsync = this.containsAwait(body);
13041
13497
  let prefix = isAsync ? "async " : "";
@@ -13047,18 +13503,18 @@ function _setDataSection() {
13047
13503
  let code = this.emit(expr, "value");
13048
13504
  if (code[0] === "{")
13049
13505
  code = `(${code})`;
13050
- return `${prefix}${paramSyntax} => ${code}`;
13506
+ return `${prefix}${paramSyntax}${ret} => ${code}`;
13051
13507
  }
13052
13508
  }
13053
13509
  if (!Array.isArray(body) || body[0] !== "block") {
13054
13510
  let code = this.emit(body, "value");
13055
13511
  if (code[0] === "{")
13056
13512
  code = `(${code})`;
13057
- return `${prefix}${paramSyntax} => ${code}`;
13513
+ return `${prefix}${paramSyntax}${ret} => ${code}`;
13058
13514
  }
13059
13515
  }
13060
13516
  let bodyCode = this.emitFunctionBody(body, params, sideEffectOnly);
13061
- return `${prefix}${paramSyntax} => ${bodyCode}`;
13517
+ return `${prefix}${paramSyntax}${ret} => ${bodyCode}`;
13062
13518
  }
13063
13519
  emitReturn(head, rest, context, sexpr) {
13064
13520
  if (rest.length === 0)
@@ -16467,8 +16923,8 @@ if (typeof globalThis !== 'undefined') {
16467
16923
  return new CodeEmitter({}).getComponentRuntime();
16468
16924
  }
16469
16925
  // src/browser.js
16470
- var VERSION = "3.16.3";
16471
- var BUILD_DATE = "2026-06-27@12:04:52GMT";
16926
+ var VERSION = "3.17.1";
16927
+ var BUILD_DATE = "2026-06-28@00:08:17GMT";
16472
16928
  if (typeof globalThis !== "undefined") {
16473
16929
  if (!globalThis.__rip)
16474
16930
  new Function(getReactiveRuntime())();