@noya-app/noya-api-client-react 0.1.42 → 0.1.44
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +15 -0
- package/dist/index.js +3523 -226
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3548 -251
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5134,17 +5134,17 @@ var TypeSystemDuplicateFormat = class extends TypeBoxError {
|
|
|
5134
5134
|
};
|
|
5135
5135
|
var TypeSystem;
|
|
5136
5136
|
(function(TypeSystem2) {
|
|
5137
|
-
function
|
|
5137
|
+
function Type3(kind, check2) {
|
|
5138
5138
|
if (type_exports2.Has(kind))
|
|
5139
5139
|
throw new TypeSystemDuplicateTypeKind(kind);
|
|
5140
|
-
type_exports2.Set(kind,
|
|
5140
|
+
type_exports2.Set(kind, check2);
|
|
5141
5141
|
return (options = {}) => Unsafe({ ...options, [Kind]: kind });
|
|
5142
5142
|
}
|
|
5143
|
-
TypeSystem2.Type =
|
|
5144
|
-
function Format(format,
|
|
5143
|
+
TypeSystem2.Type = Type3;
|
|
5144
|
+
function Format(format, check2) {
|
|
5145
5145
|
if (format_exports.Has(format))
|
|
5146
5146
|
throw new TypeSystemDuplicateFormat(format);
|
|
5147
|
-
format_exports.Set(format,
|
|
5147
|
+
format_exports.Set(format, check2);
|
|
5148
5148
|
return format;
|
|
5149
5149
|
}
|
|
5150
5150
|
TypeSystem2.Format = Format;
|
|
@@ -5717,11 +5717,8 @@ function validateUUID(value) {
|
|
|
5717
5717
|
format_exports.Set("color", () => true);
|
|
5718
5718
|
format_exports.Set("uuid", validateUUID);
|
|
5719
5719
|
|
|
5720
|
-
// ../state-manager/src/ConnectedUsersManager.ts
|
|
5721
|
-
var import_observable4 = require("@noya-app/observable");
|
|
5722
|
-
|
|
5723
5720
|
// ../state-manager/src/ConnectionEventManager.ts
|
|
5724
|
-
var
|
|
5721
|
+
var import_observable4 = require("@noya-app/observable");
|
|
5725
5722
|
|
|
5726
5723
|
// ../../node_modules/mutative/dist/mutative.esm.mjs
|
|
5727
5724
|
var PROXY_DRAFT = Symbol.for("__MUTATIVE_PROXY_DRAFT__");
|
|
@@ -7314,7 +7311,7 @@ var import_noya_utils4 = require("@noya-app/noya-utils");
|
|
|
7314
7311
|
|
|
7315
7312
|
// ../state-manager/src/FilePropertyManager.ts
|
|
7316
7313
|
var import_noya_utils5 = require("@noya-app/noya-utils");
|
|
7317
|
-
var
|
|
7314
|
+
var import_observable5 = require("@noya-app/observable");
|
|
7318
7315
|
|
|
7319
7316
|
// ../state-manager/src/historyEntries.ts
|
|
7320
7317
|
var HistoryEntries;
|
|
@@ -7403,7 +7400,7 @@ var HistoryEntries;
|
|
|
7403
7400
|
})(HistoryEntries || (HistoryEntries = {}));
|
|
7404
7401
|
|
|
7405
7402
|
// ../state-manager/src/IOManager.ts
|
|
7406
|
-
var
|
|
7403
|
+
var import_observable6 = require("@noya-app/observable");
|
|
7407
7404
|
|
|
7408
7405
|
// ../state-manager/src/jwt.ts
|
|
7409
7406
|
function base64UrlEncode(str) {
|
|
@@ -7464,69 +7461,3086 @@ async function decodeJwt({
|
|
|
7464
7461
|
if (typeof token !== "string") {
|
|
7465
7462
|
throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
|
|
7466
7463
|
}
|
|
7467
|
-
const [encodedHeader, encodedPayload, encodedSignature] = token.split(".");
|
|
7468
|
-
if (!encodedHeader || !encodedPayload || !encodedSignature) {
|
|
7469
|
-
throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
|
|
7464
|
+
const [encodedHeader, encodedPayload, encodedSignature] = token.split(".");
|
|
7465
|
+
if (!encodedHeader || !encodedPayload || !encodedSignature) {
|
|
7466
|
+
throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
|
|
7467
|
+
}
|
|
7468
|
+
const headerJson = base64UrlDecode(encodedHeader);
|
|
7469
|
+
const payloadJson = base64UrlDecode(encodedPayload);
|
|
7470
|
+
const header = JSON.parse(headerJson);
|
|
7471
|
+
const payload = JSON.parse(payloadJson);
|
|
7472
|
+
const dataToVerify = `${encodedHeader}.${encodedPayload}`;
|
|
7473
|
+
const encoder = new TextEncoder();
|
|
7474
|
+
if (secret !== void 0) {
|
|
7475
|
+
const key = await crypto.subtle.importKey(
|
|
7476
|
+
"raw",
|
|
7477
|
+
encoder.encode(secret),
|
|
7478
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
7479
|
+
false,
|
|
7480
|
+
["verify"]
|
|
7481
|
+
);
|
|
7482
|
+
const binarySignature = base64UrlDecode(encodedSignature);
|
|
7483
|
+
const signature = new Uint8Array(
|
|
7484
|
+
[...binarySignature].map((char) => char.charCodeAt(0))
|
|
7485
|
+
);
|
|
7486
|
+
const valid = await crypto.subtle.verify(
|
|
7487
|
+
"HMAC",
|
|
7488
|
+
key,
|
|
7489
|
+
signature,
|
|
7490
|
+
encoder.encode(dataToVerify)
|
|
7491
|
+
);
|
|
7492
|
+
return { header, payload, valid };
|
|
7493
|
+
}
|
|
7494
|
+
return { header, payload, valid: false };
|
|
7495
|
+
}
|
|
7496
|
+
var jwt;
|
|
7497
|
+
((jwt2) => {
|
|
7498
|
+
jwt2.encode = createJwt;
|
|
7499
|
+
jwt2.decode = decodeJwt;
|
|
7500
|
+
jwt2.ERROR = JWT_ERROR;
|
|
7501
|
+
jwt2.DEFAULT_HEADER = HEADER;
|
|
7502
|
+
})(jwt || (jwt = {}));
|
|
7503
|
+
|
|
7504
|
+
// ../state-manager/src/LogManager.ts
|
|
7505
|
+
var import_observable7 = require("@noya-app/observable");
|
|
7506
|
+
|
|
7507
|
+
// ../state-manager/src/MenuManager.ts
|
|
7508
|
+
var import_noya_utils6 = require("@noya-app/noya-utils");
|
|
7509
|
+
var import_observable8 = require("@noya-app/observable");
|
|
7510
|
+
|
|
7511
|
+
// ../state-manager/src/multiplayer.ts
|
|
7512
|
+
var import_noya_utils8 = require("@noya-app/noya-utils");
|
|
7513
|
+
var import_observable10 = require("@noya-app/observable");
|
|
7514
|
+
|
|
7515
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/errors.js
|
|
7516
|
+
var ParseError = class extends Error {
|
|
7517
|
+
#wasConstructedWithAst = false;
|
|
7518
|
+
#node;
|
|
7519
|
+
constructor(message, node, cause) {
|
|
7520
|
+
super(message, { cause });
|
|
7521
|
+
this.name = "ParseError";
|
|
7522
|
+
this.#node = node;
|
|
7523
|
+
if (!node?.input) return;
|
|
7524
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7525
|
+
}
|
|
7526
|
+
get node() {
|
|
7527
|
+
return this.#node;
|
|
7528
|
+
}
|
|
7529
|
+
withAst(node) {
|
|
7530
|
+
if (this.#node) return this;
|
|
7531
|
+
this.#node = node;
|
|
7532
|
+
if (!node?.input) return this;
|
|
7533
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7534
|
+
return this;
|
|
7535
|
+
}
|
|
7536
|
+
};
|
|
7537
|
+
var EvaluationError = class extends Error {
|
|
7538
|
+
#node;
|
|
7539
|
+
constructor(message, node, cause) {
|
|
7540
|
+
super(message, { cause });
|
|
7541
|
+
this.name = "EvaluationError";
|
|
7542
|
+
this.#node = node;
|
|
7543
|
+
if (!node?.input) return;
|
|
7544
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7545
|
+
}
|
|
7546
|
+
get node() {
|
|
7547
|
+
return this.#node;
|
|
7548
|
+
}
|
|
7549
|
+
withAst(node) {
|
|
7550
|
+
if (this.#node) return this;
|
|
7551
|
+
this.#node = node;
|
|
7552
|
+
if (!node?.input) return this;
|
|
7553
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7554
|
+
return this;
|
|
7555
|
+
}
|
|
7556
|
+
};
|
|
7557
|
+
var TypeError2 = class extends Error {
|
|
7558
|
+
#node;
|
|
7559
|
+
constructor(message, node, cause) {
|
|
7560
|
+
super(message, { cause });
|
|
7561
|
+
this.name = "TypeError";
|
|
7562
|
+
this.#node = node;
|
|
7563
|
+
if (!node?.input) return;
|
|
7564
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7565
|
+
}
|
|
7566
|
+
get node() {
|
|
7567
|
+
return this.#node;
|
|
7568
|
+
}
|
|
7569
|
+
withAst(node) {
|
|
7570
|
+
if (this.#node) return this;
|
|
7571
|
+
this.#node = node;
|
|
7572
|
+
if (!node?.input) return this;
|
|
7573
|
+
this.message = formatErrorWithHighlight(this.message, node);
|
|
7574
|
+
return this;
|
|
7575
|
+
}
|
|
7576
|
+
};
|
|
7577
|
+
function formatErrorWithHighlight(message, node) {
|
|
7578
|
+
if (node?.pos === void 0) return message;
|
|
7579
|
+
const pos = node.pos;
|
|
7580
|
+
const input = node.input;
|
|
7581
|
+
let lineNum = 1;
|
|
7582
|
+
let currentPos = 0;
|
|
7583
|
+
let columnNum = 0;
|
|
7584
|
+
while (currentPos < pos) {
|
|
7585
|
+
if (input[currentPos] === "\n") {
|
|
7586
|
+
lineNum++;
|
|
7587
|
+
columnNum = 0;
|
|
7588
|
+
} else {
|
|
7589
|
+
columnNum++;
|
|
7590
|
+
}
|
|
7591
|
+
currentPos++;
|
|
7592
|
+
}
|
|
7593
|
+
let contextStart = pos;
|
|
7594
|
+
let contextEnd = pos;
|
|
7595
|
+
while (contextStart > 0 && input[contextStart - 1] !== "\n") contextStart--;
|
|
7596
|
+
while (contextEnd < input.length && input[contextEnd] !== "\n") contextEnd++;
|
|
7597
|
+
const line = input.slice(contextStart, contextEnd);
|
|
7598
|
+
const lineNumber = `${lineNum}`.padStart(4, " ");
|
|
7599
|
+
const spaces = " ".repeat(9 + columnNum);
|
|
7600
|
+
return `${message}
|
|
7601
|
+
|
|
7602
|
+
> ${lineNumber} | ${line}
|
|
7603
|
+
${spaces}^`;
|
|
7604
|
+
}
|
|
7605
|
+
|
|
7606
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/parser.js
|
|
7607
|
+
var TOKEN = {
|
|
7608
|
+
EOF: 0,
|
|
7609
|
+
NUMBER: 1,
|
|
7610
|
+
STRING: 2,
|
|
7611
|
+
BOOLEAN: 3,
|
|
7612
|
+
NULL: 4,
|
|
7613
|
+
IDENTIFIER: 5,
|
|
7614
|
+
PLUS: 6,
|
|
7615
|
+
MINUS: 7,
|
|
7616
|
+
MULTIPLY: 8,
|
|
7617
|
+
DIVIDE: 9,
|
|
7618
|
+
MODULO: 10,
|
|
7619
|
+
EQ: 11,
|
|
7620
|
+
NE: 12,
|
|
7621
|
+
LT: 13,
|
|
7622
|
+
LE: 14,
|
|
7623
|
+
GT: 15,
|
|
7624
|
+
GE: 16,
|
|
7625
|
+
AND: 17,
|
|
7626
|
+
OR: 18,
|
|
7627
|
+
NOT: 19,
|
|
7628
|
+
IN: 20,
|
|
7629
|
+
LPAREN: 21,
|
|
7630
|
+
RPAREN: 22,
|
|
7631
|
+
LBRACKET: 23,
|
|
7632
|
+
RBRACKET: 24,
|
|
7633
|
+
LBRACE: 25,
|
|
7634
|
+
RBRACE: 26,
|
|
7635
|
+
DOT: 27,
|
|
7636
|
+
COMMA: 28,
|
|
7637
|
+
COLON: 29,
|
|
7638
|
+
QUESTION: 30,
|
|
7639
|
+
BYTES: 31
|
|
7640
|
+
};
|
|
7641
|
+
var ASTNode = class extends Array {
|
|
7642
|
+
#pos;
|
|
7643
|
+
#input;
|
|
7644
|
+
constructor(pos, input, elements) {
|
|
7645
|
+
super();
|
|
7646
|
+
this.#pos = pos;
|
|
7647
|
+
this.#input = input;
|
|
7648
|
+
this.push(...elements);
|
|
7649
|
+
}
|
|
7650
|
+
get input() {
|
|
7651
|
+
return this.#input;
|
|
7652
|
+
}
|
|
7653
|
+
get pos() {
|
|
7654
|
+
return this.#pos;
|
|
7655
|
+
}
|
|
7656
|
+
};
|
|
7657
|
+
var TOKEN_BY_NUMBER = {};
|
|
7658
|
+
for (const key in TOKEN) TOKEN_BY_NUMBER[TOKEN[key]] = key;
|
|
7659
|
+
var RESERVED = /* @__PURE__ */ new Set([
|
|
7660
|
+
"as",
|
|
7661
|
+
"break",
|
|
7662
|
+
"const",
|
|
7663
|
+
"continue",
|
|
7664
|
+
"else",
|
|
7665
|
+
"for",
|
|
7666
|
+
"function",
|
|
7667
|
+
"if",
|
|
7668
|
+
"import",
|
|
7669
|
+
"let",
|
|
7670
|
+
"loop",
|
|
7671
|
+
"package",
|
|
7672
|
+
"namespace",
|
|
7673
|
+
"return",
|
|
7674
|
+
"var",
|
|
7675
|
+
"void",
|
|
7676
|
+
"while"
|
|
7677
|
+
]);
|
|
7678
|
+
var HEX_CODES = new Uint8Array(256);
|
|
7679
|
+
for (const ch of "0123456789abcdefABCDEF") HEX_CODES[ch.charCodeAt(0)] = 1;
|
|
7680
|
+
var IDENTIFIER_CODES = new Uint8Array(256);
|
|
7681
|
+
for (const ch of "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_") {
|
|
7682
|
+
IDENTIFIER_CODES[ch.charCodeAt(0)] = 1;
|
|
7683
|
+
}
|
|
7684
|
+
var STRING_ESCAPES = {
|
|
7685
|
+
"\\": "\\",
|
|
7686
|
+
"?": "?",
|
|
7687
|
+
'"': '"',
|
|
7688
|
+
"'": "'",
|
|
7689
|
+
"`": "`",
|
|
7690
|
+
a: "\x07",
|
|
7691
|
+
b: "\b",
|
|
7692
|
+
f: "\f",
|
|
7693
|
+
n: "\n",
|
|
7694
|
+
r: "\r",
|
|
7695
|
+
t: " ",
|
|
7696
|
+
v: "\v"
|
|
7697
|
+
};
|
|
7698
|
+
var Lexer = class {
|
|
7699
|
+
constructor(input) {
|
|
7700
|
+
this.input = input;
|
|
7701
|
+
this.pos = 0;
|
|
7702
|
+
this.length = input.length;
|
|
7703
|
+
}
|
|
7704
|
+
// Read next token
|
|
7705
|
+
nextToken() {
|
|
7706
|
+
if (this.pos >= this.length) return { type: TOKEN.EOF, value: null, pos: this.pos };
|
|
7707
|
+
const ch = this.input[this.pos];
|
|
7708
|
+
const next = this.input[this.pos + 1];
|
|
7709
|
+
switch (ch) {
|
|
7710
|
+
// Whitespaces
|
|
7711
|
+
case " ":
|
|
7712
|
+
case " ":
|
|
7713
|
+
case "\n":
|
|
7714
|
+
case "\r":
|
|
7715
|
+
this.pos++;
|
|
7716
|
+
return this.nextToken();
|
|
7717
|
+
// Operators
|
|
7718
|
+
case "=":
|
|
7719
|
+
if (next !== "=") break;
|
|
7720
|
+
return { type: TOKEN.EQ, value: "==", pos: (this.pos += 2) - 2 };
|
|
7721
|
+
case "&":
|
|
7722
|
+
if (next !== "&") break;
|
|
7723
|
+
return { type: TOKEN.AND, value: "&&", pos: (this.pos += 2) - 2 };
|
|
7724
|
+
case "|":
|
|
7725
|
+
if (next !== "|") break;
|
|
7726
|
+
return { type: TOKEN.OR, value: "||", pos: (this.pos += 2) - 2 };
|
|
7727
|
+
case "+":
|
|
7728
|
+
return { type: TOKEN.PLUS, value: "+", pos: this.pos++ };
|
|
7729
|
+
case "-":
|
|
7730
|
+
return { type: TOKEN.MINUS, value: "-", pos: this.pos++ };
|
|
7731
|
+
case "*":
|
|
7732
|
+
return { type: TOKEN.MULTIPLY, value: "*", pos: this.pos++ };
|
|
7733
|
+
case "/":
|
|
7734
|
+
if (next === "/") {
|
|
7735
|
+
while (this.pos < this.length && this.input[this.pos] !== "\n") this.pos++;
|
|
7736
|
+
return this.nextToken();
|
|
7737
|
+
}
|
|
7738
|
+
return { type: TOKEN.DIVIDE, value: "/", pos: this.pos++ };
|
|
7739
|
+
case "%":
|
|
7740
|
+
return { type: TOKEN.MODULO, value: "%", pos: this.pos++ };
|
|
7741
|
+
case "<":
|
|
7742
|
+
if (next === "=") return { type: TOKEN.LE, value: "<=", pos: (this.pos += 2) - 2 };
|
|
7743
|
+
return { type: TOKEN.LT, value: "<", pos: this.pos++ };
|
|
7744
|
+
case ">":
|
|
7745
|
+
if (next === "=") return { type: TOKEN.GE, value: ">=", pos: (this.pos += 2) - 2 };
|
|
7746
|
+
return { type: TOKEN.GT, value: ">", pos: this.pos++ };
|
|
7747
|
+
case "!":
|
|
7748
|
+
if (next === "=") return { type: TOKEN.NE, value: "!=", pos: (this.pos += 2) - 2 };
|
|
7749
|
+
return { type: TOKEN.NOT, value: "!", pos: this.pos++ };
|
|
7750
|
+
case "(":
|
|
7751
|
+
return { type: TOKEN.LPAREN, value: "(", pos: this.pos++ };
|
|
7752
|
+
case ")":
|
|
7753
|
+
return { type: TOKEN.RPAREN, value: ")", pos: this.pos++ };
|
|
7754
|
+
case "[":
|
|
7755
|
+
return { type: TOKEN.LBRACKET, value: "[", pos: this.pos++ };
|
|
7756
|
+
case "]":
|
|
7757
|
+
return { type: TOKEN.RBRACKET, value: "]", pos: this.pos++ };
|
|
7758
|
+
case "{":
|
|
7759
|
+
return { type: TOKEN.LBRACE, value: "{", pos: this.pos++ };
|
|
7760
|
+
case "}":
|
|
7761
|
+
return { type: TOKEN.RBRACE, value: "}", pos: this.pos++ };
|
|
7762
|
+
case ".":
|
|
7763
|
+
return { type: TOKEN.DOT, value: ".", pos: this.pos++ };
|
|
7764
|
+
case ",":
|
|
7765
|
+
return { type: TOKEN.COMMA, value: ",", pos: this.pos++ };
|
|
7766
|
+
case ":":
|
|
7767
|
+
return { type: TOKEN.COLON, value: ":", pos: this.pos++ };
|
|
7768
|
+
case "?":
|
|
7769
|
+
return { type: TOKEN.QUESTION, value: "?", pos: this.pos++ };
|
|
7770
|
+
case `"`:
|
|
7771
|
+
case `'`:
|
|
7772
|
+
return this.readString();
|
|
7773
|
+
// Check for string prefixes (b, B, r, R followed by quote)
|
|
7774
|
+
case "b":
|
|
7775
|
+
case "B":
|
|
7776
|
+
case "r":
|
|
7777
|
+
case "R":
|
|
7778
|
+
if (next === '"' || next === "'") {
|
|
7779
|
+
this.pos++;
|
|
7780
|
+
return this.readString(ch.toLowerCase());
|
|
7781
|
+
}
|
|
7782
|
+
return this.readIdentifier();
|
|
7783
|
+
default: {
|
|
7784
|
+
if (ch >= "0" && ch <= "9") return this.readNumber();
|
|
7785
|
+
if (IDENTIFIER_CODES[ch.charCodeAt(0)]) return this.readIdentifier();
|
|
7786
|
+
}
|
|
7787
|
+
}
|
|
7788
|
+
throw new ParseError(`Unexpected character: ${ch}`, { pos: this.pos, input: this.input });
|
|
7789
|
+
}
|
|
7790
|
+
_parseAsBigInt(start, end, isHex, unsigned) {
|
|
7791
|
+
const string = this.input.substring(start, end);
|
|
7792
|
+
if (unsigned === "u" || unsigned === "U") {
|
|
7793
|
+
this.pos++;
|
|
7794
|
+
try {
|
|
7795
|
+
return {
|
|
7796
|
+
type: TOKEN.NUMBER,
|
|
7797
|
+
value: new UnsignedInt(string),
|
|
7798
|
+
pos: start
|
|
7799
|
+
};
|
|
7800
|
+
} catch (_err) {
|
|
7801
|
+
}
|
|
7802
|
+
} else {
|
|
7803
|
+
try {
|
|
7804
|
+
return {
|
|
7805
|
+
type: TOKEN.NUMBER,
|
|
7806
|
+
value: BigInt(string),
|
|
7807
|
+
pos: start
|
|
7808
|
+
};
|
|
7809
|
+
} catch (_err) {
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
throw new ParseError(isHex ? `Invalid hex integer: ${string}` : `Invalid integer: ${string}`, {
|
|
7813
|
+
pos: start,
|
|
7814
|
+
input: this.input
|
|
7815
|
+
});
|
|
7816
|
+
}
|
|
7817
|
+
readNumber() {
|
|
7818
|
+
const { input, length, pos: start } = this;
|
|
7819
|
+
if (input[start] === "0" && (input[start + 1] === "x" || input[start + 1] === "X")) {
|
|
7820
|
+
this.pos += 2;
|
|
7821
|
+
while (this.pos < length && HEX_CODES[input[this.pos].charCodeAt(0)]) this.pos++;
|
|
7822
|
+
return this._parseAsBigInt(start, this.pos, true, input[this.pos]);
|
|
7823
|
+
}
|
|
7824
|
+
let ch;
|
|
7825
|
+
while (this.pos < length && (ch = input[this.pos]) >= "0" && ch <= "9") this.pos++;
|
|
7826
|
+
if (ch === "." && (ch = input[this.pos + 1]) >= "0" && ch <= "9") {
|
|
7827
|
+
this.pos++;
|
|
7828
|
+
while (this.pos < length && (ch = input[this.pos]) >= "0" && ch <= "9") this.pos++;
|
|
7829
|
+
const string = input.substring(start, this.pos);
|
|
7830
|
+
const value = Number(string);
|
|
7831
|
+
if (Number.isFinite(value)) return { type: TOKEN.NUMBER, value, pos: start };
|
|
7832
|
+
throw new ParseError(`Invalid number: ${value}`, { pos: start, input: this.input });
|
|
7833
|
+
}
|
|
7834
|
+
return this._parseAsBigInt(start, this.pos, false, input[this.pos]);
|
|
7835
|
+
}
|
|
7836
|
+
readString(prefix) {
|
|
7837
|
+
const delimiter = this.input[this.pos++];
|
|
7838
|
+
if (this.input[this.pos] === delimiter && this.input[this.pos + 1] === delimiter) {
|
|
7839
|
+
this.pos += 2;
|
|
7840
|
+
return this.readTripleQuotedString(delimiter, prefix);
|
|
7841
|
+
}
|
|
7842
|
+
return this.readSingleQuotedString(delimiter, prefix);
|
|
7843
|
+
}
|
|
7844
|
+
_closeQuotedString(rawValue, prefix) {
|
|
7845
|
+
if (prefix === "b") {
|
|
7846
|
+
const processed = this.processEscapes(rawValue, true);
|
|
7847
|
+
const bytes = new Uint8Array(processed.length);
|
|
7848
|
+
for (let i = 0; i < processed.length; i++) {
|
|
7849
|
+
bytes[i] = processed.charCodeAt(i) & 255;
|
|
7850
|
+
}
|
|
7851
|
+
return { type: TOKEN.BYTES, value: bytes, pos: this.pos - rawValue.length - 2 };
|
|
7852
|
+
}
|
|
7853
|
+
const value = prefix === "r" ? rawValue : this.processEscapes(rawValue, false);
|
|
7854
|
+
return { type: TOKEN.STRING, value, pos: this.pos - rawValue.length };
|
|
7855
|
+
}
|
|
7856
|
+
readSingleQuotedString(delimiter, prefix) {
|
|
7857
|
+
const { input, length, pos: start } = this;
|
|
7858
|
+
const needsEscapeHandling = prefix !== "r";
|
|
7859
|
+
while (this.pos < length) {
|
|
7860
|
+
const ch = input[this.pos];
|
|
7861
|
+
if (ch === delimiter) {
|
|
7862
|
+
const rawValue = input.slice(start, this.pos);
|
|
7863
|
+
this.pos++;
|
|
7864
|
+
return this._closeQuotedString(rawValue, prefix);
|
|
7865
|
+
}
|
|
7866
|
+
if (ch === "\n" || ch === "\r") {
|
|
7867
|
+
throw new ParseError("Newlines not allowed in single-quoted strings", {
|
|
7868
|
+
pos: start - 1,
|
|
7869
|
+
input
|
|
7870
|
+
});
|
|
7871
|
+
}
|
|
7872
|
+
if (ch === "\\" && needsEscapeHandling) {
|
|
7873
|
+
this.pos += 2;
|
|
7874
|
+
if (this.pos > length) {
|
|
7875
|
+
throw new ParseError("Unterminated escape sequence", {
|
|
7876
|
+
pos: start - 1,
|
|
7877
|
+
input
|
|
7878
|
+
});
|
|
7879
|
+
}
|
|
7880
|
+
continue;
|
|
7881
|
+
}
|
|
7882
|
+
this.pos++;
|
|
7883
|
+
}
|
|
7884
|
+
throw new ParseError("Unterminated string", { pos: start - 1, input });
|
|
7885
|
+
}
|
|
7886
|
+
readTripleQuotedString(delimiter, prefix) {
|
|
7887
|
+
const start = this.pos;
|
|
7888
|
+
const needsEscapeHandling = prefix !== "r";
|
|
7889
|
+
while (this.pos < this.length) {
|
|
7890
|
+
const ch = this.input[this.pos];
|
|
7891
|
+
if (ch === delimiter && this.input[this.pos + 1] === delimiter && this.input[this.pos + 2] === delimiter) {
|
|
7892
|
+
const rawValue = this.input.slice(start, this.pos);
|
|
7893
|
+
this.pos += 3;
|
|
7894
|
+
return this._closeQuotedString(rawValue, prefix);
|
|
7895
|
+
}
|
|
7896
|
+
if (ch === "\\" && needsEscapeHandling) {
|
|
7897
|
+
this.pos += 2;
|
|
7898
|
+
if (this.pos > this.length) {
|
|
7899
|
+
throw new ParseError("Unterminated escape sequence", {
|
|
7900
|
+
pos: start - 3,
|
|
7901
|
+
input: this.input
|
|
7902
|
+
});
|
|
7903
|
+
}
|
|
7904
|
+
continue;
|
|
7905
|
+
}
|
|
7906
|
+
this.pos++;
|
|
7907
|
+
}
|
|
7908
|
+
throw new ParseError("Unterminated triple-quoted string", { pos: start - 3, input: this.input });
|
|
7909
|
+
}
|
|
7910
|
+
processEscapes(str, isBytes) {
|
|
7911
|
+
let result = "";
|
|
7912
|
+
let i = 0;
|
|
7913
|
+
while (i < str.length) {
|
|
7914
|
+
if (str[i] !== "\\" || i + 1 >= str.length) {
|
|
7915
|
+
result += str[i++];
|
|
7916
|
+
continue;
|
|
7917
|
+
}
|
|
7918
|
+
const next = str[i + 1];
|
|
7919
|
+
if (STRING_ESCAPES[next]) {
|
|
7920
|
+
result += STRING_ESCAPES[next];
|
|
7921
|
+
i += 2;
|
|
7922
|
+
} else if (next === "u") {
|
|
7923
|
+
if (isBytes) throw new ParseError("\\u not allowed in bytes literals");
|
|
7924
|
+
const hex = str.substring(i + 2, i + 6);
|
|
7925
|
+
if (hex.length !== 4 || !/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
7926
|
+
throw new ParseError(`Invalid Unicode escape: \\u${hex}`);
|
|
7927
|
+
}
|
|
7928
|
+
const code = Number.parseInt(hex, 16);
|
|
7929
|
+
if (code >= 55296 && code <= 57343) {
|
|
7930
|
+
throw new ParseError(`Invalid Unicode surrogate: \\u${hex}`);
|
|
7931
|
+
}
|
|
7932
|
+
result += String.fromCharCode(code);
|
|
7933
|
+
i += 6;
|
|
7934
|
+
} else if (next === "U") {
|
|
7935
|
+
if (isBytes) throw new ParseError("\\U not allowed in bytes literals");
|
|
7936
|
+
const hex = str.substring(i + 2, i + 10);
|
|
7937
|
+
if (hex.length !== 8 || !/^[0-9a-fA-F]{8}$/.test(hex)) {
|
|
7938
|
+
throw new ParseError(`Invalid Unicode escape: \\U${hex}`);
|
|
7939
|
+
}
|
|
7940
|
+
const code = Number.parseInt(hex, 16);
|
|
7941
|
+
if (code > 1114111) throw new ParseError(`Invalid Unicode escape: \\U${hex}`);
|
|
7942
|
+
if (code >= 55296 && code <= 57343) {
|
|
7943
|
+
throw new ParseError(`Invalid Unicode surrogate: \\U${hex}`);
|
|
7944
|
+
}
|
|
7945
|
+
result += String.fromCodePoint(code);
|
|
7946
|
+
i += 10;
|
|
7947
|
+
} else if (next === "x" || next === "X") {
|
|
7948
|
+
const hex = str.substring(i + 2, i + 4);
|
|
7949
|
+
if (hex.length !== 2 || !/^[0-9a-fA-F]{2}$/.test(hex)) {
|
|
7950
|
+
throw new ParseError(`Invalid hex escape: \\${next}${hex}`);
|
|
7951
|
+
}
|
|
7952
|
+
result += String.fromCharCode(Number.parseInt(hex, 16));
|
|
7953
|
+
i += 4;
|
|
7954
|
+
} else if (next >= "0" && next <= "7") {
|
|
7955
|
+
const octal = str.substring(i + 1, i + 4);
|
|
7956
|
+
if (octal.length !== 3 || !/^[0-7]{3}$/.test(octal)) {
|
|
7957
|
+
throw new ParseError("Octal escape must be 3 digits");
|
|
7958
|
+
}
|
|
7959
|
+
const value = Number.parseInt(octal, 8);
|
|
7960
|
+
if (value > 255) {
|
|
7961
|
+
throw new ParseError(`Octal escape out of range: \\${octal}`);
|
|
7962
|
+
}
|
|
7963
|
+
result += String.fromCharCode(value);
|
|
7964
|
+
i += 4;
|
|
7965
|
+
} else {
|
|
7966
|
+
throw new ParseError(`Invalid escape sequence: \\${next}`);
|
|
7967
|
+
}
|
|
7968
|
+
}
|
|
7969
|
+
return result;
|
|
7970
|
+
}
|
|
7971
|
+
readIdentifier() {
|
|
7972
|
+
const start = this.pos;
|
|
7973
|
+
while (this.pos < this.length && IDENTIFIER_CODES[this.input[this.pos].charCodeAt(0)])
|
|
7974
|
+
this.pos++;
|
|
7975
|
+
const text = this.input.substring(start, this.pos);
|
|
7976
|
+
switch (text) {
|
|
7977
|
+
case "true":
|
|
7978
|
+
return { type: TOKEN.BOOLEAN, value: true, pos: start };
|
|
7979
|
+
case "false":
|
|
7980
|
+
return { type: TOKEN.BOOLEAN, value: false, pos: start };
|
|
7981
|
+
case "null":
|
|
7982
|
+
return { type: TOKEN.NULL, value: null, pos: start };
|
|
7983
|
+
case "in":
|
|
7984
|
+
return { type: TOKEN.IN, value: "in", pos: start };
|
|
7985
|
+
default:
|
|
7986
|
+
return { type: TOKEN.IDENTIFIER, value: text, pos: start };
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
};
|
|
7990
|
+
var Parser = class {
|
|
7991
|
+
constructor(input) {
|
|
7992
|
+
this.input = input;
|
|
7993
|
+
this.lexer = new Lexer(input);
|
|
7994
|
+
this.currentToken = this.lexer.nextToken();
|
|
7995
|
+
}
|
|
7996
|
+
consume(expectedType) {
|
|
7997
|
+
const token = this.currentToken;
|
|
7998
|
+
this.currentToken = this.lexer.nextToken();
|
|
7999
|
+
if (token.type === expectedType) return token;
|
|
8000
|
+
throw new ParseError(
|
|
8001
|
+
`Expected ${TOKEN_BY_NUMBER[expectedType]}, got ${TOKEN_BY_NUMBER[token.type]}`,
|
|
8002
|
+
{ pos: token.pos, input: this.input }
|
|
8003
|
+
);
|
|
8004
|
+
}
|
|
8005
|
+
match(type) {
|
|
8006
|
+
return this.currentToken.type === type;
|
|
8007
|
+
}
|
|
8008
|
+
// Parse entry point
|
|
8009
|
+
parse() {
|
|
8010
|
+
const result = this.parseExpression();
|
|
8011
|
+
if (!this.match(TOKEN.EOF)) {
|
|
8012
|
+
throw new ParseError(`Unexpected character: '${this.input[this.lexer.pos - 1]}'`, {
|
|
8013
|
+
pos: this.currentToken.pos,
|
|
8014
|
+
input: this.input
|
|
8015
|
+
});
|
|
8016
|
+
}
|
|
8017
|
+
return result;
|
|
8018
|
+
}
|
|
8019
|
+
// Expression ::= LogicalOr ('?' Expression ':' Expression)? // Made right-associative
|
|
8020
|
+
parseExpression() {
|
|
8021
|
+
const expr = this.parseLogicalOr();
|
|
8022
|
+
if (this.match(TOKEN.QUESTION)) {
|
|
8023
|
+
const token = this.consume(TOKEN.QUESTION);
|
|
8024
|
+
const consequent = this.parseExpression();
|
|
8025
|
+
this.consume(TOKEN.COLON);
|
|
8026
|
+
return new ASTNode(token.pos, this.input, ["?:", expr, consequent, this.parseExpression()]);
|
|
8027
|
+
}
|
|
8028
|
+
return expr;
|
|
8029
|
+
}
|
|
8030
|
+
// LogicalOr ::= LogicalAnd ('||' LogicalAnd)*
|
|
8031
|
+
parseLogicalOr() {
|
|
8032
|
+
let expr = this.parseLogicalAnd();
|
|
8033
|
+
while (this.match(TOKEN.OR)) {
|
|
8034
|
+
const token = this.consume(TOKEN.OR);
|
|
8035
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseLogicalAnd()]);
|
|
8036
|
+
}
|
|
8037
|
+
return expr;
|
|
8038
|
+
}
|
|
8039
|
+
// LogicalAnd ::= Equality ('&&' Equality)*
|
|
8040
|
+
parseLogicalAnd() {
|
|
8041
|
+
let expr = this.parseEquality();
|
|
8042
|
+
while (this.match(TOKEN.AND)) {
|
|
8043
|
+
const token = this.consume(TOKEN.AND);
|
|
8044
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseEquality()]);
|
|
8045
|
+
}
|
|
8046
|
+
return expr;
|
|
8047
|
+
}
|
|
8048
|
+
// Equality ::= Relational (('==' | '!=') Relational)*
|
|
8049
|
+
parseEquality() {
|
|
8050
|
+
let expr = this.parseRelational();
|
|
8051
|
+
while (this.match(TOKEN.EQ) || this.match(TOKEN.NE)) {
|
|
8052
|
+
const token = this.currentToken;
|
|
8053
|
+
this.currentToken = this.lexer.nextToken();
|
|
8054
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseRelational()]);
|
|
8055
|
+
}
|
|
8056
|
+
return expr;
|
|
8057
|
+
}
|
|
8058
|
+
// Relational ::= Additive (('<' | '<=' | '>' | '>=' | 'in') Additive)*
|
|
8059
|
+
parseRelational() {
|
|
8060
|
+
let expr = this.parseAdditive();
|
|
8061
|
+
while (this.match(TOKEN.LT) || this.match(TOKEN.LE) || this.match(TOKEN.GT) || this.match(TOKEN.GE) || this.match(TOKEN.IN)) {
|
|
8062
|
+
const token = this.currentToken;
|
|
8063
|
+
this.currentToken = this.lexer.nextToken();
|
|
8064
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseAdditive()]);
|
|
8065
|
+
}
|
|
8066
|
+
return expr;
|
|
8067
|
+
}
|
|
8068
|
+
// Additive ::= Multiplicative (('+' | '-') Multiplicative)*
|
|
8069
|
+
parseAdditive() {
|
|
8070
|
+
let expr = this.parseMultiplicative();
|
|
8071
|
+
while (this.match(TOKEN.PLUS) || this.match(TOKEN.MINUS)) {
|
|
8072
|
+
const token = this.currentToken;
|
|
8073
|
+
this.currentToken = this.lexer.nextToken();
|
|
8074
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseMultiplicative()]);
|
|
8075
|
+
}
|
|
8076
|
+
return expr;
|
|
8077
|
+
}
|
|
8078
|
+
// Multiplicative ::= Unary (('*' | '/' | '%') Unary)*
|
|
8079
|
+
parseMultiplicative() {
|
|
8080
|
+
let expr = this.parseUnary();
|
|
8081
|
+
while (this.match(TOKEN.MULTIPLY) || this.match(TOKEN.DIVIDE) || this.match(TOKEN.MODULO)) {
|
|
8082
|
+
const token = this.currentToken;
|
|
8083
|
+
this.currentToken = this.lexer.nextToken();
|
|
8084
|
+
expr = new ASTNode(token.pos, this.input, [token.value, expr, this.parseUnary()]);
|
|
8085
|
+
}
|
|
8086
|
+
return expr;
|
|
8087
|
+
}
|
|
8088
|
+
// Unary ::= ('!' | '-')* Postfix
|
|
8089
|
+
parseUnary() {
|
|
8090
|
+
const token = this.currentToken;
|
|
8091
|
+
if (token.type === TOKEN.NOT) {
|
|
8092
|
+
this.currentToken = this.lexer.nextToken();
|
|
8093
|
+
return new ASTNode(token.pos, this.input, ["!_", this.parseUnary()]);
|
|
8094
|
+
}
|
|
8095
|
+
if (token.type === TOKEN.MINUS) {
|
|
8096
|
+
this.currentToken = this.lexer.nextToken();
|
|
8097
|
+
return new ASTNode(token.pos, this.input, ["-_", this.parseUnary()]);
|
|
8098
|
+
}
|
|
8099
|
+
return this.parsePostfix();
|
|
8100
|
+
}
|
|
8101
|
+
assertReservedIdentifier(property) {
|
|
8102
|
+
if (!RESERVED.has(property.value)) return;
|
|
8103
|
+
throw new ParseError(`Reserved identifier: ${property.value}`, {
|
|
8104
|
+
pos: property.pos,
|
|
8105
|
+
input: this.input
|
|
8106
|
+
});
|
|
8107
|
+
}
|
|
8108
|
+
// Postfix ::= Primary (('.' IDENTIFIER ('(' ArgumentList ')')? | '[' Expression ']'))*
|
|
8109
|
+
parsePostfix() {
|
|
8110
|
+
let expr = this.parsePrimary();
|
|
8111
|
+
while (true) {
|
|
8112
|
+
if (this.match(TOKEN.DOT)) {
|
|
8113
|
+
this.consume(TOKEN.DOT);
|
|
8114
|
+
const property = this.consume(TOKEN.IDENTIFIER);
|
|
8115
|
+
if (this.match(TOKEN.LPAREN)) {
|
|
8116
|
+
this.consume(TOKEN.LPAREN);
|
|
8117
|
+
const args = this.parseArgumentList();
|
|
8118
|
+
this.consume(TOKEN.RPAREN);
|
|
8119
|
+
expr = new ASTNode(property.pos, this.input, ["rcall", property.value, expr, args]);
|
|
8120
|
+
} else {
|
|
8121
|
+
expr = new ASTNode(property.pos, this.input, [".", expr, property.value]);
|
|
8122
|
+
}
|
|
8123
|
+
} else if (this.match(TOKEN.LBRACKET)) {
|
|
8124
|
+
const token = this.consume(TOKEN.LBRACKET);
|
|
8125
|
+
const index = this.parseExpression();
|
|
8126
|
+
this.consume(TOKEN.RBRACKET);
|
|
8127
|
+
expr = new ASTNode(token.pos, this.input, ["[]", expr, index]);
|
|
8128
|
+
} else {
|
|
8129
|
+
break;
|
|
8130
|
+
}
|
|
8131
|
+
}
|
|
8132
|
+
return expr;
|
|
8133
|
+
}
|
|
8134
|
+
// Primary ::= NUMBER | STRING | BOOLEAN | NULL | IDENTIFIER | '(' Expression ')' | Array | Object
|
|
8135
|
+
parsePrimary() {
|
|
8136
|
+
switch (this.currentToken.type) {
|
|
8137
|
+
case TOKEN.NUMBER: {
|
|
8138
|
+
const token = this.consume(TOKEN.NUMBER);
|
|
8139
|
+
return new ASTNode(token.pos, this.input, ["value", token.value]);
|
|
8140
|
+
}
|
|
8141
|
+
case TOKEN.STRING: {
|
|
8142
|
+
const token = this.consume(TOKEN.STRING);
|
|
8143
|
+
return new ASTNode(token.pos, this.input, ["value", token.value]);
|
|
8144
|
+
}
|
|
8145
|
+
case TOKEN.BYTES: {
|
|
8146
|
+
const token = this.consume(TOKEN.BYTES);
|
|
8147
|
+
return new ASTNode(token.pos, this.input, ["value", token.value]);
|
|
8148
|
+
}
|
|
8149
|
+
case TOKEN.BOOLEAN: {
|
|
8150
|
+
const token = this.consume(TOKEN.BOOLEAN);
|
|
8151
|
+
return new ASTNode(token.pos, this.input, ["value", token.value]);
|
|
8152
|
+
}
|
|
8153
|
+
case TOKEN.NULL: {
|
|
8154
|
+
const token = this.consume(TOKEN.NULL);
|
|
8155
|
+
return new ASTNode(token.pos, this.input, ["value", token.value]);
|
|
8156
|
+
}
|
|
8157
|
+
case TOKEN.IDENTIFIER: {
|
|
8158
|
+
const identifier = this.consume(TOKEN.IDENTIFIER);
|
|
8159
|
+
this.assertReservedIdentifier(identifier);
|
|
8160
|
+
if (this.match(TOKEN.LPAREN)) {
|
|
8161
|
+
this.consume(TOKEN.LPAREN);
|
|
8162
|
+
const args = this.parseArgumentList();
|
|
8163
|
+
this.consume(TOKEN.RPAREN);
|
|
8164
|
+
return new ASTNode(identifier.pos, this.input, ["call", identifier.value, args]);
|
|
8165
|
+
}
|
|
8166
|
+
return new ASTNode(identifier.pos, this.input, ["id", identifier.value]);
|
|
8167
|
+
}
|
|
8168
|
+
case TOKEN.LPAREN: {
|
|
8169
|
+
this.consume(TOKEN.LPAREN);
|
|
8170
|
+
const expr = this.parseExpression();
|
|
8171
|
+
this.consume(TOKEN.RPAREN);
|
|
8172
|
+
return expr;
|
|
8173
|
+
}
|
|
8174
|
+
case TOKEN.LBRACKET:
|
|
8175
|
+
return this.parseList();
|
|
8176
|
+
case TOKEN.LBRACE:
|
|
8177
|
+
return this.parseMap();
|
|
8178
|
+
}
|
|
8179
|
+
throw new ParseError(`Unexpected token: ${TOKEN_BY_NUMBER[this.currentToken.type]}`, {
|
|
8180
|
+
pos: this.currentToken.pos,
|
|
8181
|
+
input: this.input
|
|
8182
|
+
});
|
|
8183
|
+
}
|
|
8184
|
+
parseList() {
|
|
8185
|
+
const token = this.consume(TOKEN.LBRACKET);
|
|
8186
|
+
const elements = [];
|
|
8187
|
+
if (!this.match(TOKEN.RBRACKET)) {
|
|
8188
|
+
elements.push(this.parseExpression());
|
|
8189
|
+
while (this.match(TOKEN.COMMA)) {
|
|
8190
|
+
this.consume(TOKEN.COMMA);
|
|
8191
|
+
if (!this.match(TOKEN.RBRACKET)) {
|
|
8192
|
+
elements.push(this.parseExpression());
|
|
8193
|
+
}
|
|
8194
|
+
}
|
|
8195
|
+
}
|
|
8196
|
+
this.consume(TOKEN.RBRACKET);
|
|
8197
|
+
return new ASTNode(token.pos, this.input, ["list", elements]);
|
|
8198
|
+
}
|
|
8199
|
+
parseMap() {
|
|
8200
|
+
const token = this.consume(TOKEN.LBRACE);
|
|
8201
|
+
const properties = [];
|
|
8202
|
+
if (!this.match(TOKEN.RBRACE)) {
|
|
8203
|
+
properties.push(this.parseProperty());
|
|
8204
|
+
while (this.match(TOKEN.COMMA)) {
|
|
8205
|
+
this.consume(TOKEN.COMMA);
|
|
8206
|
+
if (!this.match(TOKEN.RBRACE)) {
|
|
8207
|
+
properties.push(this.parseProperty());
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
}
|
|
8211
|
+
this.consume(TOKEN.RBRACE);
|
|
8212
|
+
return new ASTNode(token.pos, this.input, ["map", properties]);
|
|
8213
|
+
}
|
|
8214
|
+
parseProperty() {
|
|
8215
|
+
const key = this.parseExpression();
|
|
8216
|
+
this.consume(TOKEN.COLON);
|
|
8217
|
+
const value = this.parseExpression();
|
|
8218
|
+
return [key, value];
|
|
8219
|
+
}
|
|
8220
|
+
parseArgumentList() {
|
|
8221
|
+
const args = [];
|
|
8222
|
+
if (!this.match(TOKEN.RPAREN)) {
|
|
8223
|
+
args.push(this.parseExpression());
|
|
8224
|
+
while (this.match(TOKEN.COMMA)) {
|
|
8225
|
+
this.consume(TOKEN.COMMA);
|
|
8226
|
+
if (!this.match(TOKEN.RPAREN)) {
|
|
8227
|
+
args.push(this.parseExpression());
|
|
8228
|
+
}
|
|
8229
|
+
}
|
|
8230
|
+
}
|
|
8231
|
+
return args;
|
|
8232
|
+
}
|
|
8233
|
+
};
|
|
8234
|
+
|
|
8235
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/functions.js
|
|
8236
|
+
var UnsignedInt = class {
|
|
8237
|
+
#value;
|
|
8238
|
+
constructor(value) {
|
|
8239
|
+
this.verify(BigInt(value));
|
|
8240
|
+
}
|
|
8241
|
+
get value() {
|
|
8242
|
+
return this.#value;
|
|
8243
|
+
}
|
|
8244
|
+
valueOf() {
|
|
8245
|
+
return this.#value;
|
|
8246
|
+
}
|
|
8247
|
+
verify(v) {
|
|
8248
|
+
if (v < 0n || v > 18446744073709551615n) throw new EvaluationError("Unsigned integer overflow");
|
|
8249
|
+
this.#value = v;
|
|
8250
|
+
}
|
|
8251
|
+
get [Symbol.toStringTag]() {
|
|
8252
|
+
return `value = ${this.#value}`;
|
|
8253
|
+
}
|
|
8254
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
8255
|
+
return `UnsignedInteger { value: ${this.#value} }`;
|
|
8256
|
+
}
|
|
8257
|
+
};
|
|
8258
|
+
var UNIT_NANOSECONDS = {
|
|
8259
|
+
h: 3600000000000n,
|
|
8260
|
+
m: 60000000000n,
|
|
8261
|
+
s: 1000000000n,
|
|
8262
|
+
ms: 1000000n,
|
|
8263
|
+
us: 1000n,
|
|
8264
|
+
\u00B5s: 1000n,
|
|
8265
|
+
ns: 1n
|
|
8266
|
+
};
|
|
8267
|
+
var Duration = class _Duration {
|
|
8268
|
+
#seconds;
|
|
8269
|
+
#nanos;
|
|
8270
|
+
constructor(seconds, nanos = 0) {
|
|
8271
|
+
this.#seconds = BigInt(seconds);
|
|
8272
|
+
this.#nanos = nanos;
|
|
8273
|
+
}
|
|
8274
|
+
get seconds() {
|
|
8275
|
+
return this.#seconds;
|
|
8276
|
+
}
|
|
8277
|
+
get nanos() {
|
|
8278
|
+
return this.#nanos;
|
|
8279
|
+
}
|
|
8280
|
+
valueOf() {
|
|
8281
|
+
return Number(this.#seconds) * 1e3 + this.#nanos / 1e6;
|
|
8282
|
+
}
|
|
8283
|
+
addDuration(other) {
|
|
8284
|
+
const nanos = this.#nanos + other.nanos;
|
|
8285
|
+
return new _Duration(
|
|
8286
|
+
this.#seconds + other.seconds + BigInt(Math.floor(nanos / 1e9)),
|
|
8287
|
+
nanos % 1e9
|
|
8288
|
+
);
|
|
8289
|
+
}
|
|
8290
|
+
subtractDuration(other) {
|
|
8291
|
+
const nanos = this.#nanos - other.nanos;
|
|
8292
|
+
return new _Duration(
|
|
8293
|
+
this.#seconds - other.seconds + BigInt(Math.floor(nanos / 1e9)),
|
|
8294
|
+
(nanos + 1e9) % 1e9
|
|
8295
|
+
);
|
|
8296
|
+
}
|
|
8297
|
+
extendTimestamp(ts) {
|
|
8298
|
+
return new Date(
|
|
8299
|
+
ts.getTime() + Number(this.#seconds) * 1e3 + Math.floor(this.#nanos / 1e6)
|
|
8300
|
+
);
|
|
8301
|
+
}
|
|
8302
|
+
subtractTimestamp(ts) {
|
|
8303
|
+
return new Date(
|
|
8304
|
+
ts.getTime() - Number(this.#seconds) * 1e3 - Math.floor(this.#nanos / 1e6)
|
|
8305
|
+
);
|
|
8306
|
+
}
|
|
8307
|
+
toString() {
|
|
8308
|
+
const nanos = this.#nanos ? (this.#nanos / 1e9).toLocaleString("en-US", { useGrouping: false, maximumFractionDigits: 9 }).slice(1) : "";
|
|
8309
|
+
return `${this.#seconds}${nanos}s`;
|
|
8310
|
+
}
|
|
8311
|
+
getHours() {
|
|
8312
|
+
return this.#seconds / 3600n;
|
|
8313
|
+
}
|
|
8314
|
+
getMinutes() {
|
|
8315
|
+
return this.#seconds / 60n;
|
|
8316
|
+
}
|
|
8317
|
+
getSeconds() {
|
|
8318
|
+
return this.#seconds;
|
|
8319
|
+
}
|
|
8320
|
+
getMilliseconds() {
|
|
8321
|
+
return this.#seconds * 1000n + BigInt(Math.floor(this.#nanos / 1e6));
|
|
8322
|
+
}
|
|
8323
|
+
get [Symbol.toStringTag]() {
|
|
8324
|
+
return "google.protobuf.Duration";
|
|
8325
|
+
}
|
|
8326
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
8327
|
+
return `google.protobuf.Duration { seconds: ${this.#seconds}, nanos: ${this.#nanos} }`;
|
|
8328
|
+
}
|
|
8329
|
+
};
|
|
8330
|
+
function registerFunctions(registry) {
|
|
8331
|
+
const functionOverload = (sig, handler) => registry.registerFunctionOverload(sig, handler);
|
|
8332
|
+
const identity = (v) => v;
|
|
8333
|
+
functionOverload("has(ast): bool", function(ast) {
|
|
8334
|
+
const selector = ast[2][0];
|
|
8335
|
+
if (selector[0] === ".") return hasNestedField(this, selector, ast) !== void 0;
|
|
8336
|
+
throw new EvaluationError("has() invalid argument", ast);
|
|
8337
|
+
});
|
|
8338
|
+
function hasNestedField(ev, selector, ast) {
|
|
8339
|
+
switch (selector[0]) {
|
|
8340
|
+
case "id":
|
|
8341
|
+
return ev.eval(selector);
|
|
8342
|
+
case ".": {
|
|
8343
|
+
const obj = hasNestedField(ev, selector[1], ast);
|
|
8344
|
+
if (!obj) throw new EvaluationError(`No such key: ${selector[2]}`, selector);
|
|
8345
|
+
const type = ev.debugType(obj);
|
|
8346
|
+
return type.fieldLazy(obj, selector[2], ast, ev);
|
|
8347
|
+
}
|
|
8348
|
+
}
|
|
8349
|
+
throw new EvaluationError("has() invalid argument", ast);
|
|
8350
|
+
}
|
|
8351
|
+
functionOverload("dyn(dyn): dyn", identity);
|
|
8352
|
+
for (const _t in TYPES) {
|
|
8353
|
+
const type = TYPES[_t];
|
|
8354
|
+
if (!(type instanceof Type2)) continue;
|
|
8355
|
+
functionOverload(`type(${type.name}): type`, () => type);
|
|
8356
|
+
}
|
|
8357
|
+
functionOverload("bool(bool): bool", identity);
|
|
8358
|
+
functionOverload("bool(string): bool", (v) => {
|
|
8359
|
+
switch (v) {
|
|
8360
|
+
case "1":
|
|
8361
|
+
case "t":
|
|
8362
|
+
case "true":
|
|
8363
|
+
case "TRUE":
|
|
8364
|
+
case "True":
|
|
8365
|
+
return true;
|
|
8366
|
+
case "0":
|
|
8367
|
+
case "f":
|
|
8368
|
+
case "false":
|
|
8369
|
+
case "FALSE":
|
|
8370
|
+
case "False":
|
|
8371
|
+
return false;
|
|
8372
|
+
default:
|
|
8373
|
+
throw new EvaluationError(`bool() conversion error: invalid string value "${v}"`);
|
|
8374
|
+
}
|
|
8375
|
+
});
|
|
8376
|
+
const objectKeys = Object.keys;
|
|
8377
|
+
functionOverload("size(string): int", (v) => BigInt(stringSize(v)));
|
|
8378
|
+
functionOverload("size(bytes): int", (v) => BigInt(v.length));
|
|
8379
|
+
functionOverload("size(list): int", (v) => BigInt(v.length ?? v.size));
|
|
8380
|
+
functionOverload(
|
|
8381
|
+
"size(map): int",
|
|
8382
|
+
(v) => BigInt(v instanceof Map ? v.size : objectKeys(v).length)
|
|
8383
|
+
);
|
|
8384
|
+
functionOverload("string.size(): int", (v) => BigInt(stringSize(v)));
|
|
8385
|
+
functionOverload("bytes.size(): int", (v) => BigInt(v.length));
|
|
8386
|
+
functionOverload("list.size(): int", (v) => BigInt(v.length ?? v.size));
|
|
8387
|
+
functionOverload(
|
|
8388
|
+
"map.size(): int",
|
|
8389
|
+
(v) => BigInt(v instanceof Map ? v.size : objectKeys(v).length)
|
|
8390
|
+
);
|
|
8391
|
+
functionOverload("bytes(string): bytes", (v) => ByteOpts.fromString(v));
|
|
8392
|
+
functionOverload("bytes(bytes): bytes", identity);
|
|
8393
|
+
functionOverload("double(double): double", identity);
|
|
8394
|
+
functionOverload("double(int): double", (v) => Number(v));
|
|
8395
|
+
functionOverload("double(string): double", (v) => {
|
|
8396
|
+
if (!v || v !== v.trim())
|
|
8397
|
+
throw new EvaluationError("double() type error: cannot convert to double");
|
|
8398
|
+
const s = v.toLowerCase();
|
|
8399
|
+
switch (s) {
|
|
8400
|
+
case "inf":
|
|
8401
|
+
case "+inf":
|
|
8402
|
+
case "infinity":
|
|
8403
|
+
case "+infinity":
|
|
8404
|
+
return Number.POSITIVE_INFINITY;
|
|
8405
|
+
case "-inf":
|
|
8406
|
+
case "-infinity":
|
|
8407
|
+
return Number.NEGATIVE_INFINITY;
|
|
8408
|
+
case "nan":
|
|
8409
|
+
return Number.NaN;
|
|
8410
|
+
default: {
|
|
8411
|
+
const parsed = Number(v);
|
|
8412
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
8413
|
+
throw new EvaluationError("double() type error: cannot convert to double");
|
|
8414
|
+
}
|
|
8415
|
+
}
|
|
8416
|
+
});
|
|
8417
|
+
functionOverload("int(int): int", identity);
|
|
8418
|
+
functionOverload("int(double): int", (v) => {
|
|
8419
|
+
if (Number.isFinite(v)) return BigInt(Math.trunc(v));
|
|
8420
|
+
throw new EvaluationError("int() type error: integer overflow");
|
|
8421
|
+
});
|
|
8422
|
+
functionOverload("int(string): int", (v) => {
|
|
8423
|
+
if (v !== v.trim() || v.length > 20 || v.includes("0x")) {
|
|
8424
|
+
throw new EvaluationError("int() type error: cannot convert to int");
|
|
8425
|
+
}
|
|
8426
|
+
try {
|
|
8427
|
+
const num = BigInt(v);
|
|
8428
|
+
if (num <= 9223372036854775807n && num >= -9223372036854775808n) return num;
|
|
8429
|
+
} catch (_e) {
|
|
8430
|
+
}
|
|
8431
|
+
throw new EvaluationError("int() type error: cannot convert to int");
|
|
8432
|
+
});
|
|
8433
|
+
functionOverload("uint(uint): uint", identity);
|
|
8434
|
+
functionOverload("uint(double): uint", (v) => {
|
|
8435
|
+
if (Number.isFinite(v)) return BigInt(Math.trunc(v));
|
|
8436
|
+
throw new EvaluationError("int() type error: integer overflow");
|
|
8437
|
+
});
|
|
8438
|
+
functionOverload("uint(string): uint", (v) => {
|
|
8439
|
+
if (v !== v.trim() || v.length > 20 || v.includes("0x")) {
|
|
8440
|
+
throw new EvaluationError("uint() type error: cannot convert to uint");
|
|
8441
|
+
}
|
|
8442
|
+
try {
|
|
8443
|
+
const num = BigInt(v);
|
|
8444
|
+
if (num <= 18446744073709551615n && num >= 0n) return num;
|
|
8445
|
+
} catch (_e) {
|
|
8446
|
+
}
|
|
8447
|
+
throw new EvaluationError("uint() type error: cannot convert to uint");
|
|
8448
|
+
});
|
|
8449
|
+
functionOverload("string(string): string", identity);
|
|
8450
|
+
functionOverload("string(bool): string", (v) => `${v}`);
|
|
8451
|
+
functionOverload("string(int): string", (v) => `${v}`);
|
|
8452
|
+
functionOverload("string(bytes): string", (v) => ByteOpts.toUtf8(v));
|
|
8453
|
+
functionOverload("string(double): string", (v) => {
|
|
8454
|
+
if (v === Infinity) return "+Inf";
|
|
8455
|
+
if (v === -Infinity) return "-Inf";
|
|
8456
|
+
return `${v}`;
|
|
8457
|
+
});
|
|
8458
|
+
functionOverload("string.startsWith(string): bool", (a, b) => a.startsWith(b));
|
|
8459
|
+
functionOverload("string.endsWith(string): bool", (a, b) => a.endsWith(b));
|
|
8460
|
+
functionOverload("string.contains(string): bool", (a, b) => a.includes(b));
|
|
8461
|
+
functionOverload(
|
|
8462
|
+
"string.indexOf(string): bool",
|
|
8463
|
+
(string, search) => BigInt(string.indexOf(search))
|
|
8464
|
+
);
|
|
8465
|
+
functionOverload("string.indexOf(string, int): bool", (string, search, fromIndex) => {
|
|
8466
|
+
if (search === "") return fromIndex;
|
|
8467
|
+
fromIndex = Number(fromIndex);
|
|
8468
|
+
if (fromIndex < 0 || fromIndex >= string.length) {
|
|
8469
|
+
throw new EvaluationError("string.indexOf(search, fromIndex): fromIndex out of range");
|
|
8470
|
+
}
|
|
8471
|
+
return BigInt(string.indexOf(search, fromIndex));
|
|
8472
|
+
});
|
|
8473
|
+
functionOverload(
|
|
8474
|
+
"string.lastIndexOf(string): bool",
|
|
8475
|
+
(string, search) => BigInt(string.lastIndexOf(search))
|
|
8476
|
+
);
|
|
8477
|
+
functionOverload("string.lastIndexOf(string, int): bool", (string, search, fromIndex) => {
|
|
8478
|
+
if (search === "") return fromIndex;
|
|
8479
|
+
fromIndex = Number(fromIndex);
|
|
8480
|
+
if (fromIndex < 0 || fromIndex >= string.length) {
|
|
8481
|
+
throw new EvaluationError("string.lastIndexOf(search, fromIndex): fromIndex out of range");
|
|
8482
|
+
}
|
|
8483
|
+
return BigInt(string.lastIndexOf(search, fromIndex));
|
|
8484
|
+
});
|
|
8485
|
+
functionOverload("string.substring(int): string", (string, start) => {
|
|
8486
|
+
start = Number(start);
|
|
8487
|
+
if (start < 0 || start > string.length) {
|
|
8488
|
+
throw new EvaluationError("string.substring(start, end): start index out of range");
|
|
8489
|
+
}
|
|
8490
|
+
return string.substring(start);
|
|
8491
|
+
});
|
|
8492
|
+
functionOverload("string.substring(int, int): string", (string, start, end) => {
|
|
8493
|
+
start = Number(start);
|
|
8494
|
+
if (start < 0 || start > string.length) {
|
|
8495
|
+
throw new EvaluationError("string.substring(start, end): start index out of range");
|
|
8496
|
+
}
|
|
8497
|
+
end = Number(end);
|
|
8498
|
+
if (end < start || end > string.length) {
|
|
8499
|
+
throw new EvaluationError("string.substring(start, end): end index out of range");
|
|
8500
|
+
}
|
|
8501
|
+
return string.substring(start, end);
|
|
8502
|
+
});
|
|
8503
|
+
functionOverload("string.matches(string): bool", (a, b) => {
|
|
8504
|
+
try {
|
|
8505
|
+
return new RegExp(b).test(a);
|
|
8506
|
+
} catch (_err) {
|
|
8507
|
+
throw new EvaluationError(`Invalid regular expression: ${b}`);
|
|
8508
|
+
}
|
|
8509
|
+
});
|
|
8510
|
+
functionOverload("string.split(string): list", (s, sep) => s.split(sep));
|
|
8511
|
+
functionOverload("string.split(string, int): list", (s, sep, l) => s.split(sep, l));
|
|
8512
|
+
functionOverload("list.join(): string", (v) => {
|
|
8513
|
+
for (let i = 0; i < v.length; i++) {
|
|
8514
|
+
if (typeof v[i] !== "string") {
|
|
8515
|
+
throw new EvaluationError("string.join(): list must contain only strings");
|
|
8516
|
+
}
|
|
8517
|
+
}
|
|
8518
|
+
return v.join("");
|
|
8519
|
+
});
|
|
8520
|
+
functionOverload("list.join(string): string", (v, sep) => {
|
|
8521
|
+
for (let i = 0; i < v.length; i++) {
|
|
8522
|
+
if (typeof v[i] !== "string") {
|
|
8523
|
+
throw new EvaluationError("string.join(separator): list must contain only strings");
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
return v.join(sep);
|
|
8527
|
+
});
|
|
8528
|
+
const textEncoder = new TextEncoder("utf8");
|
|
8529
|
+
const textDecoder = new TextDecoder("utf8");
|
|
8530
|
+
const ByteOpts = typeof Buffer !== "undefined" ? {
|
|
8531
|
+
byteLength: (v) => Buffer.byteLength(v),
|
|
8532
|
+
fromString: (str) => Buffer.from(str, "utf8"),
|
|
8533
|
+
toHex: (b) => Buffer.prototype.hexSlice.call(b, 0, b.length),
|
|
8534
|
+
toBase64: (b) => Buffer.prototype.base64Slice.call(b, 0, b.length),
|
|
8535
|
+
toUtf8: (b) => Buffer.prototype.utf8Slice.call(b, 0, b.length),
|
|
8536
|
+
jsonParse: (b) => JSON.parse(b)
|
|
8537
|
+
} : {
|
|
8538
|
+
textEncoder: new TextEncoder("utf8"),
|
|
8539
|
+
byteLength: (v) => textEncoder.encode(v).length,
|
|
8540
|
+
fromString: (str) => textEncoder.encode(str),
|
|
8541
|
+
toHex: Uint8Array.prototype.toHex ? (b) => b.toHex() : (b) => Array.from(b, (i) => i.toString(16).padStart(2, "0")).join(""),
|
|
8542
|
+
toBase64: Uint8Array.prototype.toBase64 ? (b) => b.toBase64() : (b) => btoa(Array.from(b, (i) => String.fromCodePoint(i)).join("")),
|
|
8543
|
+
toUtf8: (b) => textDecoder.decode(b),
|
|
8544
|
+
jsonParse: (b) => JSON.parse(textEncoder.decode(b))
|
|
8545
|
+
};
|
|
8546
|
+
functionOverload("bytes.json(): map", ByteOpts.jsonParse);
|
|
8547
|
+
functionOverload("bytes.hex(): string", ByteOpts.toHex);
|
|
8548
|
+
functionOverload("bytes.string(): string", ByteOpts.toUtf8);
|
|
8549
|
+
functionOverload("bytes.base64(): string", ByteOpts.toBase64);
|
|
8550
|
+
functionOverload("bytes.at(int): int", (b, index) => {
|
|
8551
|
+
if (index < 0 || index >= b.length) throw new EvaluationError("Bytes index out of range");
|
|
8552
|
+
return BigInt(b[index]);
|
|
8553
|
+
});
|
|
8554
|
+
const TS = "google.protobuf.Timestamp";
|
|
8555
|
+
function tzDate(d, timeZone) {
|
|
8556
|
+
return new Date(d.toLocaleString("en-US", { timeZone }));
|
|
8557
|
+
}
|
|
8558
|
+
function getDayOfYear(d, tz) {
|
|
8559
|
+
const workingDate = tz ? tzDate(d, tz) : new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
|
|
8560
|
+
const start = new Date(workingDate.getFullYear(), 0, 0);
|
|
8561
|
+
return BigInt(Math.floor((workingDate - start) / 864e5) - 1);
|
|
8562
|
+
}
|
|
8563
|
+
functionOverload(`timestamp(string): ${TS}`, (v) => {
|
|
8564
|
+
if (v.length < 20 || v.length > 30) {
|
|
8565
|
+
throw new EvaluationError("timestamp() requires a string in ISO 8601 format");
|
|
8566
|
+
}
|
|
8567
|
+
const d = new Date(v);
|
|
8568
|
+
if (d <= 253402300799999 && d >= -621355968e5) return d;
|
|
8569
|
+
throw new EvaluationError("timestamp() requires a string in ISO 8601 format");
|
|
8570
|
+
});
|
|
8571
|
+
functionOverload(`timestamp(int): ${TS}`, (i) => {
|
|
8572
|
+
i = Number(i) * 1e3;
|
|
8573
|
+
if (i <= 253402300799999 && i >= -621355968e5) return new Date(i);
|
|
8574
|
+
throw new EvaluationError("timestamp() requires a valid integer unix timestamp");
|
|
8575
|
+
});
|
|
8576
|
+
functionOverload(`${TS}.getDate(): int`, (d) => BigInt(d.getUTCDate()));
|
|
8577
|
+
functionOverload(`${TS}.getDate(string): int`, (d, tz) => BigInt(tzDate(d, tz).getDate()));
|
|
8578
|
+
functionOverload(`${TS}.getDayOfMonth(): int`, (d) => BigInt(d.getUTCDate() - 1));
|
|
8579
|
+
functionOverload(
|
|
8580
|
+
`${TS}.getDayOfMonth(string): int`,
|
|
8581
|
+
(d, tz) => BigInt(tzDate(d, tz).getDate() - 1)
|
|
8582
|
+
);
|
|
8583
|
+
functionOverload(`${TS}.getDayOfWeek(): int`, (d) => BigInt(d.getUTCDay()));
|
|
8584
|
+
functionOverload(`${TS}.getDayOfWeek(string): int`, (d, tz) => BigInt(tzDate(d, tz).getDay()));
|
|
8585
|
+
functionOverload(`${TS}.getDayOfYear(): int`, getDayOfYear);
|
|
8586
|
+
functionOverload(`${TS}.getDayOfYear(string): int`, getDayOfYear);
|
|
8587
|
+
functionOverload(`${TS}.getFullYear(): int`, (d) => BigInt(d.getUTCFullYear()));
|
|
8588
|
+
functionOverload(`${TS}.getFullYear(string): int`, (d, tz) => BigInt(tzDate(d, tz).getFullYear()));
|
|
8589
|
+
functionOverload(`${TS}.getHours(): int`, (d) => BigInt(d.getUTCHours()));
|
|
8590
|
+
functionOverload(`${TS}.getHours(string): int`, (d, tz) => BigInt(tzDate(d, tz).getHours()));
|
|
8591
|
+
functionOverload(`${TS}.getMilliseconds(): int`, (d) => BigInt(d.getUTCMilliseconds()));
|
|
8592
|
+
functionOverload(`${TS}.getMilliseconds(string): int`, (d) => BigInt(d.getUTCMilliseconds()));
|
|
8593
|
+
functionOverload(`${TS}.getMinutes(): int`, (d) => BigInt(d.getUTCMinutes()));
|
|
8594
|
+
functionOverload(`${TS}.getMinutes(string): int`, (d, tz) => BigInt(tzDate(d, tz).getMinutes()));
|
|
8595
|
+
functionOverload(`${TS}.getMonth(): int`, (d) => BigInt(d.getUTCMonth()));
|
|
8596
|
+
functionOverload(`${TS}.getMonth(string): int`, (d, tz) => BigInt(tzDate(d, tz).getMonth()));
|
|
8597
|
+
functionOverload(`${TS}.getSeconds(): int`, (d) => BigInt(d.getUTCSeconds()));
|
|
8598
|
+
functionOverload(`${TS}.getSeconds(string): int`, (d, tz) => BigInt(tzDate(d, tz).getSeconds()));
|
|
8599
|
+
const parseDurationPattern = /(\d*\.?\d*)(ns|us|µs|ms|s|m|h)/;
|
|
8600
|
+
function parseDuration(string) {
|
|
8601
|
+
if (!string) throw new EvaluationError(`Invalid duration string: ''`);
|
|
8602
|
+
const isNegative = string[0] === "-";
|
|
8603
|
+
if (string[0] === "-" || string[0] === "+") string = string.slice(1);
|
|
8604
|
+
let nanoseconds = BigInt(0);
|
|
8605
|
+
while (true) {
|
|
8606
|
+
const match = parseDurationPattern.exec(string);
|
|
8607
|
+
if (!match) throw new EvaluationError(`Invalid duration string: ${string}`);
|
|
8608
|
+
if (match.index !== 0) throw new EvaluationError(`Invalid duration string: ${string}`);
|
|
8609
|
+
string = string.slice(match[0].length);
|
|
8610
|
+
const unitNanos = UNIT_NANOSECONDS[match[2]];
|
|
8611
|
+
const [intPart = "0", fracPart = ""] = match[1].split(".");
|
|
8612
|
+
const intVal = BigInt(intPart) * unitNanos;
|
|
8613
|
+
const fracNanos = fracPart ? BigInt(fracPart.slice(0, 13).padEnd(13, "0")) * unitNanos / 10000000000000n : 0n;
|
|
8614
|
+
nanoseconds += intVal + fracNanos;
|
|
8615
|
+
if (string === "") break;
|
|
8616
|
+
}
|
|
8617
|
+
const seconds = nanoseconds >= 1000000000n ? nanoseconds / 1000000000n : 0n;
|
|
8618
|
+
const nanos = Number(nanoseconds % 1000000000n);
|
|
8619
|
+
if (isNegative) return new Duration(-seconds, -nanos);
|
|
8620
|
+
return new Duration(seconds, nanos);
|
|
8621
|
+
}
|
|
8622
|
+
functionOverload(`duration(string): google.protobuf.Duration`, (s) => parseDuration(s));
|
|
8623
|
+
functionOverload(`google.protobuf.Duration.getHours(): int`, (d) => d.getHours());
|
|
8624
|
+
functionOverload(`google.protobuf.Duration.getMinutes(): int`, (d) => d.getMinutes());
|
|
8625
|
+
functionOverload(`google.protobuf.Duration.getSeconds(): int`, (d) => d.getSeconds());
|
|
8626
|
+
functionOverload(`google.protobuf.Duration.getMilliseconds(): int`, (d) => d.getMilliseconds());
|
|
8627
|
+
function getIterableElementType(receiverType, checker) {
|
|
8628
|
+
if (receiverType.type === "list") return receiverType.valueType;
|
|
8629
|
+
if (receiverType.type === "map") return receiverType.keyType;
|
|
8630
|
+
return checker.getType("dyn");
|
|
8631
|
+
}
|
|
8632
|
+
function validateIdentifierArg(args, functionDesc) {
|
|
8633
|
+
const identArg = args[0];
|
|
8634
|
+
if (identArg instanceof ASTNode && identArg[0] === "id") return identArg[1];
|
|
8635
|
+
throw new TypeError2(`${functionDesc} requires first argument to be an identifier`, identArg);
|
|
8636
|
+
}
|
|
8637
|
+
function predicateTypeCheck(methodName) {
|
|
8638
|
+
return (checker, receiverType, args) => {
|
|
8639
|
+
const varName = validateIdentifierArg(args, `${methodName}(var, predicate)`);
|
|
8640
|
+
const elementType = getIterableElementType(receiverType, checker);
|
|
8641
|
+
const scopedChecker = checker.createOverlay(varName, elementType);
|
|
8642
|
+
const predicateType = scopedChecker.check(args[1]);
|
|
8643
|
+
if (predicateType.isDynOrBool()) return predicateType;
|
|
8644
|
+
throw new TypeError2(`predicate must return bool, got '${predicateType}'`, args[1]);
|
|
8645
|
+
};
|
|
8646
|
+
}
|
|
8647
|
+
function mapTypeCheck(checker, receiverType, args) {
|
|
8648
|
+
const funcDesc = `map(var, ${args.length === 3 ? "filter, " : ""}transform)`;
|
|
8649
|
+
const varName = validateIdentifierArg(args, funcDesc);
|
|
8650
|
+
const elementType = getIterableElementType(receiverType, checker);
|
|
8651
|
+
const scopedChecker = checker.createOverlay(varName, elementType);
|
|
8652
|
+
if (args.length === 3) {
|
|
8653
|
+
const filterType = scopedChecker.check(args[1]);
|
|
8654
|
+
if (!filterType.isDynOrBool()) {
|
|
8655
|
+
throw new TypeError2(
|
|
8656
|
+
`${funcDesc} filter predicate must return bool, got '${filterType}'`,
|
|
8657
|
+
args[1]
|
|
8658
|
+
);
|
|
8659
|
+
}
|
|
8660
|
+
}
|
|
8661
|
+
return checker.getType(`list<${scopedChecker.check(args[args.length - 1])}>`);
|
|
8662
|
+
}
|
|
8663
|
+
function filterTypeCheck(checker, receiverType, args) {
|
|
8664
|
+
const funcDesc = `filter(var, filter)`;
|
|
8665
|
+
const varName = validateIdentifierArg(args, funcDesc);
|
|
8666
|
+
const elementType = getIterableElementType(receiverType, checker);
|
|
8667
|
+
const scopedChecker = checker.createOverlay(varName, elementType);
|
|
8668
|
+
const filterType = scopedChecker.check(args[1]);
|
|
8669
|
+
if (filterType.isDynOrBool()) return checker.getType(`list<${elementType}>`);
|
|
8670
|
+
throw new TypeError2(`${funcDesc} predicate must return bool, got '${filterType}'`, args[1]);
|
|
8671
|
+
}
|
|
8672
|
+
functionOverload("list.all(ast, ast): bool", {
|
|
8673
|
+
handler: allMacro,
|
|
8674
|
+
typeCheck: predicateTypeCheck("all")
|
|
8675
|
+
});
|
|
8676
|
+
functionOverload("map.all(ast, ast): bool", {
|
|
8677
|
+
handler: allMacro,
|
|
8678
|
+
typeCheck: predicateTypeCheck("all")
|
|
8679
|
+
});
|
|
8680
|
+
functionOverload("list.exists(ast, ast): bool", {
|
|
8681
|
+
handler: existsMacro,
|
|
8682
|
+
typeCheck: predicateTypeCheck("exists")
|
|
8683
|
+
});
|
|
8684
|
+
functionOverload("map.exists(ast, ast): bool", {
|
|
8685
|
+
handler: existsMacro,
|
|
8686
|
+
typeCheck: predicateTypeCheck("exists")
|
|
8687
|
+
});
|
|
8688
|
+
functionOverload("list.exists_one(ast, ast): bool", {
|
|
8689
|
+
handler: existsOneMacro,
|
|
8690
|
+
typeCheck: predicateTypeCheck("exists_one")
|
|
8691
|
+
});
|
|
8692
|
+
functionOverload("map.exists_one(ast, ast): bool", {
|
|
8693
|
+
handler: existsOneMacro,
|
|
8694
|
+
typeCheck: predicateTypeCheck("exists_one")
|
|
8695
|
+
});
|
|
8696
|
+
functionOverload("list.map(ast, ast): list", { handler: mapMacro, typeCheck: mapTypeCheck });
|
|
8697
|
+
functionOverload("list.map(ast, ast, ast): list", {
|
|
8698
|
+
handler: filterMapMacro,
|
|
8699
|
+
typeCheck: mapTypeCheck
|
|
8700
|
+
});
|
|
8701
|
+
functionOverload("map.map(ast, ast): list", { handler: mapMacro, typeCheck: mapTypeCheck });
|
|
8702
|
+
functionOverload("map.map(ast, ast, ast): list", {
|
|
8703
|
+
handler: filterMapMacro,
|
|
8704
|
+
typeCheck: mapTypeCheck
|
|
8705
|
+
});
|
|
8706
|
+
functionOverload("list.filter(ast, ast): list", {
|
|
8707
|
+
handler: filterMacro,
|
|
8708
|
+
typeCheck: filterTypeCheck
|
|
8709
|
+
});
|
|
8710
|
+
functionOverload("map.filter(ast, ast): list", { handler: filterMacro, typeCheck: filterTypeCheck });
|
|
8711
|
+
}
|
|
8712
|
+
var kPredicateEvaluator = Symbol("predicateEvaluator");
|
|
8713
|
+
function allMacro(receiver, ast) {
|
|
8714
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8715
|
+
"all(var, predicate)",
|
|
8716
|
+
ast
|
|
8717
|
+
);
|
|
8718
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8719
|
+
let error = null;
|
|
8720
|
+
for (let i = 0; i < items.length; i++) {
|
|
8721
|
+
try {
|
|
8722
|
+
if (evaluator.childEvaluateBool(items[i])) continue;
|
|
8723
|
+
return false;
|
|
8724
|
+
} catch (e) {
|
|
8725
|
+
if (e.message.includes("Unknown variable")) throw e;
|
|
8726
|
+
if (e.message.includes("predicate result is not a boolean")) throw e;
|
|
8727
|
+
error ??= e;
|
|
8728
|
+
}
|
|
8729
|
+
}
|
|
8730
|
+
if (error) throw error;
|
|
8731
|
+
return true;
|
|
8732
|
+
}
|
|
8733
|
+
function existsMacro(receiver, ast) {
|
|
8734
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8735
|
+
"exists(var, predicate)",
|
|
8736
|
+
ast
|
|
8737
|
+
);
|
|
8738
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8739
|
+
let error;
|
|
8740
|
+
for (let i = 0; i < items.length; i++) {
|
|
8741
|
+
try {
|
|
8742
|
+
if (evaluator.childEvaluateBool(items[i])) return true;
|
|
8743
|
+
} catch (e) {
|
|
8744
|
+
if (e.message.includes("Unknown variable")) throw e;
|
|
8745
|
+
if (e.message.includes("predicate result is not a boolean")) throw e;
|
|
8746
|
+
error ??= e;
|
|
8747
|
+
}
|
|
8748
|
+
}
|
|
8749
|
+
if (error) throw error;
|
|
8750
|
+
return false;
|
|
8751
|
+
}
|
|
8752
|
+
function existsOneMacro(receiver, ast) {
|
|
8753
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8754
|
+
"exists_one(var, predicate)",
|
|
8755
|
+
ast
|
|
8756
|
+
);
|
|
8757
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8758
|
+
let count = 0;
|
|
8759
|
+
for (let i = 0; i < items.length; i++) {
|
|
8760
|
+
if (evaluator.childEvaluateBool(items[i]) === false) continue;
|
|
8761
|
+
if (++count > 1) return false;
|
|
8762
|
+
}
|
|
8763
|
+
return count === 1;
|
|
8764
|
+
}
|
|
8765
|
+
function mapMacro(receiver, ast) {
|
|
8766
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8767
|
+
"map(var, transform)",
|
|
8768
|
+
ast
|
|
8769
|
+
);
|
|
8770
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8771
|
+
const results = [];
|
|
8772
|
+
for (let i = 0; i < items.length; i++) results[i] = evaluator.childEvaluate(items[i]);
|
|
8773
|
+
return results;
|
|
8774
|
+
}
|
|
8775
|
+
function filterMapMacro(receiver, ast) {
|
|
8776
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8777
|
+
"map(var, filter, transform)",
|
|
8778
|
+
ast
|
|
8779
|
+
);
|
|
8780
|
+
const transform = ast[3][2];
|
|
8781
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8782
|
+
const results = [];
|
|
8783
|
+
for (let i = 0; i < items.length; i++) {
|
|
8784
|
+
switch (evaluator.childEvaluateBool(items[i])) {
|
|
8785
|
+
case false:
|
|
8786
|
+
continue;
|
|
8787
|
+
case true:
|
|
8788
|
+
results.push(evaluator.eval(transform));
|
|
8789
|
+
continue;
|
|
8790
|
+
}
|
|
8791
|
+
}
|
|
8792
|
+
return results;
|
|
8793
|
+
}
|
|
8794
|
+
function filterMacro(receiver, ast) {
|
|
8795
|
+
const evaluator = ast[kPredicateEvaluator] ??= this.predicateEvaluator(
|
|
8796
|
+
"filter(var, predicate)",
|
|
8797
|
+
ast
|
|
8798
|
+
);
|
|
8799
|
+
const items = evaluator.getIterableItems(receiver);
|
|
8800
|
+
const results = [];
|
|
8801
|
+
for (let i = 0; i < items.length; i++) {
|
|
8802
|
+
const item = items[i];
|
|
8803
|
+
if (evaluator.childEvaluateBool(item) === false) continue;
|
|
8804
|
+
results.push(item);
|
|
8805
|
+
}
|
|
8806
|
+
return results;
|
|
8807
|
+
}
|
|
8808
|
+
function stringSize(str) {
|
|
8809
|
+
let count = 0;
|
|
8810
|
+
for (const c of str) count++;
|
|
8811
|
+
return count;
|
|
8812
|
+
}
|
|
8813
|
+
|
|
8814
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/registry.js
|
|
8815
|
+
var Type2 = class {
|
|
8816
|
+
#name;
|
|
8817
|
+
constructor(name) {
|
|
8818
|
+
this.#name = name;
|
|
8819
|
+
Object.freeze(this);
|
|
8820
|
+
}
|
|
8821
|
+
get name() {
|
|
8822
|
+
return this.#name;
|
|
8823
|
+
}
|
|
8824
|
+
get [Symbol.toStringTag]() {
|
|
8825
|
+
return `Type<${this.#name}>`;
|
|
8826
|
+
}
|
|
8827
|
+
toString() {
|
|
8828
|
+
return `Type<${this.#name}>`;
|
|
8829
|
+
}
|
|
8830
|
+
};
|
|
8831
|
+
var TYPES = {
|
|
8832
|
+
string: new Type2("string"),
|
|
8833
|
+
bool: new Type2("bool"),
|
|
8834
|
+
int: new Type2("int"),
|
|
8835
|
+
uint: new Type2("uint"),
|
|
8836
|
+
double: new Type2("double"),
|
|
8837
|
+
map: new Type2("map"),
|
|
8838
|
+
list: new Type2("list"),
|
|
8839
|
+
bytes: new Type2("bytes"),
|
|
8840
|
+
null_type: new Type2("null"),
|
|
8841
|
+
type: new Type2("type"),
|
|
8842
|
+
google: {
|
|
8843
|
+
protobuf: {
|
|
8844
|
+
Timestamp: new Type2("google.protobuf.Timestamp"),
|
|
8845
|
+
Duration: new Type2("google.protobuf.Duration")
|
|
8846
|
+
}
|
|
8847
|
+
}
|
|
8848
|
+
};
|
|
8849
|
+
TYPES["google.protobuf.Timestamp"] = TYPES.google.protobuf.Timestamp;
|
|
8850
|
+
TYPES["google.protobuf.Duration"] = TYPES.google.protobuf.Duration;
|
|
8851
|
+
var LayeredMap = class _LayeredMap {
|
|
8852
|
+
#parent = null;
|
|
8853
|
+
#entries = null;
|
|
8854
|
+
constructor(source) {
|
|
8855
|
+
if (source instanceof _LayeredMap) {
|
|
8856
|
+
this.#parent = source;
|
|
8857
|
+
this.#entries = /* @__PURE__ */ new Map();
|
|
8858
|
+
} else {
|
|
8859
|
+
this.#entries = new Map(source);
|
|
8860
|
+
}
|
|
8861
|
+
}
|
|
8862
|
+
fork(lock = true) {
|
|
8863
|
+
if (lock) this.set = this.#throwLocked;
|
|
8864
|
+
return new this.constructor(this);
|
|
8865
|
+
}
|
|
8866
|
+
#throwLocked() {
|
|
8867
|
+
throw new Error("Cannot modify frozen registry");
|
|
8868
|
+
}
|
|
8869
|
+
set(key, value) {
|
|
8870
|
+
this.#entries.set(key, value);
|
|
8871
|
+
return this;
|
|
8872
|
+
}
|
|
8873
|
+
has(key) {
|
|
8874
|
+
return this.#entries.has(key) || (this.#parent ? this.#parent.has(key) : false);
|
|
8875
|
+
}
|
|
8876
|
+
get(key) {
|
|
8877
|
+
return this.#entries.get(key) || this.#parent?.get(key);
|
|
8878
|
+
}
|
|
8879
|
+
*#entryIterator() {
|
|
8880
|
+
if (this.#parent) yield* this.#parent;
|
|
8881
|
+
yield* this.#entries;
|
|
8882
|
+
}
|
|
8883
|
+
[Symbol.iterator]() {
|
|
8884
|
+
return this.#entryIterator();
|
|
8885
|
+
}
|
|
8886
|
+
get size() {
|
|
8887
|
+
return this.#entries.size + (this.#parent ? this.#parent.size : 0);
|
|
8888
|
+
}
|
|
8889
|
+
};
|
|
8890
|
+
var DynVariableRegistry = class extends LayeredMap {
|
|
8891
|
+
constructor(source = null, marker = null) {
|
|
8892
|
+
super(source, marker);
|
|
8893
|
+
}
|
|
8894
|
+
get(name) {
|
|
8895
|
+
const value = super.get(name);
|
|
8896
|
+
return value === void 0 ? dynType : value;
|
|
8897
|
+
}
|
|
8898
|
+
};
|
|
8899
|
+
function createLayeredMap(source, MapCtor = LayeredMap, lock = true) {
|
|
8900
|
+
if (source instanceof MapCtor) return source.fork(lock);
|
|
8901
|
+
return new MapCtor(source);
|
|
8902
|
+
}
|
|
8903
|
+
var TypeDeclaration = class {
|
|
8904
|
+
#matchesCache = /* @__PURE__ */ new WeakMap();
|
|
8905
|
+
constructor({ kind, type, name, keyType, valueType, values }) {
|
|
8906
|
+
this.kind = kind;
|
|
8907
|
+
this.type = type;
|
|
8908
|
+
this.name = name;
|
|
8909
|
+
if (keyType) this.keyType = keyType;
|
|
8910
|
+
if (valueType) this.valueType = valueType;
|
|
8911
|
+
if (values) this.values = values;
|
|
8912
|
+
if (kind === "list") this.fieldLazy = this.#getListField;
|
|
8913
|
+
else if (kind === "map") this.fieldLazy = this.#getMapField;
|
|
8914
|
+
else if (kind === "message") this.fieldLazy = this.#getMessageField;
|
|
8915
|
+
else if (kind === "dyn") this.fieldLazy = this.#getMapField;
|
|
8916
|
+
Object.freeze(this);
|
|
8917
|
+
}
|
|
8918
|
+
isDynOrBool() {
|
|
8919
|
+
return this.type === "bool" || this.kind === "dyn";
|
|
8920
|
+
}
|
|
8921
|
+
toString() {
|
|
8922
|
+
return this.name;
|
|
8923
|
+
}
|
|
8924
|
+
#getMessageField(obj, key, ast, ev) {
|
|
8925
|
+
const type = ev.objectTypesByConstructor.get(obj.constructor);
|
|
8926
|
+
if (!type) return;
|
|
8927
|
+
if (!type.fields) return Object.hasOwn(obj, key) ? obj[key] : void 0;
|
|
8928
|
+
const valueType = type.fields[key];
|
|
8929
|
+
if (!valueType) return;
|
|
8930
|
+
const value = obj[key];
|
|
8931
|
+
if (valueType.kind === "dyn") return value;
|
|
8932
|
+
const actualType = ev.debugType(value);
|
|
8933
|
+
if (valueType.matches(actualType)) return value;
|
|
8934
|
+
throw new EvaluationError(
|
|
8935
|
+
`Field '${key}' is not of type '${valueType}', got '${actualType}'`,
|
|
8936
|
+
ast
|
|
8937
|
+
);
|
|
8938
|
+
}
|
|
8939
|
+
#getMapField(obj, key, ast, ev) {
|
|
8940
|
+
let value;
|
|
8941
|
+
if (obj instanceof Map) value = obj.get(key);
|
|
8942
|
+
else value = Object.hasOwn(obj, key) ? obj[key] : void 0;
|
|
8943
|
+
if (value === void 0) return;
|
|
8944
|
+
if (this.valueType.kind === "dyn") return value;
|
|
8945
|
+
const type = ev.debugType(value);
|
|
8946
|
+
if (this.valueType.matches(type)) return value;
|
|
8947
|
+
throw new EvaluationError(
|
|
8948
|
+
`Field '${key}' is not of type '${this.valueType}', got '${type}'`,
|
|
8949
|
+
ast
|
|
8950
|
+
);
|
|
8951
|
+
}
|
|
8952
|
+
#getListField(obj, key, ast, ev) {
|
|
8953
|
+
if (!(typeof key === "number" || typeof key === "bigint")) return;
|
|
8954
|
+
const value = obj[key];
|
|
8955
|
+
if (value === void 0) {
|
|
8956
|
+
throw new EvaluationError(
|
|
8957
|
+
`No such key: index out of bounds, index ${key} ${key < 0 ? "< 0" : `>= size ${obj.length}`}`,
|
|
8958
|
+
ast
|
|
8959
|
+
);
|
|
8960
|
+
}
|
|
8961
|
+
const type = ev.debugType(value);
|
|
8962
|
+
if (this.valueType.matches(type)) return value;
|
|
8963
|
+
throw new EvaluationError(
|
|
8964
|
+
`List item with index '${key}' is not of type '${this.valueType}', got '${type}'`,
|
|
8965
|
+
ast
|
|
8966
|
+
);
|
|
8967
|
+
}
|
|
8968
|
+
fieldLazy() {
|
|
8969
|
+
}
|
|
8970
|
+
field(obj, key, ast, ev) {
|
|
8971
|
+
const v = this.fieldLazy(obj, key, ast, ev);
|
|
8972
|
+
if (v !== void 0) return v;
|
|
8973
|
+
throw new EvaluationError(`No such key: ${key}`, ast);
|
|
8974
|
+
}
|
|
8975
|
+
matchesBoth(other) {
|
|
8976
|
+
return this.matches(other) && other.matches(this);
|
|
8977
|
+
}
|
|
8978
|
+
matches(other) {
|
|
8979
|
+
return this.#matchesCache.get(other) ?? this.#matchesCache.set(other, this.#matches(other)).get(other);
|
|
8980
|
+
}
|
|
8981
|
+
#matches(other) {
|
|
8982
|
+
if (this === other) return true;
|
|
8983
|
+
if (other.kind === "dyn") return other.valueType ? this.matches(other.valueType) : true;
|
|
8984
|
+
switch (this.kind) {
|
|
8985
|
+
case "dyn":
|
|
8986
|
+
return true;
|
|
8987
|
+
case "list":
|
|
8988
|
+
return other.kind === "list" && this.valueType.matches(other.valueType);
|
|
8989
|
+
case "map":
|
|
8990
|
+
return other.kind === "map" && this.keyType.matches(other.keyType) && this.valueType.matches(other.valueType);
|
|
8991
|
+
default:
|
|
8992
|
+
return this.name === other.name;
|
|
8993
|
+
}
|
|
8994
|
+
}
|
|
8995
|
+
};
|
|
8996
|
+
var FunctionDeclaration = class {
|
|
8997
|
+
constructor({ name, receiverType, argTypes, returnType, handler, typeCheck }) {
|
|
8998
|
+
this.name = name;
|
|
8999
|
+
this.macro = argTypes.includes(astType);
|
|
9000
|
+
this.receiverType = receiverType || null;
|
|
9001
|
+
this.argTypes = argTypes;
|
|
9002
|
+
this.returnType = returnType;
|
|
9003
|
+
const receiverString = receiverType ? `${receiverType}.` : "";
|
|
9004
|
+
this.signature = `${receiverString}${name}(${argTypes.join(", ")}): ${returnType}`;
|
|
9005
|
+
this.handler = handler;
|
|
9006
|
+
this.typeCheck = typeCheck;
|
|
9007
|
+
Object.freeze(this);
|
|
9008
|
+
}
|
|
9009
|
+
matchesArgs(argTypes) {
|
|
9010
|
+
if (argTypes.length !== this.argTypes.length) return false;
|
|
9011
|
+
return this.argTypes.every((t, i) => t.matches(argTypes[i]));
|
|
9012
|
+
}
|
|
9013
|
+
};
|
|
9014
|
+
var OperatorDeclaration = class {
|
|
9015
|
+
constructor({ operator, leftType, rightType, handler, returnType }) {
|
|
9016
|
+
this.operator = operator;
|
|
9017
|
+
this.leftType = leftType;
|
|
9018
|
+
this.rightType = rightType || null;
|
|
9019
|
+
this.handler = handler;
|
|
9020
|
+
this.returnType = returnType;
|
|
9021
|
+
if (rightType) this.signature = `${leftType} ${operator} ${rightType}: ${returnType}`;
|
|
9022
|
+
else this.signature = `${operator}${leftType}: ${returnType}`;
|
|
9023
|
+
Object.freeze(this);
|
|
9024
|
+
}
|
|
9025
|
+
get isUnary() {
|
|
9026
|
+
return this.rightType === null;
|
|
9027
|
+
}
|
|
9028
|
+
get isBinary() {
|
|
9029
|
+
return this.rightType !== null;
|
|
9030
|
+
}
|
|
9031
|
+
equals(other) {
|
|
9032
|
+
return this.operator === other.operator && this.leftType === other.leftType && this.rightType === other.rightType;
|
|
9033
|
+
}
|
|
9034
|
+
};
|
|
9035
|
+
function _createListType(valueType) {
|
|
9036
|
+
return new TypeDeclaration({
|
|
9037
|
+
kind: "list",
|
|
9038
|
+
name: `list<${valueType}>`,
|
|
9039
|
+
type: "list",
|
|
9040
|
+
valueType
|
|
9041
|
+
});
|
|
9042
|
+
}
|
|
9043
|
+
function _createPrimitiveType(name) {
|
|
9044
|
+
return new TypeDeclaration({
|
|
9045
|
+
kind: "primitive",
|
|
9046
|
+
name,
|
|
9047
|
+
type: name
|
|
9048
|
+
});
|
|
9049
|
+
}
|
|
9050
|
+
function _createMessageType(name) {
|
|
9051
|
+
return new TypeDeclaration({
|
|
9052
|
+
kind: "message",
|
|
9053
|
+
name,
|
|
9054
|
+
type: name
|
|
9055
|
+
});
|
|
9056
|
+
}
|
|
9057
|
+
function _createDynType(valueType) {
|
|
9058
|
+
const name = valueType ? `dyn<${valueType}>` : "dyn";
|
|
9059
|
+
return new TypeDeclaration({
|
|
9060
|
+
kind: "dyn",
|
|
9061
|
+
name,
|
|
9062
|
+
type: name,
|
|
9063
|
+
valueType
|
|
9064
|
+
});
|
|
9065
|
+
}
|
|
9066
|
+
function _createMapType(keyType, valueType) {
|
|
9067
|
+
return new TypeDeclaration({
|
|
9068
|
+
kind: "map",
|
|
9069
|
+
name: `map<${keyType}, ${valueType}>`,
|
|
9070
|
+
type: "map",
|
|
9071
|
+
keyType,
|
|
9072
|
+
valueType
|
|
9073
|
+
});
|
|
9074
|
+
}
|
|
9075
|
+
var dynType = _createDynType();
|
|
9076
|
+
var astType = _createPrimitiveType("ast");
|
|
9077
|
+
var listType = _createListType(dynType);
|
|
9078
|
+
var mapType = _createMapType(dynType, dynType);
|
|
9079
|
+
var celTypes = Object.freeze({
|
|
9080
|
+
string: _createPrimitiveType("string"),
|
|
9081
|
+
bool: _createPrimitiveType("bool"),
|
|
9082
|
+
int: _createPrimitiveType("int"),
|
|
9083
|
+
uint: _createPrimitiveType("uint"),
|
|
9084
|
+
double: _createPrimitiveType("double"),
|
|
9085
|
+
bytes: _createPrimitiveType("bytes"),
|
|
9086
|
+
dyn: dynType,
|
|
9087
|
+
null: _createPrimitiveType("null"),
|
|
9088
|
+
type: _createPrimitiveType("type"),
|
|
9089
|
+
"google.protobuf.Timestamp": _createPrimitiveType("google.protobuf.Timestamp"),
|
|
9090
|
+
"google.protobuf.Duration": _createPrimitiveType("google.protobuf.Duration"),
|
|
9091
|
+
list: listType,
|
|
9092
|
+
"list<dyn>": listType,
|
|
9093
|
+
map: mapType,
|
|
9094
|
+
"map<dyn, dyn>": mapType
|
|
9095
|
+
});
|
|
9096
|
+
var FunctionsByReceiver = class {
|
|
9097
|
+
/** @type {Array<FunctionDeclaration>} */
|
|
9098
|
+
functions = [];
|
|
9099
|
+
exists = false;
|
|
9100
|
+
hasMacro = false;
|
|
9101
|
+
add(decl) {
|
|
9102
|
+
this.exists = true;
|
|
9103
|
+
if (decl.macro) this.hasMacro = true;
|
|
9104
|
+
this.functions.push(decl);
|
|
9105
|
+
}
|
|
9106
|
+
findMatch(argTypes) {
|
|
9107
|
+
if (!this.exists) return null;
|
|
9108
|
+
for (const fn of this.functions) {
|
|
9109
|
+
if (fn.matchesArgs(argTypes)) return fn;
|
|
9110
|
+
}
|
|
9111
|
+
return null;
|
|
9112
|
+
}
|
|
9113
|
+
};
|
|
9114
|
+
var NO_RECEIVER = new FunctionsByReceiver();
|
|
9115
|
+
var FunctionCandidates = class {
|
|
9116
|
+
exists = false;
|
|
9117
|
+
hasMacro = false;
|
|
9118
|
+
returnType = null;
|
|
9119
|
+
/** @type {Map<string|null, FunctionsByReceiver>} */
|
|
9120
|
+
#byReceiverType = /* @__PURE__ */ new Map();
|
|
9121
|
+
add(declaration) {
|
|
9122
|
+
this.exists = true;
|
|
9123
|
+
if (declaration.macro) this.hasMacro = true;
|
|
9124
|
+
if (!this.returnType) this.returnType = declaration.returnType;
|
|
9125
|
+
else if (declaration.typeCheck) this.returnType = dynType;
|
|
9126
|
+
else if (this.returnType !== declaration.returnType) this.returnType = dynType;
|
|
9127
|
+
const receiverType = declaration.receiverType;
|
|
9128
|
+
const coll = this.#byReceiverType.get(receiverType) || this.#byReceiverType.set(receiverType, new FunctionsByReceiver()).get(receiverType);
|
|
9129
|
+
coll.add(declaration);
|
|
9130
|
+
}
|
|
9131
|
+
filterByReceiverType(receiverType) {
|
|
9132
|
+
if (receiverType === null) return this.#byReceiverType.get(null) || NO_RECEIVER;
|
|
9133
|
+
return (
|
|
9134
|
+
// First try exact match
|
|
9135
|
+
this.#byReceiverType.get(receiverType) || // For generic types, also try matching with the base type
|
|
9136
|
+
// e.g., if looking for list<string>, also check list<dyn>
|
|
9137
|
+
(receiverType.type === "list" || receiverType.type === "map" ? this.#byReceiverType.get(celTypes[receiverType.type]) : null) || NO_RECEIVER
|
|
9138
|
+
);
|
|
9139
|
+
}
|
|
9140
|
+
};
|
|
9141
|
+
function splitByComma(str) {
|
|
9142
|
+
const parts = [];
|
|
9143
|
+
let current2 = "";
|
|
9144
|
+
let depth = 0;
|
|
9145
|
+
for (const char of str) {
|
|
9146
|
+
if (char === "<") depth++;
|
|
9147
|
+
else if (char === ">") depth--;
|
|
9148
|
+
else if (char === "," && depth === 0) {
|
|
9149
|
+
parts.push(current2);
|
|
9150
|
+
current2 = "";
|
|
9151
|
+
continue;
|
|
9152
|
+
}
|
|
9153
|
+
current2 += char;
|
|
9154
|
+
}
|
|
9155
|
+
if (current2) parts.push(current2);
|
|
9156
|
+
return parts;
|
|
9157
|
+
}
|
|
9158
|
+
var builtinObjectTypes = [
|
|
9159
|
+
[void 0, "map"],
|
|
9160
|
+
[Object, "map"],
|
|
9161
|
+
[Map, "map"],
|
|
9162
|
+
[Array, "list"],
|
|
9163
|
+
[Uint8Array, "bytes"],
|
|
9164
|
+
[Date, "google.protobuf.Timestamp"],
|
|
9165
|
+
[Duration, "google.protobuf.Duration"],
|
|
9166
|
+
[UnsignedInt, "uint"],
|
|
9167
|
+
[Type2, "type"]
|
|
9168
|
+
];
|
|
9169
|
+
if (typeof Buffer !== "undefined") builtinObjectTypes.push([Buffer, "bytes"]);
|
|
9170
|
+
var Registry = class _Registry {
|
|
9171
|
+
#overloadResolutionCache = {};
|
|
9172
|
+
#overloadCheckCache = {};
|
|
9173
|
+
#typeDeclarations;
|
|
9174
|
+
#operatorDeclarations;
|
|
9175
|
+
#functionDeclarations;
|
|
9176
|
+
#dynTypes = /* @__PURE__ */ new Map();
|
|
9177
|
+
constructor(opts = {}) {
|
|
9178
|
+
this.objectTypes = createLayeredMap(opts.objectTypes);
|
|
9179
|
+
this.objectTypesByConstructor = createLayeredMap(opts.objectTypesByConstructor);
|
|
9180
|
+
this.objectTypeInstances = createLayeredMap(opts.objectTypeInstances);
|
|
9181
|
+
this.#functionDeclarations = createLayeredMap(opts.functionDeclarations);
|
|
9182
|
+
this.#operatorDeclarations = createLayeredMap(opts.operatorDeclarations);
|
|
9183
|
+
this.#typeDeclarations = createLayeredMap(
|
|
9184
|
+
opts.typeDeclarations || Object.entries(celTypes),
|
|
9185
|
+
void 0,
|
|
9186
|
+
false
|
|
9187
|
+
);
|
|
9188
|
+
this.variables = opts.unlistedVariablesAreDyn ? createLayeredMap(opts.variables, DynVariableRegistry) : createLayeredMap(opts.variables);
|
|
9189
|
+
if (!this.variables.size) {
|
|
9190
|
+
for (const [instance, name] of builtinObjectTypes) {
|
|
9191
|
+
this.registerType(name, instance, true);
|
|
9192
|
+
}
|
|
9193
|
+
const globalValues2 = new Map(Object.entries(TYPES));
|
|
9194
|
+
for (const [name, type] of globalValues2) {
|
|
9195
|
+
if (!(type instanceof Type2)) continue;
|
|
9196
|
+
this.registerVariable(name, "type");
|
|
9197
|
+
}
|
|
9198
|
+
}
|
|
9199
|
+
}
|
|
9200
|
+
#invalidateOverloadsCache() {
|
|
9201
|
+
this.#overloadResolutionCache = {};
|
|
9202
|
+
this.#overloadCheckCache = {};
|
|
9203
|
+
}
|
|
9204
|
+
registerVariable(name, type) {
|
|
9205
|
+
if (this.variables.has(name)) throw new Error(`Variable already registered: ${name}`);
|
|
9206
|
+
this.variables.set(name, type instanceof TypeDeclaration ? type : this.getType(type));
|
|
9207
|
+
return this;
|
|
9208
|
+
}
|
|
9209
|
+
getFunctionCandidates(receiverType, functionName, argCount) {
|
|
9210
|
+
const candidates = new FunctionCandidates();
|
|
9211
|
+
for (const [, dec] of this.#functionDeclarations) {
|
|
9212
|
+
if (functionName !== dec.name) continue;
|
|
9213
|
+
if (receiverType === null && dec.receiverType) continue;
|
|
9214
|
+
if (receiverType && dec.receiverType === null) continue;
|
|
9215
|
+
candidates.exists = true;
|
|
9216
|
+
if (dec.macro) candidates.hasMacro = true;
|
|
9217
|
+
if (receiverType && !receiverType.matches(dec.receiverType)) continue;
|
|
9218
|
+
if (dec.argTypes.length !== argCount) continue;
|
|
9219
|
+
candidates.add(dec);
|
|
9220
|
+
}
|
|
9221
|
+
return candidates;
|
|
9222
|
+
}
|
|
9223
|
+
getType(typename) {
|
|
9224
|
+
return this.#parseTypeString(typename, true);
|
|
9225
|
+
}
|
|
9226
|
+
getDynType(type) {
|
|
9227
|
+
return this.#dynTypes.get(type) || this.#dynTypes.set(type, this.#parseTypeString(`dyn<${type}>`, true)).get(type);
|
|
9228
|
+
}
|
|
9229
|
+
assertType(typename, type, signature) {
|
|
9230
|
+
try {
|
|
9231
|
+
return this.#parseTypeString(typename, true);
|
|
9232
|
+
} catch (e) {
|
|
9233
|
+
e.message = `Invalid ${type} '${e.unknownType || typename}' in '${signature}'`;
|
|
9234
|
+
throw e;
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
getFunctionType(typename) {
|
|
9238
|
+
if (typename === "ast") return astType;
|
|
9239
|
+
return this.#parseTypeString(typename, true);
|
|
9240
|
+
}
|
|
9241
|
+
registerType(typename, _d, withoutDynRegistration) {
|
|
9242
|
+
const decl = {
|
|
9243
|
+
name: typename,
|
|
9244
|
+
type: this.#parseTypeString(typename, false),
|
|
9245
|
+
ctor: typeof _d === "function" ? _d : _d?.ctor,
|
|
9246
|
+
fields: this.#normalizeFields(typename, _d?.fields)
|
|
9247
|
+
};
|
|
9248
|
+
if (!withoutDynRegistration) {
|
|
9249
|
+
if (this.objectTypes.has(typename)) throw new Error(`Type already registered: ${typename}`);
|
|
9250
|
+
if (typeof decl.ctor !== "function") {
|
|
9251
|
+
throw new Error(`Constructor function missing for type '${typename}'`);
|
|
9252
|
+
}
|
|
9253
|
+
}
|
|
9254
|
+
this.objectTypes.set(typename, decl);
|
|
9255
|
+
this.objectTypesByConstructor.set(decl.ctor, decl);
|
|
9256
|
+
if (withoutDynRegistration) return;
|
|
9257
|
+
const type = new Type2(typename);
|
|
9258
|
+
this.objectTypeInstances.set(typename, type);
|
|
9259
|
+
this.registerFunctionOverload(`type(${typename}): type`, () => type);
|
|
9260
|
+
}
|
|
9261
|
+
/** @returns {TypeDeclaration} */
|
|
9262
|
+
#parseTypeString(typeStr, requireKnownTypes = false) {
|
|
9263
|
+
const existing = this.#typeDeclarations.get(typeStr);
|
|
9264
|
+
if (existing) return existing;
|
|
9265
|
+
const dynMatch = typeStr.match(/^dyn<(.+)>$/);
|
|
9266
|
+
if (dynMatch) {
|
|
9267
|
+
const type = this.#parseTypeString(dynMatch[1].trim(), requireKnownTypes);
|
|
9268
|
+
return this.#createDeclaration(_createDynType, `dyn<${type}>`, type);
|
|
9269
|
+
}
|
|
9270
|
+
const listMatch = typeStr.match(/^list<(.+)>$/);
|
|
9271
|
+
if (listMatch) {
|
|
9272
|
+
const vType = this.#parseTypeString(listMatch[1].trim(), requireKnownTypes);
|
|
9273
|
+
return this.#createDeclaration(_createListType, `list<${vType}>`, vType);
|
|
9274
|
+
}
|
|
9275
|
+
const mapMatch = typeStr.match(/^map<(.+)>$/);
|
|
9276
|
+
if (mapMatch) {
|
|
9277
|
+
const parts = splitByComma(mapMatch[1]);
|
|
9278
|
+
if (parts.length !== 2) throw new Error(`Invalid map type: ${typeStr}`);
|
|
9279
|
+
const kType = this.#parseTypeString(parts[0].trim(), requireKnownTypes);
|
|
9280
|
+
const vType = this.#parseTypeString(parts[1].trim(), requireKnownTypes);
|
|
9281
|
+
return this.#createDeclaration(_createMapType, `map<${kType}, ${vType}>`, kType, vType);
|
|
9282
|
+
}
|
|
9283
|
+
if (requireKnownTypes) {
|
|
9284
|
+
const err = new Error(`Unknown type: ${typeStr}`);
|
|
9285
|
+
err.unknownType = typeStr;
|
|
9286
|
+
throw err;
|
|
9287
|
+
}
|
|
9288
|
+
return this.#createDeclaration(_createMessageType, typeStr, typeStr);
|
|
9289
|
+
}
|
|
9290
|
+
#createDeclaration(creator, key, ...args) {
|
|
9291
|
+
return this.#typeDeclarations.get(key) || this.#typeDeclarations.set(key, creator(...args)).get(key);
|
|
9292
|
+
}
|
|
9293
|
+
#findBinaryOverloads(operator, leftType, rightType) {
|
|
9294
|
+
const nonexactMatches = [];
|
|
9295
|
+
for (const [, decl] of this.#operatorDeclarations) {
|
|
9296
|
+
if (decl.operator !== operator) continue;
|
|
9297
|
+
if (this.#exactMatch(decl, leftType, rightType)) return [decl];
|
|
9298
|
+
if (this.#matchesOverload(decl, leftType, rightType)) nonexactMatches.push(decl);
|
|
9299
|
+
}
|
|
9300
|
+
if (nonexactMatches.length === 0 && (operator === "==" || operator === "!=") && this.#hasDynOperand(leftType, rightType)) {
|
|
9301
|
+
const handler = operator === "==" ? (a, b) => a === b : (a, b) => a !== b;
|
|
9302
|
+
return [{ handler, returnType: this.getType("bool") }];
|
|
9303
|
+
}
|
|
9304
|
+
return nonexactMatches;
|
|
9305
|
+
}
|
|
9306
|
+
findUnaryOverload(op, left) {
|
|
9307
|
+
const cached = this.#overloadResolutionCache[op]?.get(left);
|
|
9308
|
+
if (cached !== void 0) return cached;
|
|
9309
|
+
let value = false;
|
|
9310
|
+
for (const [, decl] of this.#operatorDeclarations) {
|
|
9311
|
+
if (decl.operator !== op || decl.leftType !== left) continue;
|
|
9312
|
+
value = decl;
|
|
9313
|
+
break;
|
|
9314
|
+
}
|
|
9315
|
+
return (this.#overloadResolutionCache[op] ??= /* @__PURE__ */ new Map()).set(left, value).get(left);
|
|
9316
|
+
}
|
|
9317
|
+
findBinaryOverload(op, left, right) {
|
|
9318
|
+
return this.#overloadResolutionCache[op]?.get(left)?.get(right) ?? this.#cacheOverloadResult(
|
|
9319
|
+
this.#overloadResolutionCache,
|
|
9320
|
+
op,
|
|
9321
|
+
left,
|
|
9322
|
+
right,
|
|
9323
|
+
this.#findBinaryOverloadUncached(op, left, right)
|
|
9324
|
+
);
|
|
9325
|
+
}
|
|
9326
|
+
checkBinaryOverload(op, left, right) {
|
|
9327
|
+
return this.#overloadCheckCache[op]?.get(left)?.get(right) ?? this.#cacheOverloadResult(
|
|
9328
|
+
this.#overloadCheckCache,
|
|
9329
|
+
op,
|
|
9330
|
+
left,
|
|
9331
|
+
right,
|
|
9332
|
+
this.#checkBinaryOverloadUncached(op, left, right)
|
|
9333
|
+
);
|
|
9334
|
+
}
|
|
9335
|
+
#findBinaryOverloadUncached(operator, leftType, rightType) {
|
|
9336
|
+
const ops = this.#findBinaryOverloads(operator, leftType, rightType);
|
|
9337
|
+
if (ops.length === 0) return false;
|
|
9338
|
+
if (ops.length === 1) return ops[0];
|
|
9339
|
+
throw new Error(`Operator overload '${ops[0].signature}' overlaps with '${ops[1].signature}'.`);
|
|
9340
|
+
}
|
|
9341
|
+
#checkBinaryOverloadUncached(op, left, right) {
|
|
9342
|
+
const ops = this.#findBinaryOverloads(op, left, right);
|
|
9343
|
+
if (ops.length === 0) return false;
|
|
9344
|
+
const firstType = ops[0].returnType;
|
|
9345
|
+
if (ops.every((d) => d.returnType === firstType)) return firstType;
|
|
9346
|
+
if ((firstType.kind === "list" || firstType.kind === "map") && ops.every((d) => d.returnType.kind === firstType.kind)) {
|
|
9347
|
+
return firstType.kind === "list" ? celTypes.list : celTypes.map;
|
|
9348
|
+
}
|
|
9349
|
+
return celTypes.dyn;
|
|
9350
|
+
}
|
|
9351
|
+
#cacheOverloadResult(cache, op, left, right, result) {
|
|
9352
|
+
const opMap = cache[op] ??= /* @__PURE__ */ new Map();
|
|
9353
|
+
const leftMap = opMap.get(left) || opMap.set(left, /* @__PURE__ */ new Map()).get(left);
|
|
9354
|
+
leftMap.set(right, result);
|
|
9355
|
+
return result;
|
|
9356
|
+
}
|
|
9357
|
+
#exactMatch(decl, actualLeft, actualRight) {
|
|
9358
|
+
return actualLeft === decl.leftType && actualRight === decl.rightType || actualLeft.name === `dyn<${decl.leftType}>` && actualRight === decl.rightType || actualLeft === decl.leftType && actualRight.name === `dyn<${decl.rightType}>` || actualLeft.name === `dyn<${decl.leftType}>` && actualRight.name === `dyn<${decl.rightType}>`;
|
|
9359
|
+
}
|
|
9360
|
+
#matchesOverload(decl, actualLeft, actualRight) {
|
|
9361
|
+
if (!this.#isAssignable(actualLeft, decl.leftType)) return false;
|
|
9362
|
+
if (!this.#isAssignable(actualRight, decl.rightType)) return false;
|
|
9363
|
+
return this.#validateParameters(decl.operator, actualLeft, actualRight);
|
|
9364
|
+
}
|
|
9365
|
+
#isAssignable(actual, declared) {
|
|
9366
|
+
if (actual === declared) return true;
|
|
9367
|
+
if (actual.kind === "dyn") {
|
|
9368
|
+
return actual.valueType ? this.#isAssignable(actual.valueType, declared) : true;
|
|
9369
|
+
}
|
|
9370
|
+
if (actual.type !== declared.type) return false;
|
|
9371
|
+
if (declared === celTypes.list) return true;
|
|
9372
|
+
if (declared === celTypes.map) return true;
|
|
9373
|
+
return false;
|
|
9374
|
+
}
|
|
9375
|
+
#validateParameters(operator, leftType, rightType) {
|
|
9376
|
+
if (operator === "in") {
|
|
9377
|
+
if (leftType.kind === "dyn") return true;
|
|
9378
|
+
if (rightType.kind === "list") return rightType.valueType.matchesBoth(leftType);
|
|
9379
|
+
if (rightType.kind === "map") return rightType.keyType.matchesBoth(leftType);
|
|
9380
|
+
return true;
|
|
9381
|
+
}
|
|
9382
|
+
if (operator === "+" || operator === "==" || operator === "!=") {
|
|
9383
|
+
if (leftType.kind === "list" && rightType.kind === "list") {
|
|
9384
|
+
return leftType.matchesBoth(rightType);
|
|
9385
|
+
}
|
|
9386
|
+
if (leftType.kind === "map" && rightType.kind === "map") {
|
|
9387
|
+
return leftType.matchesBoth(rightType);
|
|
9388
|
+
}
|
|
9389
|
+
}
|
|
9390
|
+
return true;
|
|
9391
|
+
}
|
|
9392
|
+
#hasDynOperand(leftType, rightType) {
|
|
9393
|
+
if (leftType.kind === "dyn" || rightType.kind === "dyn") return true;
|
|
9394
|
+
return false;
|
|
9395
|
+
}
|
|
9396
|
+
#toCelFieldDeclaration(typename, fields, k, requireKnownTypes = false) {
|
|
9397
|
+
try {
|
|
9398
|
+
const field = typeof fields[k] === "string" ? { type: fields[k] } : { ...fields[k] };
|
|
9399
|
+
if (typeof field?.type !== "string") throw new Error(`unsupported declaration`);
|
|
9400
|
+
return this.#parseTypeString(field.type, requireKnownTypes);
|
|
9401
|
+
} catch (e) {
|
|
9402
|
+
e.message = `Field '${k}' in type '${typename}' has unsupported declaration: ${JSON.stringify(fields[k])}`;
|
|
9403
|
+
throw e;
|
|
9404
|
+
}
|
|
9405
|
+
}
|
|
9406
|
+
#normalizeFields(typename, fields) {
|
|
9407
|
+
if (!fields) return;
|
|
9408
|
+
const all = {};
|
|
9409
|
+
for (const k of Object.keys(fields)) all[k] = this.#toCelFieldDeclaration(typename, fields, k);
|
|
9410
|
+
return all;
|
|
9411
|
+
}
|
|
9412
|
+
clone(opts = {}) {
|
|
9413
|
+
return new _Registry({
|
|
9414
|
+
objectTypes: this.objectTypes,
|
|
9415
|
+
objectTypesByConstructor: this.objectTypesByConstructor,
|
|
9416
|
+
objectTypeInstances: this.objectTypeInstances,
|
|
9417
|
+
typeDeclarations: this.#typeDeclarations,
|
|
9418
|
+
operatorDeclarations: this.#operatorDeclarations,
|
|
9419
|
+
functionDeclarations: this.#functionDeclarations,
|
|
9420
|
+
variables: this.variables,
|
|
9421
|
+
unlistedVariablesAreDyn: opts.unlistedVariablesAreDyn
|
|
9422
|
+
});
|
|
9423
|
+
}
|
|
9424
|
+
/** @param {string} signature */
|
|
9425
|
+
#parseFunctionDeclaration(signature, handler, typeCheck) {
|
|
9426
|
+
const match = signature.match(/^(?:([a-zA-Z0-9.]+)\.)?(\w+)\((.*?)\):\s*(.+)$/);
|
|
9427
|
+
if (!match) throw new Error(`Invalid signature: ${signature}`);
|
|
9428
|
+
const [, receiverType, name, argsStr, _returnType] = match;
|
|
9429
|
+
try {
|
|
9430
|
+
return new FunctionDeclaration({
|
|
9431
|
+
name,
|
|
9432
|
+
receiverType: receiverType ? this.getType(receiverType.trim()) : null,
|
|
9433
|
+
returnType: this.getType(_returnType.trim() || "dyn"),
|
|
9434
|
+
argTypes: splitByComma(argsStr).map((s) => this.getFunctionType(s.trim())),
|
|
9435
|
+
handler,
|
|
9436
|
+
typeCheck
|
|
9437
|
+
});
|
|
9438
|
+
} catch (e) {
|
|
9439
|
+
throw new Error(`Invalid function declaration: ${signature}`);
|
|
9440
|
+
}
|
|
9441
|
+
}
|
|
9442
|
+
/**
|
|
9443
|
+
* @param {FunctionDeclaration} a
|
|
9444
|
+
* @param {FunctionDeclaration} b
|
|
9445
|
+
*/
|
|
9446
|
+
#functionSignatureOverlaps(a, b) {
|
|
9447
|
+
if (a.name !== b.name) return false;
|
|
9448
|
+
if (a.argTypes.length !== b.argTypes.length) return false;
|
|
9449
|
+
if ((a.receiverType || b.receiverType) && (!a.receiverType || !b.receiverType)) return false;
|
|
9450
|
+
const isDifferentReceiver = a.receiverType !== b.receiverType && a.receiverType !== dynType && b.receiverType !== dynType;
|
|
9451
|
+
return !isDifferentReceiver && (b.macro || a.macro || b.argTypes.every((type1, i) => {
|
|
9452
|
+
const type2 = a.argTypes[i];
|
|
9453
|
+
if (type1 === type2) return true;
|
|
9454
|
+
if (type1 === astType || type2 === astType) return true;
|
|
9455
|
+
if (type1 === dynType || type2 === dynType) return true;
|
|
9456
|
+
return false;
|
|
9457
|
+
}));
|
|
9458
|
+
}
|
|
9459
|
+
/** @param {FunctionDeclaration} newDec */
|
|
9460
|
+
#checkOverlappingSignatures(newDec) {
|
|
9461
|
+
for (const [, decl] of this.#functionDeclarations) {
|
|
9462
|
+
if (!this.#functionSignatureOverlaps(decl, newDec)) continue;
|
|
9463
|
+
throw new Error(
|
|
9464
|
+
`Function signature '${newDec.signature}' overlaps with existing overload '${decl.signature}'.`
|
|
9465
|
+
);
|
|
9466
|
+
}
|
|
9467
|
+
}
|
|
9468
|
+
registerFunctionOverload(s, handlerOrOptions) {
|
|
9469
|
+
const handler = typeof handlerOrOptions === "function" ? handlerOrOptions : handlerOrOptions.handler;
|
|
9470
|
+
const options = typeof handlerOrOptions === "function" ? {} : handlerOrOptions;
|
|
9471
|
+
const dec = this.#parseFunctionDeclaration(s, handler, options.typeCheck);
|
|
9472
|
+
this.#checkOverlappingSignatures(dec);
|
|
9473
|
+
this.#functionDeclarations.set(dec.signature, dec);
|
|
9474
|
+
}
|
|
9475
|
+
registerOperatorOverload(string, handler) {
|
|
9476
|
+
const unaryParts = string.match(/^([-!])([\w.<>]+)(?::\s*([\w.<>]+))?$/);
|
|
9477
|
+
if (unaryParts) {
|
|
9478
|
+
const [, op2, operandType, returnType2] = unaryParts;
|
|
9479
|
+
return this.unaryOverload(op2, operandType, handler, returnType2);
|
|
9480
|
+
}
|
|
9481
|
+
const parts = string.match(
|
|
9482
|
+
/^([\w.<>]+) ([-+*%/]|==|!=|<|<=|>|>=|in) ([\w.<>]+)(?::\s*([\w.<>]+))?$/
|
|
9483
|
+
);
|
|
9484
|
+
if (!parts) throw new Error(`Operator overload invalid: ${string}`);
|
|
9485
|
+
const [, leftType, op, rightType, returnType] = parts;
|
|
9486
|
+
return this.binaryOverload(leftType, op, rightType, handler, returnType);
|
|
9487
|
+
}
|
|
9488
|
+
unaryOverload(op, typeStr, handler, returnTypeStr) {
|
|
9489
|
+
const leftType = this.assertType(typeStr, "type", `${op}${typeStr}`);
|
|
9490
|
+
const returnType = this.assertType(
|
|
9491
|
+
returnTypeStr || typeStr,
|
|
9492
|
+
"return type",
|
|
9493
|
+
`${op}${typeStr}: ${returnTypeStr || typeStr}`
|
|
9494
|
+
);
|
|
9495
|
+
const decl = new OperatorDeclaration({ operator: `${op}_`, leftType, returnType, handler });
|
|
9496
|
+
if (this.#hasOverload(decl)) {
|
|
9497
|
+
throw new Error(`Operator overload already registered: ${op}${typeStr}`);
|
|
9498
|
+
}
|
|
9499
|
+
this.#operatorDeclarations.set(decl.signature, decl);
|
|
9500
|
+
this.#invalidateOverloadsCache();
|
|
9501
|
+
}
|
|
9502
|
+
#hasOverload(decl) {
|
|
9503
|
+
for (const [, other] of this.#operatorDeclarations) if (decl.equals(other)) return true;
|
|
9504
|
+
return false;
|
|
9505
|
+
}
|
|
9506
|
+
binaryOverload(leftTypeStr, op, rightTypeStr, handler, returnTypeStr) {
|
|
9507
|
+
returnTypeStr ??= isRelational(op) ? "bool" : leftTypeStr;
|
|
9508
|
+
const sig = `${leftTypeStr} ${op} ${rightTypeStr}: ${returnTypeStr}`;
|
|
9509
|
+
const leftType = this.assertType(leftTypeStr, "left type", sig);
|
|
9510
|
+
const rightType = this.assertType(rightTypeStr, "right type", sig);
|
|
9511
|
+
const returnType = this.assertType(returnTypeStr, "return type", sig);
|
|
9512
|
+
if (isRelational(op) && returnType.type !== "bool") {
|
|
9513
|
+
throw new Error(`Comparison operator '${op}' must return 'bool', got '${returnType.type}'`);
|
|
9514
|
+
}
|
|
9515
|
+
const dec = new OperatorDeclaration({ operator: op, leftType, rightType, returnType, handler });
|
|
9516
|
+
if (this.#hasOverload(dec)) {
|
|
9517
|
+
throw new Error(`Operator overload already registered: ${dec.signature}`);
|
|
9518
|
+
}
|
|
9519
|
+
if (op === "==") {
|
|
9520
|
+
const declarations = [
|
|
9521
|
+
new OperatorDeclaration({
|
|
9522
|
+
operator: "!=",
|
|
9523
|
+
leftType,
|
|
9524
|
+
rightType,
|
|
9525
|
+
handler(a, b, ast, ev) {
|
|
9526
|
+
return !handler(a, b, ast, ev);
|
|
9527
|
+
},
|
|
9528
|
+
returnType
|
|
9529
|
+
})
|
|
9530
|
+
];
|
|
9531
|
+
if (leftType !== rightType) {
|
|
9532
|
+
declarations.push(
|
|
9533
|
+
new OperatorDeclaration({
|
|
9534
|
+
operator: "==",
|
|
9535
|
+
leftType: rightType,
|
|
9536
|
+
rightType: leftType,
|
|
9537
|
+
handler(a, b, ast, ev) {
|
|
9538
|
+
return handler(b, a, ast, ev);
|
|
9539
|
+
},
|
|
9540
|
+
returnType
|
|
9541
|
+
}),
|
|
9542
|
+
new OperatorDeclaration({
|
|
9543
|
+
operator: "!=",
|
|
9544
|
+
leftType: rightType,
|
|
9545
|
+
rightType: leftType,
|
|
9546
|
+
handler(a, b, ast, ev) {
|
|
9547
|
+
return !handler(b, a, ast, ev);
|
|
9548
|
+
},
|
|
9549
|
+
returnType
|
|
9550
|
+
})
|
|
9551
|
+
);
|
|
9552
|
+
}
|
|
9553
|
+
for (const decl of declarations) {
|
|
9554
|
+
if (!this.#hasOverload(decl)) continue;
|
|
9555
|
+
throw new Error(`Operator overload already registered: ${decl.signature}`);
|
|
9556
|
+
}
|
|
9557
|
+
for (const decl of declarations) this.#operatorDeclarations.set(decl.signature, decl);
|
|
9558
|
+
}
|
|
9559
|
+
this.#operatorDeclarations.set(dec.signature, dec);
|
|
9560
|
+
this.#invalidateOverloadsCache();
|
|
9561
|
+
}
|
|
9562
|
+
};
|
|
9563
|
+
function isRelational(op) {
|
|
9564
|
+
return op === "<" || op === "<=" || op === ">" || op === ">=" || op === "==" || op === "!=" || op === "in";
|
|
9565
|
+
}
|
|
9566
|
+
function createRegistry(opts) {
|
|
9567
|
+
return new Registry(opts);
|
|
9568
|
+
}
|
|
9569
|
+
|
|
9570
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/overloads.js
|
|
9571
|
+
function registerOverloads(registry) {
|
|
9572
|
+
const unaryOverload2 = registry.unaryOverload.bind(registry);
|
|
9573
|
+
const binaryOverload2 = registry.binaryOverload.bind(registry);
|
|
9574
|
+
function verifyInteger(v, ast) {
|
|
9575
|
+
if (v <= 9223372036854775807n && v >= -9223372036854775808n) return v;
|
|
9576
|
+
throw new EvaluationError(`integer overflow: ${v}`, ast);
|
|
9577
|
+
}
|
|
9578
|
+
unaryOverload2("!", "bool", (a) => !a);
|
|
9579
|
+
unaryOverload2("-", "int", (a) => -a);
|
|
9580
|
+
binaryOverload2("int", "*", "int", (a, b, ast) => verifyInteger(a * b, ast));
|
|
9581
|
+
binaryOverload2("int", "+", "int", (a, b, ast) => verifyInteger(a + b, ast));
|
|
9582
|
+
binaryOverload2("int", "-", "int", (a, b, ast) => verifyInteger(a - b, ast));
|
|
9583
|
+
binaryOverload2("int", "/", "int", (a, b, ast) => {
|
|
9584
|
+
if (b === 0n) throw new EvaluationError("division by zero", ast);
|
|
9585
|
+
return a / b;
|
|
9586
|
+
});
|
|
9587
|
+
binaryOverload2("int", "%", "int", (a, b, ast) => {
|
|
9588
|
+
if (b === 0n) throw new EvaluationError("modulo by zero", ast);
|
|
9589
|
+
return a % b;
|
|
9590
|
+
});
|
|
9591
|
+
unaryOverload2("-", "double", (a) => -a);
|
|
9592
|
+
binaryOverload2("double", "*", "double", (a, b) => a * b);
|
|
9593
|
+
binaryOverload2("double", "+", "double", (a, b) => a + b);
|
|
9594
|
+
binaryOverload2("double", "-", "double", (a, b) => a - b);
|
|
9595
|
+
binaryOverload2("double", "/", "double", (a, b, ast) => {
|
|
9596
|
+
if (b === 0) throw new EvaluationError("division by zero", ast);
|
|
9597
|
+
return a / b;
|
|
9598
|
+
});
|
|
9599
|
+
binaryOverload2("string", "+", "string", (a, b) => a + b);
|
|
9600
|
+
binaryOverload2("list", "+", "list", (a, b) => [...a, ...b]);
|
|
9601
|
+
binaryOverload2("bytes", "+", "bytes", (a, b) => {
|
|
9602
|
+
const result = new Uint8Array(a.length + b.length);
|
|
9603
|
+
result.set(a, 0);
|
|
9604
|
+
result.set(b, a.length);
|
|
9605
|
+
return result;
|
|
9606
|
+
});
|
|
9607
|
+
const GPD = "google.protobuf.Duration";
|
|
9608
|
+
binaryOverload2(GPD, "+", GPD, (a, b) => a.addDuration(b));
|
|
9609
|
+
binaryOverload2(GPD, "-", GPD, (a, b) => a.subtractDuration(b));
|
|
9610
|
+
binaryOverload2(GPD, "==", GPD, (a, b) => a.seconds === b.seconds && a.nanos === b.nanos);
|
|
9611
|
+
const GPT = "google.protobuf.Timestamp";
|
|
9612
|
+
binaryOverload2(GPT, "==", GPT, (a, b) => a.getTime() === b.getTime());
|
|
9613
|
+
binaryOverload2(GPT, "-", GPD, (a, b) => b.subtractTimestamp(a));
|
|
9614
|
+
binaryOverload2(GPT, "+", GPD, (a, b) => b.extendTimestamp(a));
|
|
9615
|
+
binaryOverload2(GPD, "+", GPT, (a, b) => a.extendTimestamp(b));
|
|
9616
|
+
function listIncludes(value, list, ast, ev) {
|
|
9617
|
+
if (list instanceof Set && list.has(value)) return true;
|
|
9618
|
+
for (const v of list) if (isEqual2(value, v, ev)) return true;
|
|
9619
|
+
return false;
|
|
9620
|
+
}
|
|
9621
|
+
function listStrictIncludes(value, list) {
|
|
9622
|
+
return Array.isArray(list) ? list.includes(value) : list.has(value);
|
|
9623
|
+
}
|
|
9624
|
+
for (const t of ["string", "bool", "null", "type"])
|
|
9625
|
+
binaryOverload2(t, "in", `list`, listStrictIncludes);
|
|
9626
|
+
for (const t of ["int", "double", "list", "map"]) binaryOverload2(t, "in", `list`, listIncludes);
|
|
9627
|
+
for (const t of ["string", "int", "double", "bool", "null"]) {
|
|
9628
|
+
binaryOverload2(t, "in", "map", (a, b) => {
|
|
9629
|
+
if (b instanceof Map) return b.get(a) !== void 0;
|
|
9630
|
+
return Object.hasOwn(b, a) ? b[a] !== void 0 : false;
|
|
9631
|
+
});
|
|
9632
|
+
}
|
|
9633
|
+
for (const t of ["type", "null", "bool", "string", "int", "uint", "double"]) {
|
|
9634
|
+
binaryOverload2(t, "==", t, (a, b) => a === b);
|
|
9635
|
+
}
|
|
9636
|
+
binaryOverload2("int", `==`, `dyn<double>`, (a, b) => a == b);
|
|
9637
|
+
binaryOverload2("int", `==`, `dyn<uint>`, (a, b) => a == b.valueOf());
|
|
9638
|
+
binaryOverload2("uint", `==`, `dyn<double>`, (a, b) => a.valueOf() == b);
|
|
9639
|
+
binaryOverload2("uint", `==`, `dyn<int>`, (a, b) => a.valueOf() == b);
|
|
9640
|
+
binaryOverload2("double", `==`, `dyn<int>`, (a, b) => a == b);
|
|
9641
|
+
binaryOverload2("double", `==`, `dyn<uint>`, (a, b) => a == b.valueOf());
|
|
9642
|
+
binaryOverload2("bytes", `==`, "bytes", (a, b) => {
|
|
9643
|
+
let i = a.length;
|
|
9644
|
+
if (i !== b.length) return false;
|
|
9645
|
+
while (i--) if (a[i] !== b[i]) return false;
|
|
9646
|
+
return true;
|
|
9647
|
+
});
|
|
9648
|
+
binaryOverload2("list", `==`, "list", (a, b, ast, ev) => {
|
|
9649
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
9650
|
+
const length = a.length;
|
|
9651
|
+
if (length !== b.length) return false;
|
|
9652
|
+
for (let i = 0; i < length; i++) {
|
|
9653
|
+
if (!isEqual2(a[i], b[i], ev)) return false;
|
|
9654
|
+
}
|
|
9655
|
+
return true;
|
|
9656
|
+
}
|
|
9657
|
+
if (a instanceof Set && b instanceof Set) {
|
|
9658
|
+
if (a.size !== b.size) return false;
|
|
9659
|
+
for (const value of a) if (!b.has(value)) return false;
|
|
9660
|
+
return true;
|
|
9661
|
+
}
|
|
9662
|
+
const arr = a instanceof Set ? b : a;
|
|
9663
|
+
const set4 = a instanceof Set ? a : b;
|
|
9664
|
+
if (!Array.isArray(arr)) return false;
|
|
9665
|
+
if (arr.length !== set4?.size) return false;
|
|
9666
|
+
for (let i = 0; i < arr.length; i++) if (!set4.has(arr[i])) return false;
|
|
9667
|
+
return true;
|
|
9668
|
+
});
|
|
9669
|
+
binaryOverload2("map", `==`, "map", (a, b, ast, ev) => {
|
|
9670
|
+
if (a instanceof Map && b instanceof Map) {
|
|
9671
|
+
if (a.size !== b.size) return false;
|
|
9672
|
+
for (const [key, value] of a)
|
|
9673
|
+
if (!(b.has(key) && isEqual2(value, b.get(key), ev))) return false;
|
|
9674
|
+
return true;
|
|
9675
|
+
}
|
|
9676
|
+
if (a instanceof Map || b instanceof Map) {
|
|
9677
|
+
const obj = a instanceof Map ? b : a;
|
|
9678
|
+
const map3 = a instanceof Map ? a : b;
|
|
9679
|
+
const keysObj = Object.keys(obj);
|
|
9680
|
+
if (map3.size !== keysObj.length) return false;
|
|
9681
|
+
for (const [key, value] of map3) {
|
|
9682
|
+
if (!(key in obj && isEqual2(value, obj[key], ev))) return false;
|
|
9683
|
+
}
|
|
9684
|
+
return true;
|
|
9685
|
+
}
|
|
9686
|
+
const keysA = Object.keys(a);
|
|
9687
|
+
const keysB = Object.keys(b);
|
|
9688
|
+
if (keysA.length !== keysB.length) return false;
|
|
9689
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
9690
|
+
const key = keysA[i];
|
|
9691
|
+
if (!(key in b && isEqual2(a[key], b[key], ev))) return false;
|
|
9692
|
+
}
|
|
9693
|
+
return true;
|
|
9694
|
+
});
|
|
9695
|
+
binaryOverload2("uint", "+", "uint", (a, b) => new UnsignedInt(a.valueOf() + b.valueOf()));
|
|
9696
|
+
binaryOverload2("uint", "-", "uint", (a, b) => new UnsignedInt(a.valueOf() - b.valueOf()));
|
|
9697
|
+
binaryOverload2("uint", "*", "uint", (a, b) => new UnsignedInt(a.valueOf() * b.valueOf()));
|
|
9698
|
+
binaryOverload2("uint", "/", "uint", (a, b, ast) => {
|
|
9699
|
+
if (b.valueOf() === 0n) throw new EvaluationError("division by zero", ast);
|
|
9700
|
+
return new UnsignedInt(a.valueOf() / b.valueOf());
|
|
9701
|
+
});
|
|
9702
|
+
binaryOverload2("uint", "%", "uint", (a, b, ast) => {
|
|
9703
|
+
if (b.valueOf() === 0n) throw new EvaluationError("modulo by zero", ast);
|
|
9704
|
+
return new UnsignedInt(a.valueOf() % b.valueOf());
|
|
9705
|
+
});
|
|
9706
|
+
for (const [left, right] of [
|
|
9707
|
+
["int", "int"],
|
|
9708
|
+
["uint", "uint"],
|
|
9709
|
+
["double", "double"],
|
|
9710
|
+
["string", "string"],
|
|
9711
|
+
["google.protobuf.Timestamp", "google.protobuf.Timestamp"],
|
|
9712
|
+
["google.protobuf.Duration", "google.protobuf.Duration"],
|
|
9713
|
+
["int", "uint"],
|
|
9714
|
+
["int", "double"],
|
|
9715
|
+
["double", "int"],
|
|
9716
|
+
["double", "uint"],
|
|
9717
|
+
["uint", "int"],
|
|
9718
|
+
["uint", "double"]
|
|
9719
|
+
]) {
|
|
9720
|
+
binaryOverload2(left, "<", right, (a, b) => a < b);
|
|
9721
|
+
binaryOverload2(left, "<=", right, (a, b) => a <= b);
|
|
9722
|
+
binaryOverload2(left, ">", right, (a, b) => a > b);
|
|
9723
|
+
binaryOverload2(left, ">=", right, (a, b) => a >= b);
|
|
9724
|
+
}
|
|
9725
|
+
}
|
|
9726
|
+
function isEqual2(a, b, ev) {
|
|
9727
|
+
if (a === b) return true;
|
|
9728
|
+
switch (typeof a) {
|
|
9729
|
+
case "string":
|
|
9730
|
+
return false;
|
|
9731
|
+
case "bigint":
|
|
9732
|
+
if (typeof b === "number") return a == b;
|
|
9733
|
+
return false;
|
|
9734
|
+
case "number":
|
|
9735
|
+
if (typeof b === "bigint") return a == b;
|
|
9736
|
+
return false;
|
|
9737
|
+
case "boolean":
|
|
9738
|
+
return false;
|
|
9739
|
+
case "object":
|
|
9740
|
+
if (typeof b !== "object" || a === null || b === null) return false;
|
|
9741
|
+
const leftType = ev.objectTypesByConstructor.get(a.constructor)?.type;
|
|
9742
|
+
const rightType = ev.objectTypesByConstructor.get(b.constructor)?.type;
|
|
9743
|
+
if (!leftType || leftType !== rightType) return false;
|
|
9744
|
+
const handler = ev.registry.findBinaryOverload("==", leftType, rightType)?.handler;
|
|
9745
|
+
if (!handler) return false;
|
|
9746
|
+
return handler(a, b, null, ev);
|
|
9747
|
+
}
|
|
9748
|
+
throw new EvaluationError(`Cannot compare values of type ${typeof a}`);
|
|
9749
|
+
}
|
|
9750
|
+
|
|
9751
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/type-checker.js
|
|
9752
|
+
var TypeChecker = class {
|
|
9753
|
+
constructor({ ctx, objectTypes, objectTypesByConstructor, registry }) {
|
|
9754
|
+
this.ctx = ctx;
|
|
9755
|
+
this.objectTypes = objectTypes;
|
|
9756
|
+
this.objectTypesByConstructor = objectTypesByConstructor;
|
|
9757
|
+
this.registry = registry;
|
|
9758
|
+
}
|
|
9759
|
+
/**
|
|
9760
|
+
* Get a TypeDeclaration instance for a type name
|
|
9761
|
+
* @param {string} typeName - The type name (e.g., 'string', 'int', 'dyn')
|
|
9762
|
+
* @returns {TypeDeclaration} The type declaration instance
|
|
9763
|
+
*/
|
|
9764
|
+
getType(typeName) {
|
|
9765
|
+
return this.registry.getType(typeName);
|
|
9766
|
+
}
|
|
9767
|
+
createOverlay(varName, varType) {
|
|
9768
|
+
return new this.constructor({
|
|
9769
|
+
ctx: this.ctx.createOverlay(varName, varType),
|
|
9770
|
+
objectTypes: this.objectTypes,
|
|
9771
|
+
objectTypesByConstructor: this.objectTypesByConstructor,
|
|
9772
|
+
registry: this.registry
|
|
9773
|
+
});
|
|
9774
|
+
}
|
|
9775
|
+
/**
|
|
9776
|
+
* Check an expression and return its inferred type
|
|
9777
|
+
* @param {Array|any} ast - The AST node to check
|
|
9778
|
+
* @returns {Object} The inferred type declaration
|
|
9779
|
+
* @throws {TypeError} If type checking fails
|
|
9780
|
+
*/
|
|
9781
|
+
check(ast) {
|
|
9782
|
+
if (ast.checkedType) return ast.checkedType;
|
|
9783
|
+
switch (ast[0]) {
|
|
9784
|
+
case "value":
|
|
9785
|
+
return ast.checkedType ??= this.inferLiteralType(ast[1]);
|
|
9786
|
+
case "id":
|
|
9787
|
+
return ast.checkedType ??= this.checkVariable(ast);
|
|
9788
|
+
case ".":
|
|
9789
|
+
case "[]":
|
|
9790
|
+
return ast.checkedType ??= this.checkAccess(ast);
|
|
9791
|
+
case "call":
|
|
9792
|
+
return ast.checkedType ??= this.checkCall(ast);
|
|
9793
|
+
case "rcall":
|
|
9794
|
+
return ast.checkedType ??= this.checkReceiverCall(ast);
|
|
9795
|
+
case "list":
|
|
9796
|
+
return ast.checkedType ??= this.checkList(ast);
|
|
9797
|
+
case "map":
|
|
9798
|
+
return ast.checkedType ??= this.checkMap(ast);
|
|
9799
|
+
case "?:":
|
|
9800
|
+
return ast.checkedType ??= this.checkTernary(ast);
|
|
9801
|
+
case "||":
|
|
9802
|
+
case "&&":
|
|
9803
|
+
return ast.checkedType ??= this.checkLogicalOp(ast);
|
|
9804
|
+
case "!_":
|
|
9805
|
+
case "-_":
|
|
9806
|
+
return ast.checkedType ??= this.checkUnaryOperator(ast);
|
|
9807
|
+
case "==":
|
|
9808
|
+
case "!=":
|
|
9809
|
+
case "<":
|
|
9810
|
+
case "<=":
|
|
9811
|
+
case ">":
|
|
9812
|
+
case ">=":
|
|
9813
|
+
case "+":
|
|
9814
|
+
case "-":
|
|
9815
|
+
case "*":
|
|
9816
|
+
case "/":
|
|
9817
|
+
case "%":
|
|
9818
|
+
case "in":
|
|
9819
|
+
return ast.checkedType ??= this.checkBinaryOperator(ast);
|
|
9820
|
+
default:
|
|
9821
|
+
throw new TypeError2(`Unknown operation: ${ast[0]}`, ast);
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
inferLiteralType(value) {
|
|
9825
|
+
switch (typeof value) {
|
|
9826
|
+
case "string":
|
|
9827
|
+
return this.getType("string");
|
|
9828
|
+
case "bigint":
|
|
9829
|
+
return this.getType("int");
|
|
9830
|
+
case "number":
|
|
9831
|
+
return this.getType("double");
|
|
9832
|
+
case "boolean":
|
|
9833
|
+
return this.getType("bool");
|
|
9834
|
+
case "object":
|
|
9835
|
+
if (value === null) return this.getType("null");
|
|
9836
|
+
const type = this.objectTypesByConstructor.get(value.constructor)?.type;
|
|
9837
|
+
if (type) return type;
|
|
9838
|
+
throw new TypeError2(`Unsupported type: ${value.constructor?.name || typeof value}`);
|
|
9839
|
+
default:
|
|
9840
|
+
throw new TypeError2(`Unsupported type: ${typeof value}`);
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
checkVariable(ast) {
|
|
9844
|
+
const varName = ast[1];
|
|
9845
|
+
const varType = this.ctx.getType(varName);
|
|
9846
|
+
if (varType !== void 0) return varType;
|
|
9847
|
+
throw new TypeError2(`Unknown variable: ${varName}`, ast);
|
|
9848
|
+
}
|
|
9849
|
+
checkAccess(ast) {
|
|
9850
|
+
const leftType = this.check(ast[1]);
|
|
9851
|
+
if (leftType.kind === "dyn") return leftType;
|
|
9852
|
+
const indexType = ast[0] === "[]" ? this.check(ast[2]) : this.getType("string");
|
|
9853
|
+
const indexTypeName = indexType.type;
|
|
9854
|
+
if (leftType.kind === "list") {
|
|
9855
|
+
if (indexTypeName !== "int" && indexTypeName !== "dyn") {
|
|
9856
|
+
throw new TypeError2(`List index must be int, got '${indexTypeName}'`, ast);
|
|
9857
|
+
}
|
|
9858
|
+
return leftType.valueType;
|
|
9859
|
+
}
|
|
9860
|
+
if (leftType.kind === "map") return leftType.valueType;
|
|
9861
|
+
const customType = this.objectTypes.get(leftType.name);
|
|
9862
|
+
if (customType) {
|
|
9863
|
+
if (!(indexTypeName === "string" || indexTypeName === "dyn")) {
|
|
9864
|
+
throw new TypeError2(
|
|
9865
|
+
`Cannot index type '${leftType.name}' with type '${indexTypeName}'`,
|
|
9866
|
+
ast
|
|
9867
|
+
);
|
|
9868
|
+
}
|
|
9869
|
+
if (customType.fields) {
|
|
9870
|
+
const keyName2 = ast[0] === "." ? ast[2] : void 0;
|
|
9871
|
+
if (keyName2) {
|
|
9872
|
+
const fieldType = customType.fields[keyName2];
|
|
9873
|
+
if (fieldType) return fieldType;
|
|
9874
|
+
throw new TypeError2(`No such key: ${keyName2}`, ast);
|
|
9875
|
+
}
|
|
9876
|
+
}
|
|
9877
|
+
return this.getType("dyn");
|
|
9878
|
+
}
|
|
9879
|
+
throw new TypeError2(`Cannot index type '${leftType}'`, ast);
|
|
9880
|
+
}
|
|
9881
|
+
checkCall(ast) {
|
|
9882
|
+
const functionName = ast[1];
|
|
9883
|
+
const args = ast[2];
|
|
9884
|
+
const byReceiver = (ast.functionCandidates ??= this.registry.getFunctionCandidates(
|
|
9885
|
+
null,
|
|
9886
|
+
functionName,
|
|
9887
|
+
args.length
|
|
9888
|
+
)).filterByReceiverType(null);
|
|
9889
|
+
if (!byReceiver.exists) throw new TypeError2(`Function not found: '${functionName}'`, ast);
|
|
9890
|
+
if (byReceiver.hasMacro) return this.#returnMacroType(null, byReceiver, args, ast);
|
|
9891
|
+
const argTypes = args.map(this.check, this);
|
|
9892
|
+
const decl = byReceiver.findMatch(argTypes);
|
|
9893
|
+
if (!decl) {
|
|
9894
|
+
throw new TypeError2(
|
|
9895
|
+
`found no matching overload for '${functionName}(${argTypes.join(", ")})'`,
|
|
9896
|
+
ast
|
|
9897
|
+
);
|
|
9898
|
+
}
|
|
9899
|
+
return decl.returnType;
|
|
9900
|
+
}
|
|
9901
|
+
#returnMacroType(receiverType, byReceiver, args, ast) {
|
|
9902
|
+
const candidate = byReceiver.functions[0];
|
|
9903
|
+
if (candidate.typeCheck) return candidate.typeCheck(this, receiverType, args, ast);
|
|
9904
|
+
return candidate.returnType;
|
|
9905
|
+
}
|
|
9906
|
+
checkReceiverCall(ast) {
|
|
9907
|
+
const methodName = ast[1];
|
|
9908
|
+
const args = ast[3];
|
|
9909
|
+
const receiverType = this.check(ast[2]);
|
|
9910
|
+
const functionCandidates = ast.functionCandidates ??= this.registry.getFunctionCandidates(
|
|
9911
|
+
receiverType,
|
|
9912
|
+
methodName,
|
|
9913
|
+
args.length
|
|
9914
|
+
);
|
|
9915
|
+
if (!functionCandidates.exists) {
|
|
9916
|
+
throw new TypeError2(
|
|
9917
|
+
`Function not found: '${methodName}' for value of type '${receiverType}'`,
|
|
9918
|
+
ast
|
|
9919
|
+
);
|
|
9920
|
+
}
|
|
9921
|
+
if (receiverType.kind === "dyn") return functionCandidates.returnType || receiverType;
|
|
9922
|
+
const byReceiver = functionCandidates.filterByReceiverType(receiverType);
|
|
9923
|
+
if (byReceiver.hasMacro) return this.#returnMacroType(receiverType, byReceiver, args, ast);
|
|
9924
|
+
const argTypes = args.map(this.check, this);
|
|
9925
|
+
const decl = byReceiver.findMatch(argTypes);
|
|
9926
|
+
if (!decl) {
|
|
9927
|
+
throw new TypeError2(
|
|
9928
|
+
`found no matching overload for '${receiverType.type}.${methodName}(${argTypes.join(
|
|
9929
|
+
", "
|
|
9930
|
+
)})'`,
|
|
9931
|
+
ast
|
|
9932
|
+
);
|
|
9933
|
+
}
|
|
9934
|
+
return decl.returnType;
|
|
9935
|
+
}
|
|
9936
|
+
checkList(ast) {
|
|
9937
|
+
const elements = ast[1];
|
|
9938
|
+
if (elements.length === 0) return this.getType(`list`);
|
|
9939
|
+
const firstType = this.check(elements[0]);
|
|
9940
|
+
const allSameType = elements.every((e) => firstType === this.check(e));
|
|
9941
|
+
if (allSameType) return this.getType(`list<${firstType}>`);
|
|
9942
|
+
return this.getType(`list`);
|
|
9943
|
+
}
|
|
9944
|
+
checkMap(ast) {
|
|
9945
|
+
const entries = ast[1];
|
|
9946
|
+
if (entries.length === 0) return this.getType("map");
|
|
9947
|
+
const firstKeyType = this.check(entries[0][0]);
|
|
9948
|
+
const firstValueType = this.check(entries[0][1]);
|
|
9949
|
+
let allSameKeyType = true;
|
|
9950
|
+
let allSameValueType = true;
|
|
9951
|
+
for (let i = 1; i < entries.length; i++) {
|
|
9952
|
+
const [key, value] = entries[i];
|
|
9953
|
+
if (firstKeyType !== this.check(key)) allSameKeyType = false;
|
|
9954
|
+
if (firstValueType !== this.check(value)) allSameValueType = false;
|
|
9955
|
+
}
|
|
9956
|
+
const inferredKeyType = allSameKeyType ? firstKeyType : "dyn";
|
|
9957
|
+
const inferredValueType = allSameValueType ? firstValueType : "dyn";
|
|
9958
|
+
return this.getType(`map<${inferredKeyType}, ${inferredValueType}>`);
|
|
9959
|
+
}
|
|
9960
|
+
checkTernary(ast) {
|
|
9961
|
+
const condType = this.check(ast[1]);
|
|
9962
|
+
if (!condType.isDynOrBool()) {
|
|
9963
|
+
throw new TypeError2(`Ternary condition must be bool, got '${condType}'`, ast);
|
|
9964
|
+
}
|
|
9965
|
+
const trueType = this.check(ast[2]);
|
|
9966
|
+
const falseType = this.check(ast[3]);
|
|
9967
|
+
if (trueType === falseType) return trueType;
|
|
9968
|
+
if (trueType.name === "dyn") return trueType;
|
|
9969
|
+
if (falseType.name === "dyn") return falseType;
|
|
9970
|
+
throw new TypeError2(
|
|
9971
|
+
`Ternary branches must have the same type, got '${trueType}' and '${falseType}'`,
|
|
9972
|
+
ast
|
|
9973
|
+
);
|
|
9974
|
+
}
|
|
9975
|
+
checkLogicalOp(ast) {
|
|
9976
|
+
const leftType = this.check(ast[1]);
|
|
9977
|
+
const rightType = this.check(ast[2]);
|
|
9978
|
+
if (!leftType.isDynOrBool()) {
|
|
9979
|
+
throw new TypeError2(`Logical operator requires bool operands, got '${leftType}'`, ast);
|
|
9980
|
+
}
|
|
9981
|
+
if (!rightType.isDynOrBool()) {
|
|
9982
|
+
throw new TypeError2(`Logical operator requires bool operands, got '${rightType}'`, ast);
|
|
9983
|
+
}
|
|
9984
|
+
return this.getType("bool");
|
|
9985
|
+
}
|
|
9986
|
+
checkUnaryOperator(ast) {
|
|
9987
|
+
const op = ast[0];
|
|
9988
|
+
const operandType = this.check(ast[1]);
|
|
9989
|
+
if (operandType.kind === "dyn") return op === "!_" ? this.getType("bool") : operandType;
|
|
9990
|
+
const overload = this.registry.findUnaryOverload(op, operandType);
|
|
9991
|
+
if (overload) return overload.returnType;
|
|
9992
|
+
throw new TypeError2(`no such overload: ${op[0]}${operandType.type}`, ast);
|
|
9993
|
+
}
|
|
9994
|
+
checkBinaryOperator(ast) {
|
|
9995
|
+
const op = ast[0];
|
|
9996
|
+
const leftType = this.check(ast[1]);
|
|
9997
|
+
const rightType = this.check(ast[2]);
|
|
9998
|
+
const type = this.registry.checkBinaryOverload(op, leftType, rightType);
|
|
9999
|
+
if (type) return type;
|
|
10000
|
+
throw new TypeError2(`no such overload: ${leftType} ${op} ${rightType}`, ast);
|
|
10001
|
+
}
|
|
10002
|
+
};
|
|
10003
|
+
|
|
10004
|
+
// ../../node_modules/@marcbachmann/cel-js/lib/evaluator.js
|
|
10005
|
+
var globalRegistry = createRegistry();
|
|
10006
|
+
registerOverloads(globalRegistry);
|
|
10007
|
+
registerFunctions(globalRegistry);
|
|
10008
|
+
var handlers = new Map(
|
|
10009
|
+
Object.entries({
|
|
10010
|
+
value(ast) {
|
|
10011
|
+
return ast[1];
|
|
10012
|
+
},
|
|
10013
|
+
id(ast, ev) {
|
|
10014
|
+
return ev.value(ast[1], ast).value;
|
|
10015
|
+
},
|
|
10016
|
+
"||"(ast, ev) {
|
|
10017
|
+
try {
|
|
10018
|
+
const left = ev.eval(ast[1]);
|
|
10019
|
+
if (left === true) return true;
|
|
10020
|
+
if (left !== false) {
|
|
10021
|
+
throw new EvaluationError("Left operand of || is not a boolean", ast[1]);
|
|
10022
|
+
}
|
|
10023
|
+
} catch (err) {
|
|
10024
|
+
if (err.message.includes("Unknown variable")) throw err;
|
|
10025
|
+
if (err.message.includes("is not a boolean")) throw err;
|
|
10026
|
+
const right2 = ev.eval(ast[2]);
|
|
10027
|
+
if (right2 === true) return true;
|
|
10028
|
+
if (right2 === false) throw err;
|
|
10029
|
+
throw new EvaluationError("Right operand of || is not a boolean", ast[2]);
|
|
10030
|
+
}
|
|
10031
|
+
const right = ev.eval(ast[2]);
|
|
10032
|
+
if (typeof right === "boolean") return right;
|
|
10033
|
+
throw new EvaluationError("Right operand of || is not a boolean", ast[2]);
|
|
10034
|
+
},
|
|
10035
|
+
"&&"(ast, ev) {
|
|
10036
|
+
try {
|
|
10037
|
+
const left = ev.eval(ast[1]);
|
|
10038
|
+
if (left === false) return false;
|
|
10039
|
+
if (left !== true) {
|
|
10040
|
+
throw new EvaluationError("Left operand of && is not a boolean", ast[1]);
|
|
10041
|
+
}
|
|
10042
|
+
} catch (err) {
|
|
10043
|
+
if (err.message.includes("Unknown variable")) throw err;
|
|
10044
|
+
if (err.message.includes("is not a boolean")) throw err;
|
|
10045
|
+
const right2 = ev.eval(ast[2]);
|
|
10046
|
+
if (right2 === false) return false;
|
|
10047
|
+
if (right2 === true) throw err;
|
|
10048
|
+
throw new EvaluationError("Right operand of && is not a boolean", ast[2]);
|
|
10049
|
+
}
|
|
10050
|
+
const right = ev.eval(ast[2]);
|
|
10051
|
+
if (typeof right === "boolean") return right;
|
|
10052
|
+
throw new EvaluationError("Right operand of && is not a boolean", ast[2]);
|
|
10053
|
+
},
|
|
10054
|
+
"."(ast, ev) {
|
|
10055
|
+
const left = ev.eval(ast[1]);
|
|
10056
|
+
return ev.debugType(left).field(left, ast[2], ast, ev);
|
|
10057
|
+
},
|
|
10058
|
+
"[]"(ast, ev) {
|
|
10059
|
+
const left = ev.eval(ast[1]);
|
|
10060
|
+
return ev.debugType(left).field(left, ev.eval(ast[2]), ast, ev);
|
|
10061
|
+
},
|
|
10062
|
+
rcall(ast, ev) {
|
|
10063
|
+
const functionName = ast[1];
|
|
10064
|
+
const receiver = ev.eval(ast[2]);
|
|
10065
|
+
const checkedType = ast[2].checkedType || ev.celTypes.dyn;
|
|
10066
|
+
const argAst = ast[3];
|
|
10067
|
+
const argLen = argAst.length;
|
|
10068
|
+
const functionCandidates = ast.functionCandidates ??= ev.registry.getFunctionCandidates(
|
|
10069
|
+
checkedType,
|
|
10070
|
+
functionName,
|
|
10071
|
+
argLen
|
|
10072
|
+
);
|
|
10073
|
+
const receiverType = checkedType.kind !== "dyn" ? checkedType : ev.debugType(receiver);
|
|
10074
|
+
if (!functionCandidates.exists) {
|
|
10075
|
+
throw new EvaluationError(
|
|
10076
|
+
`Function not found: '${functionName}' for value of type '${receiverType}'`,
|
|
10077
|
+
ast
|
|
10078
|
+
);
|
|
10079
|
+
}
|
|
10080
|
+
const byReceiver = functionCandidates.filterByReceiverType(receiverType);
|
|
10081
|
+
let args;
|
|
10082
|
+
let argTypes;
|
|
10083
|
+
if (byReceiver.hasMacro) {
|
|
10084
|
+
args = argAst;
|
|
10085
|
+
argTypes = ast.argMacroTypes ??= new Array(argLen).fill(ev.registry.getFunctionType("ast"));
|
|
10086
|
+
} else {
|
|
10087
|
+
args = ast.argValues ??= new Array(argLen);
|
|
10088
|
+
argTypes = ast.argTypes ??= new Array(argLen);
|
|
10089
|
+
for (let i = 0; i < argLen; i++) {
|
|
10090
|
+
const arg = argAst[i];
|
|
10091
|
+
args[i] = ev.eval(arg);
|
|
10092
|
+
argTypes[i] = getFunctionArgType(arg.checkedType, ev.debugType(args[i]), ev);
|
|
10093
|
+
}
|
|
10094
|
+
}
|
|
10095
|
+
const decl = byReceiver.findMatch(argTypes);
|
|
10096
|
+
if (!decl) {
|
|
10097
|
+
throw new EvaluationError(
|
|
10098
|
+
`found no matching overload for '${receiverType.type}.${functionName}(${argTypes.join(
|
|
10099
|
+
", "
|
|
10100
|
+
)})'`,
|
|
10101
|
+
ast
|
|
10102
|
+
);
|
|
10103
|
+
}
|
|
10104
|
+
try {
|
|
10105
|
+
if (decl.macro) return decl.handler.call(ev, receiver, ast);
|
|
10106
|
+
return decl.handler.call(ev, receiver, ...args);
|
|
10107
|
+
} catch (err) {
|
|
10108
|
+
if (err instanceof EvaluationError) throw err.withAst(ast);
|
|
10109
|
+
throw err;
|
|
10110
|
+
}
|
|
10111
|
+
},
|
|
10112
|
+
call(ast, ev) {
|
|
10113
|
+
const functionName = ast[1];
|
|
10114
|
+
const argAst = ast[2];
|
|
10115
|
+
const argLen = argAst.length;
|
|
10116
|
+
const functionCandidates = ast.functionCandidates ??= ev.registry.getFunctionCandidates(
|
|
10117
|
+
null,
|
|
10118
|
+
functionName,
|
|
10119
|
+
argLen
|
|
10120
|
+
);
|
|
10121
|
+
if (functionCandidates.exists === false) {
|
|
10122
|
+
throw new EvaluationError(`Function not found: '${functionName}'`, ast);
|
|
10123
|
+
}
|
|
10124
|
+
const byReceiver = functionCandidates.filterByReceiverType(null);
|
|
10125
|
+
let args;
|
|
10126
|
+
let argTypes;
|
|
10127
|
+
if (functionCandidates.hasMacro) {
|
|
10128
|
+
args = argAst;
|
|
10129
|
+
argTypes = ast.argMacroTypes ??= new Array(argLen).fill(ev.registry.getFunctionType("ast"));
|
|
10130
|
+
} else {
|
|
10131
|
+
args = ast.argValues ??= new Array(argLen);
|
|
10132
|
+
argTypes = ast.argTypes ??= new Array(argLen);
|
|
10133
|
+
for (let i = 0; i < argLen; i++) {
|
|
10134
|
+
const arg = argAst[i];
|
|
10135
|
+
args[i] = ev.eval(arg);
|
|
10136
|
+
argTypes[i] = getFunctionArgType(arg.checkedType, ev.debugType(args[i]), ev);
|
|
10137
|
+
}
|
|
10138
|
+
}
|
|
10139
|
+
const decl = byReceiver.findMatch(argTypes);
|
|
10140
|
+
if (!decl) {
|
|
10141
|
+
throw new EvaluationError(
|
|
10142
|
+
`found no matching overload for '${functionName}(${argTypes.join(", ")})'`,
|
|
10143
|
+
ast
|
|
10144
|
+
);
|
|
10145
|
+
}
|
|
10146
|
+
try {
|
|
10147
|
+
if (decl.macro) return decl.handler.call(ev, ast);
|
|
10148
|
+
return decl.handler.apply(ev, args);
|
|
10149
|
+
} catch (err) {
|
|
10150
|
+
if (err instanceof EvaluationError) throw err.withAst(ast);
|
|
10151
|
+
throw err;
|
|
10152
|
+
}
|
|
10153
|
+
},
|
|
10154
|
+
list(ast, ev) {
|
|
10155
|
+
const elements = ast[1];
|
|
10156
|
+
const result = new Array(elements.length);
|
|
10157
|
+
for (let i = 0; i < elements.length; i++) result[i] = ev.eval(elements[i]);
|
|
10158
|
+
return result;
|
|
10159
|
+
},
|
|
10160
|
+
map(ast, ev) {
|
|
10161
|
+
const result = {};
|
|
10162
|
+
const props = ast[1];
|
|
10163
|
+
for (let i = 0; i < props.length; i++) {
|
|
10164
|
+
const e = props[i];
|
|
10165
|
+
result[ev.eval(e[0])] = ev.eval(e[1]);
|
|
10166
|
+
}
|
|
10167
|
+
return result;
|
|
10168
|
+
},
|
|
10169
|
+
"?:"(ast, ev) {
|
|
10170
|
+
const condition = ev.eval(ast[1]);
|
|
10171
|
+
if (condition === true) return ev.eval(ast[2]);
|
|
10172
|
+
else if (condition === false) return ev.eval(ast[3]);
|
|
10173
|
+
throw new EvaluationError("Ternary condition must be a boolean");
|
|
10174
|
+
},
|
|
10175
|
+
"!_": unaryOverload,
|
|
10176
|
+
"-_": unaryOverload,
|
|
10177
|
+
"!=": binaryOverload,
|
|
10178
|
+
"==": binaryOverload,
|
|
10179
|
+
in: binaryOverload,
|
|
10180
|
+
"+": binaryOverload,
|
|
10181
|
+
"-": binaryOverload,
|
|
10182
|
+
"*": binaryOverload,
|
|
10183
|
+
"/": binaryOverload,
|
|
10184
|
+
"%": binaryOverload,
|
|
10185
|
+
"<": binaryOverload,
|
|
10186
|
+
"<=": binaryOverload,
|
|
10187
|
+
">": binaryOverload,
|
|
10188
|
+
">=": binaryOverload
|
|
10189
|
+
})
|
|
10190
|
+
);
|
|
10191
|
+
function unaryOverload(ast, ev) {
|
|
10192
|
+
const left = ev.eval(ast[1]);
|
|
10193
|
+
const leftType = ev.debugType(left);
|
|
10194
|
+
const overload = ev.registry.findUnaryOverload(ast[0], leftType);
|
|
10195
|
+
if (overload) return overload.handler(left);
|
|
10196
|
+
throw new EvaluationError(`no such overload: ${ast[0][0]}${leftType}`, ast);
|
|
10197
|
+
}
|
|
10198
|
+
function binaryOverload(ast, ev) {
|
|
10199
|
+
const left = ev.eval(ast[1]);
|
|
10200
|
+
const right = ev.eval(ast[2]);
|
|
10201
|
+
const leftType = getOperandType(ast[1].checkedType, ev.debugType(left), ev);
|
|
10202
|
+
const rightType = getOperandType(ast[2].checkedType, ev.debugType(right), ev);
|
|
10203
|
+
const overload = ev.registry.findBinaryOverload(ast[0], leftType, rightType);
|
|
10204
|
+
if (overload) return overload.handler(left, right, ast, ev);
|
|
10205
|
+
throw new EvaluationError(`no such overload: ${leftType} ${ast[0]} ${rightType}`, ast);
|
|
10206
|
+
}
|
|
10207
|
+
function getOperandType(checkedType, runtimeType, ev) {
|
|
10208
|
+
if (checkedType === runtimeType || !checkedType) return runtimeType;
|
|
10209
|
+
if (checkedType.kind === "dyn") return ev.registry.getDynType(runtimeType);
|
|
10210
|
+
if (checkedType.kind !== runtimeType.kind) {
|
|
10211
|
+
throw new EvaluationError(`Type mismatch: expected ${checkedType}, got ${runtimeType}`);
|
|
10212
|
+
}
|
|
10213
|
+
return checkedType;
|
|
10214
|
+
}
|
|
10215
|
+
function getFunctionArgType(checkedType, runtimeType) {
|
|
10216
|
+
if (checkedType === runtimeType || !checkedType || checkedType.kind === "dyn") return runtimeType;
|
|
10217
|
+
if (checkedType.kind !== runtimeType.kind) {
|
|
10218
|
+
throw new EvaluationError(`Type mismatch: expected ${checkedType}, got ${runtimeType}`);
|
|
10219
|
+
}
|
|
10220
|
+
return checkedType;
|
|
10221
|
+
}
|
|
10222
|
+
var Context = class {
|
|
10223
|
+
createOverlay(name, type) {
|
|
10224
|
+
return new OverlayContext({
|
|
10225
|
+
parent: this,
|
|
10226
|
+
variableName: name,
|
|
10227
|
+
variableType: type
|
|
10228
|
+
});
|
|
10229
|
+
}
|
|
10230
|
+
getVariable(name) {
|
|
10231
|
+
const type = this.getType(name);
|
|
10232
|
+
if (!type) return;
|
|
10233
|
+
const value = this.getValue(name);
|
|
10234
|
+
if (value === void 0) return;
|
|
10235
|
+
return { type, value };
|
|
10236
|
+
}
|
|
10237
|
+
};
|
|
10238
|
+
var RootContext = class extends Context {
|
|
10239
|
+
constructor({ variables, fallbackValues }) {
|
|
10240
|
+
super();
|
|
10241
|
+
this.variables = variables;
|
|
10242
|
+
this.fallbackValues = fallbackValues;
|
|
10243
|
+
this.primary = null;
|
|
10244
|
+
this.primaryGetter = this.#getFromSecondary;
|
|
10245
|
+
}
|
|
10246
|
+
getType(name) {
|
|
10247
|
+
return this.variables.get(name);
|
|
10248
|
+
}
|
|
10249
|
+
getValue() {
|
|
10250
|
+
}
|
|
10251
|
+
setPrimaryContext(primary) {
|
|
10252
|
+
if (typeof primary !== "object") throw new EvaluationError("Context must be an object");
|
|
10253
|
+
this.primary = primary;
|
|
10254
|
+
if (!primary) this.getValue = this.#getFromSecondary;
|
|
10255
|
+
else if (primary instanceof Map) this.getValue = this.#getFromMap;
|
|
10256
|
+
else this.getValue = this.#getFromObject;
|
|
10257
|
+
}
|
|
10258
|
+
#getFromSecondary(key) {
|
|
10259
|
+
return this.fallbackValues.get(key);
|
|
10260
|
+
}
|
|
10261
|
+
#getFromObject(key) {
|
|
10262
|
+
const v = Object.hasOwn(this.primary, key) ? this.primary[key] : void 0;
|
|
10263
|
+
if (v !== void 0) return v;
|
|
10264
|
+
return this.fallbackValues.get(key);
|
|
10265
|
+
}
|
|
10266
|
+
#getFromMap(key) {
|
|
10267
|
+
const v = this.primary.get(key);
|
|
10268
|
+
if (v !== void 0) return v;
|
|
10269
|
+
return this.fallbackValues.get(key);
|
|
10270
|
+
}
|
|
10271
|
+
};
|
|
10272
|
+
var OverlayContext = class extends Context {
|
|
10273
|
+
constructor({ parent, variableName, variableType }) {
|
|
10274
|
+
super();
|
|
10275
|
+
this.parent = parent;
|
|
10276
|
+
this.variableName = variableName;
|
|
10277
|
+
this.variableType = variableType;
|
|
10278
|
+
this.variableValue = void 0;
|
|
10279
|
+
}
|
|
10280
|
+
getType(name) {
|
|
10281
|
+
if (this.variableName === name) return this.variableType;
|
|
10282
|
+
return this.parent.getType(name);
|
|
7470
10283
|
}
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
10284
|
+
getValue(name) {
|
|
10285
|
+
if (this.variableName === name) return this.variableValue;
|
|
10286
|
+
return this.parent.getValue(name);
|
|
10287
|
+
}
|
|
10288
|
+
setVariableValue(value) {
|
|
10289
|
+
this.variableValue = value;
|
|
10290
|
+
}
|
|
10291
|
+
};
|
|
10292
|
+
var registryByEnvironment = /* @__PURE__ */ new WeakMap();
|
|
10293
|
+
var globalValues = new Map(Object.entries(TYPES));
|
|
10294
|
+
var Environment = class _Environment {
|
|
10295
|
+
#variables;
|
|
10296
|
+
#registry;
|
|
10297
|
+
#evaluator;
|
|
10298
|
+
#typeChecker;
|
|
10299
|
+
#opts;
|
|
10300
|
+
constructor(opts) {
|
|
10301
|
+
this.#opts = opts;
|
|
10302
|
+
this.#registry = (opts?.inherit instanceof _Environment ? registryByEnvironment.get(opts.inherit) : globalRegistry).clone({
|
|
10303
|
+
unlistedVariablesAreDyn: opts?.unlistedVariablesAreDyn ?? false
|
|
10304
|
+
});
|
|
10305
|
+
this.#variables = this.#registry.variables;
|
|
10306
|
+
const childOpts = {
|
|
10307
|
+
registry: this.#registry,
|
|
10308
|
+
variables: this.#variables,
|
|
10309
|
+
objectTypes: this.#registry.objectTypes,
|
|
10310
|
+
objectTypesByConstructor: this.#registry.objectTypesByConstructor,
|
|
10311
|
+
ctx: new RootContext({
|
|
10312
|
+
variables: this.#variables,
|
|
10313
|
+
fallbackValues: globalValues
|
|
10314
|
+
})
|
|
10315
|
+
};
|
|
10316
|
+
this.#typeChecker = new TypeChecker(childOpts);
|
|
10317
|
+
this.#evaluator = new Evaluator({ ...childOpts, typeChecker: this.#typeChecker });
|
|
10318
|
+
registryByEnvironment.set(this, this.#registry);
|
|
10319
|
+
Object.freeze(this);
|
|
10320
|
+
}
|
|
10321
|
+
clone(opts) {
|
|
10322
|
+
return new _Environment({
|
|
10323
|
+
inherit: this,
|
|
10324
|
+
unlistedVariablesAreDyn: this.#opts?.unlistedVariablesAreDyn ?? false
|
|
10325
|
+
});
|
|
10326
|
+
}
|
|
10327
|
+
registerFunction(string, handler) {
|
|
10328
|
+
this.#registry.registerFunctionOverload(string, handler);
|
|
10329
|
+
return this;
|
|
10330
|
+
}
|
|
10331
|
+
registerOperator(string, handler) {
|
|
10332
|
+
this.#registry.registerOperatorOverload(string, handler);
|
|
10333
|
+
return this;
|
|
10334
|
+
}
|
|
10335
|
+
registerType(typename, constructor) {
|
|
10336
|
+
this.#registry.registerType(typename, constructor);
|
|
10337
|
+
return this;
|
|
10338
|
+
}
|
|
10339
|
+
registerVariable(name, type) {
|
|
10340
|
+
this.#registry.registerVariable(name, type);
|
|
10341
|
+
return this;
|
|
10342
|
+
}
|
|
10343
|
+
hasVariable(name) {
|
|
10344
|
+
return this.#registry.variables.has(name);
|
|
10345
|
+
}
|
|
10346
|
+
check(expression) {
|
|
10347
|
+
try {
|
|
10348
|
+
const typeDecl = this.#typeChecker.check(new Parser(expression).parse());
|
|
10349
|
+
return { valid: true, type: this.#formatTypeForCheck(typeDecl) };
|
|
10350
|
+
} catch (e) {
|
|
10351
|
+
return { valid: false, error: e };
|
|
10352
|
+
}
|
|
10353
|
+
}
|
|
10354
|
+
#checkAST(ast) {
|
|
10355
|
+
try {
|
|
10356
|
+
const typeDecl = this.#typeChecker.check(ast);
|
|
10357
|
+
return { valid: true, type: this.#formatTypeForCheck(typeDecl) };
|
|
10358
|
+
} catch (e) {
|
|
10359
|
+
return { valid: false, error: e };
|
|
10360
|
+
}
|
|
10361
|
+
}
|
|
10362
|
+
#formatTypeForCheck(typeDecl) {
|
|
10363
|
+
if (typeDecl.name === `list<dyn>`) return "list";
|
|
10364
|
+
if (typeDecl.name === `map<dyn, dyn>`) return "map";
|
|
10365
|
+
return `${typeDecl.name}`;
|
|
10366
|
+
}
|
|
10367
|
+
parse(expression) {
|
|
10368
|
+
const ast = new Parser(expression).parse();
|
|
10369
|
+
const evaluateParsed = this.#evaluateAST.bind(this, ast);
|
|
10370
|
+
evaluateParsed.check = this.#checkAST.bind(this, ast);
|
|
10371
|
+
evaluateParsed.ast = ast;
|
|
10372
|
+
return evaluateParsed;
|
|
10373
|
+
}
|
|
10374
|
+
evaluate(expression, context) {
|
|
10375
|
+
return this.#evaluateAST(new Parser(expression).parse(), context);
|
|
10376
|
+
}
|
|
10377
|
+
#evaluateAST(ast, context = null) {
|
|
10378
|
+
const evaluator = this.#evaluator;
|
|
10379
|
+
evaluator.ctx.setPrimaryContext(context);
|
|
10380
|
+
evaluator.tryCheck(ast);
|
|
10381
|
+
return evaluator.eval(ast);
|
|
10382
|
+
}
|
|
10383
|
+
};
|
|
10384
|
+
function unsupportedType(type) {
|
|
10385
|
+
throw new EvaluationError(`Unsupported type: ${type}`);
|
|
10386
|
+
}
|
|
10387
|
+
var Evaluator = class {
|
|
10388
|
+
handlers = handlers;
|
|
10389
|
+
celTypes = celTypes;
|
|
10390
|
+
constructor({ registry, objectTypes, objectTypesByConstructor, typeChecker, ctx }) {
|
|
10391
|
+
this.objectTypes = objectTypes;
|
|
10392
|
+
this.objectTypesByConstructor = objectTypesByConstructor;
|
|
10393
|
+
this.registry = registry;
|
|
10394
|
+
this.typeChecker = typeChecker;
|
|
10395
|
+
this.ctx = ctx;
|
|
10396
|
+
}
|
|
10397
|
+
value(name, ast) {
|
|
10398
|
+
const dec = this.ctx.getVariable(name);
|
|
10399
|
+
if (!dec) throw new EvaluationError(`Unknown variable: ${name}`, ast);
|
|
10400
|
+
const valueType = this.debugType(dec.value);
|
|
10401
|
+
if (dec.type.matches(valueType)) return dec;
|
|
10402
|
+
throw new EvaluationError(
|
|
10403
|
+
`Variable '${name}' is not of type '${dec.type}', got '${valueType}'`,
|
|
10404
|
+
ast
|
|
7488
10405
|
);
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
10406
|
+
}
|
|
10407
|
+
predicateEvaluator(functionName, ast) {
|
|
10408
|
+
return new PredicateEvaluator(this, functionName, ast);
|
|
10409
|
+
}
|
|
10410
|
+
debugType(v) {
|
|
10411
|
+
switch (typeof v) {
|
|
10412
|
+
case "string":
|
|
10413
|
+
return this.celTypes.string;
|
|
10414
|
+
case "bigint":
|
|
10415
|
+
return this.celTypes.int;
|
|
10416
|
+
case "number":
|
|
10417
|
+
return this.celTypes.double;
|
|
10418
|
+
case "boolean":
|
|
10419
|
+
return this.celTypes.bool;
|
|
10420
|
+
case "object":
|
|
10421
|
+
if (v === null) return this.celTypes.null;
|
|
10422
|
+
return this.objectTypesByConstructor.get(v.constructor)?.type || unsupportedType(v.constructor?.name || typeof v);
|
|
10423
|
+
default:
|
|
10424
|
+
unsupportedType(typeof v);
|
|
10425
|
+
}
|
|
10426
|
+
}
|
|
10427
|
+
tryCheck(ast) {
|
|
10428
|
+
try {
|
|
10429
|
+
return ast.checkedType || this.typeChecker.check(ast);
|
|
10430
|
+
} catch (_e) {
|
|
10431
|
+
}
|
|
10432
|
+
}
|
|
10433
|
+
eval(ast) {
|
|
10434
|
+
const handler = this.handlers.get(ast[0]);
|
|
10435
|
+
if (handler) return handler(ast, this);
|
|
10436
|
+
throw new EvaluationError(`Unknown operation: ${ast[0]}`, ast);
|
|
10437
|
+
}
|
|
10438
|
+
};
|
|
10439
|
+
var PredicateEvaluator = class extends Evaluator {
|
|
10440
|
+
constructor(e, functionName, ast) {
|
|
10441
|
+
super(e);
|
|
10442
|
+
const [identifier, predicate] = ast[3];
|
|
10443
|
+
if (identifier?.[0] !== "id") {
|
|
10444
|
+
throw new EvaluationError(`${functionName} invalid predicate iteration variable`, ast);
|
|
10445
|
+
}
|
|
10446
|
+
this.ast = ast;
|
|
10447
|
+
this.functionName = functionName;
|
|
10448
|
+
this.predicateVariable = identifier[1];
|
|
10449
|
+
this.predicateExpression = predicate;
|
|
10450
|
+
const receiverType = ast[2].checkedType || this.celTypes.dyn;
|
|
10451
|
+
let predicateType = this.celTypes.dyn;
|
|
10452
|
+
if (receiverType.type === "list") predicateType = receiverType.valueType;
|
|
10453
|
+
if (receiverType.type === "map") predicateType = receiverType.keyType;
|
|
10454
|
+
this.ctx = this.ctx.createOverlay(this.predicateVariable, predicateType);
|
|
10455
|
+
this.tryCheck(predicate);
|
|
10456
|
+
}
|
|
10457
|
+
getIterableItems(collection) {
|
|
10458
|
+
if (Array.isArray(collection)) return collection;
|
|
10459
|
+
if (collection instanceof Set) return [...collection];
|
|
10460
|
+
if (collection instanceof Map) return [...collection.keys()];
|
|
10461
|
+
if (typeof collection === "object") return Object.keys(collection);
|
|
10462
|
+
throw new EvaluationError(
|
|
10463
|
+
`${this.functionName} cannot iterate over non-collection type. argument must be a list, map, or object`,
|
|
10464
|
+
this.ast
|
|
7494
10465
|
);
|
|
7495
|
-
return { header, payload, valid };
|
|
7496
10466
|
}
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7509
|
-
|
|
10467
|
+
childEvaluateBool(item) {
|
|
10468
|
+
this.ctx.setVariableValue(item);
|
|
10469
|
+
switch (this.eval(this.predicateExpression)) {
|
|
10470
|
+
case true:
|
|
10471
|
+
return true;
|
|
10472
|
+
case false:
|
|
10473
|
+
return false;
|
|
10474
|
+
default:
|
|
10475
|
+
throw new EvaluationError(
|
|
10476
|
+
`${this.functionName} predicate result is not a boolean`,
|
|
10477
|
+
Array.isArray(this.predicateExpression) ? this.predicateExpression : this.ast
|
|
10478
|
+
);
|
|
10479
|
+
}
|
|
10480
|
+
}
|
|
10481
|
+
childEvaluate(item) {
|
|
10482
|
+
this.ctx.setVariableValue(item);
|
|
10483
|
+
return this.eval(this.predicateExpression);
|
|
10484
|
+
}
|
|
10485
|
+
};
|
|
10486
|
+
var globalEnvironment = new Environment({
|
|
10487
|
+
unlistedVariablesAreDyn: true
|
|
10488
|
+
});
|
|
7510
10489
|
|
|
7511
|
-
// ../state-manager/src/
|
|
10490
|
+
// ../state-manager/src/multiplayerPolicies.ts
|
|
7512
10491
|
var import_noya_utils7 = require("@noya-app/noya-utils");
|
|
7513
|
-
var
|
|
10492
|
+
var celEnvironment = new Environment({
|
|
10493
|
+
unlistedVariablesAreDyn: true
|
|
10494
|
+
});
|
|
10495
|
+
var MAX_SAFE_INTEGER_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
10496
|
+
celEnvironment.registerFunction("random(): double", () => Math.random()).registerFunction("randomInt(int, int): int", (min, max) => {
|
|
10497
|
+
if (max < min) {
|
|
10498
|
+
throw new Error(
|
|
10499
|
+
"randomInt requires the second argument to be greater than or equal to the first"
|
|
10500
|
+
);
|
|
10501
|
+
}
|
|
10502
|
+
if (max === min) {
|
|
10503
|
+
return min;
|
|
10504
|
+
}
|
|
10505
|
+
const span = max - min + 1n;
|
|
10506
|
+
if (span > MAX_SAFE_INTEGER_BIGINT) {
|
|
10507
|
+
throw new Error("randomInt range is too large to generate safely");
|
|
10508
|
+
}
|
|
10509
|
+
const spanNumber = Number(span);
|
|
10510
|
+
const offset = BigInt(Math.floor(Math.random() * spanNumber));
|
|
10511
|
+
return min + offset;
|
|
10512
|
+
}).registerFunction(
|
|
10513
|
+
"now(): double",
|
|
10514
|
+
function() {
|
|
10515
|
+
const nowVariable = this.ctx.getVariable("now");
|
|
10516
|
+
const nowValue = nowVariable?.value ?? Date.now();
|
|
10517
|
+
return typeof nowValue === "number" ? nowValue : Number(nowValue);
|
|
10518
|
+
}
|
|
10519
|
+
).registerFunction(
|
|
10520
|
+
"timestamp(): string",
|
|
10521
|
+
function() {
|
|
10522
|
+
const nowVariable = this.ctx.getVariable("now");
|
|
10523
|
+
const nowValue = typeof nowVariable?.value === "number" ? nowVariable.value : typeof nowVariable?.value === "string" ? Number(nowVariable.value) : Date.now();
|
|
10524
|
+
return new Date(nowValue).toISOString();
|
|
10525
|
+
}
|
|
10526
|
+
).registerFunction("uuid(): string", () => (0, import_noya_utils7.uuid)());
|
|
10527
|
+
var READ_DENIED = Symbol("readDenied");
|
|
7514
10528
|
|
|
7515
10529
|
// ../state-manager/src/stateManager.ts
|
|
7516
10530
|
var import_observable9 = require("@noya-app/observable");
|
|
7517
10531
|
|
|
7518
10532
|
// ../state-manager/src/multiplayer.ts
|
|
7519
|
-
var createHash = (value, options) => (0,
|
|
10533
|
+
var createHash = (value, options) => (0, import_noya_utils8.hash)(value, { ...options, ignoreUndefinedProperties: true });
|
|
7520
10534
|
|
|
7521
10535
|
// ../state-manager/src/NoyaManager.ts
|
|
7522
|
-
var
|
|
7523
|
-
var
|
|
10536
|
+
var import_noya_utils19 = require("@noya-app/noya-utils");
|
|
10537
|
+
var import_observable21 = require("@noya-app/observable");
|
|
7524
10538
|
|
|
7525
10539
|
// ../noya-pipeline/src/graphToTasks.ts
|
|
7526
10540
|
var import_observable11 = require("@noya-app/observable");
|
|
7527
10541
|
|
|
7528
10542
|
// ../noya-pipeline/src/state.ts
|
|
7529
|
-
var
|
|
10543
|
+
var import_noya_utils9 = require("@noya-app/noya-utils");
|
|
7530
10544
|
var rectSchema = Type.Object({
|
|
7531
10545
|
x: Type.Number(),
|
|
7532
10546
|
y: Type.Number(),
|
|
@@ -7631,11 +10645,11 @@ var import_observable12 = require("@noya-app/observable");
|
|
|
7631
10645
|
var import_observable13 = require("@noya-app/observable");
|
|
7632
10646
|
|
|
7633
10647
|
// ../state-manager/src/ResourceManager.ts
|
|
7634
|
-
var
|
|
10648
|
+
var import_noya_utils10 = require("@noya-app/noya-utils");
|
|
7635
10649
|
var import_observable14 = require("@noya-app/observable");
|
|
7636
10650
|
|
|
7637
10651
|
// ../state-manager/src/rpcManager.ts
|
|
7638
|
-
var
|
|
10652
|
+
var import_noya_utils11 = require("@noya-app/noya-utils");
|
|
7639
10653
|
var import_observable15 = require("@noya-app/observable");
|
|
7640
10654
|
|
|
7641
10655
|
// ../state-manager/src/SecretManager.ts
|
|
@@ -7644,18 +10658,144 @@ var import_observable16 = require("@noya-app/observable");
|
|
|
7644
10658
|
// ../state-manager/src/TaskManager.ts
|
|
7645
10659
|
var import_observable17 = require("@noya-app/observable");
|
|
7646
10660
|
|
|
7647
|
-
// ../state-manager/src/
|
|
7648
|
-
var
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
10661
|
+
// ../state-manager/src/TranscriptionManager.ts
|
|
10662
|
+
var import_noya_utils12 = require("@noya-app/noya-utils");
|
|
10663
|
+
var import_observable18 = require("@noya-app/observable");
|
|
10664
|
+
|
|
10665
|
+
// ../state-manager/src/UserManager.ts
|
|
10666
|
+
var import_observable20 = require("@noya-app/observable");
|
|
10667
|
+
|
|
10668
|
+
// ../state-manager/src/sync/clientId.ts
|
|
10669
|
+
var import_noya_utils14 = require("@noya-app/noya-utils");
|
|
10670
|
+
var import_observable19 = require("@noya-app/observable");
|
|
10671
|
+
|
|
10672
|
+
// ../state-manager/src/sync/defaultNames.ts
|
|
10673
|
+
var import_noya_utils13 = require("@noya-app/noya-utils");
|
|
10674
|
+
var animals = [
|
|
10675
|
+
"cat",
|
|
10676
|
+
"dog",
|
|
10677
|
+
"owl",
|
|
10678
|
+
"fish",
|
|
10679
|
+
"horse",
|
|
10680
|
+
"rabbit",
|
|
10681
|
+
"snake",
|
|
10682
|
+
"lion",
|
|
10683
|
+
"bear",
|
|
10684
|
+
"wolf",
|
|
10685
|
+
"fox",
|
|
10686
|
+
"elephant",
|
|
10687
|
+
"giraffe",
|
|
10688
|
+
"zebra",
|
|
10689
|
+
"panda",
|
|
10690
|
+
"monkey",
|
|
10691
|
+
"penguin",
|
|
10692
|
+
"koala",
|
|
10693
|
+
"kangaroo",
|
|
10694
|
+
"whale",
|
|
10695
|
+
"shark",
|
|
10696
|
+
"turtle",
|
|
10697
|
+
"crocodile",
|
|
10698
|
+
"hippo"
|
|
10699
|
+
];
|
|
10700
|
+
var adjectives = [
|
|
10701
|
+
"happy",
|
|
10702
|
+
"sleepy",
|
|
10703
|
+
"hungry",
|
|
10704
|
+
"thirsty",
|
|
10705
|
+
"healthy",
|
|
10706
|
+
"rich",
|
|
10707
|
+
"funky",
|
|
10708
|
+
"cool",
|
|
10709
|
+
"awesome",
|
|
10710
|
+
"amazing",
|
|
10711
|
+
"fantastic",
|
|
10712
|
+
"incredible",
|
|
10713
|
+
"super",
|
|
10714
|
+
"mega",
|
|
10715
|
+
"ultra"
|
|
10716
|
+
];
|
|
10717
|
+
function randomElement(array) {
|
|
10718
|
+
return array[Math.floor(Math.random() * array.length)];
|
|
10719
|
+
}
|
|
10720
|
+
function getClientImageUrl(animal) {
|
|
10721
|
+
return `https://avatars.noya.site/animals/animals_${animal}.svg`;
|
|
10722
|
+
}
|
|
10723
|
+
function randomClientIdentity() {
|
|
10724
|
+
const animal = randomElement(animals);
|
|
10725
|
+
const name = `${(0, import_noya_utils13.upperFirst)(randomElement(adjectives))} ${(0, import_noya_utils13.upperFirst)(animal)}`;
|
|
10726
|
+
return {
|
|
10727
|
+
name,
|
|
10728
|
+
animal,
|
|
10729
|
+
image: getClientImageUrl(animal)
|
|
10730
|
+
};
|
|
10731
|
+
}
|
|
10732
|
+
function getClientAnimalFromName(name) {
|
|
10733
|
+
const parts = name.trim().split(/\s+/);
|
|
10734
|
+
const possibleAnimal = parts[parts.length - 1]?.toLowerCase();
|
|
10735
|
+
if (!possibleAnimal) return void 0;
|
|
10736
|
+
return animals.includes(possibleAnimal) ? possibleAnimal : void 0;
|
|
10737
|
+
}
|
|
10738
|
+
|
|
10739
|
+
// ../state-manager/src/sync/clientId.ts
|
|
10740
|
+
var CLIENT_ID_STORAGE_KEY = "noya-client-id";
|
|
10741
|
+
var CLIENT_NAME_STORAGE_KEY = "noya-client-name";
|
|
10742
|
+
var CLIENT_IMAGE_STORAGE_KEY = "noya-client-image";
|
|
10743
|
+
var clientId$ = new import_observable19.Observable(void 0);
|
|
10744
|
+
var clientName$ = new import_observable19.Observable(void 0);
|
|
10745
|
+
var clientImage$ = new import_observable19.Observable(void 0);
|
|
10746
|
+
var safeGetItem = (key) => {
|
|
10747
|
+
try {
|
|
10748
|
+
return typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
|
|
10749
|
+
} catch {
|
|
10750
|
+
return null;
|
|
10751
|
+
}
|
|
10752
|
+
};
|
|
10753
|
+
var safeSetItem = (key, value) => {
|
|
10754
|
+
try {
|
|
10755
|
+
if (typeof localStorage !== "undefined") {
|
|
10756
|
+
localStorage.setItem(key, value);
|
|
10757
|
+
}
|
|
10758
|
+
} catch {
|
|
10759
|
+
}
|
|
10760
|
+
};
|
|
10761
|
+
if (typeof window !== "undefined") {
|
|
10762
|
+
const storedClientId = safeGetItem(CLIENT_ID_STORAGE_KEY);
|
|
10763
|
+
if (storedClientId) {
|
|
10764
|
+
clientId$.set(storedClientId);
|
|
10765
|
+
} else {
|
|
10766
|
+
const newClientId = (0, import_noya_utils14.uuid)();
|
|
10767
|
+
safeSetItem(CLIENT_ID_STORAGE_KEY, newClientId);
|
|
10768
|
+
clientId$.set(newClientId);
|
|
10769
|
+
}
|
|
10770
|
+
let storedClientName = safeGetItem(CLIENT_NAME_STORAGE_KEY) ?? void 0;
|
|
10771
|
+
let storedClientImage = safeGetItem(CLIENT_IMAGE_STORAGE_KEY) ?? void 0;
|
|
10772
|
+
const newIdentity = randomClientIdentity();
|
|
10773
|
+
if (!storedClientName) {
|
|
10774
|
+
storedClientName = newIdentity.name;
|
|
10775
|
+
safeSetItem(CLIENT_NAME_STORAGE_KEY, storedClientName);
|
|
10776
|
+
}
|
|
10777
|
+
if (!storedClientImage) {
|
|
10778
|
+
const animal = (storedClientName && getClientAnimalFromName(storedClientName)) ?? newIdentity.animal;
|
|
10779
|
+
if (animal) {
|
|
10780
|
+
storedClientImage = getClientImageUrl(animal);
|
|
10781
|
+
safeSetItem(CLIENT_IMAGE_STORAGE_KEY, storedClientImage);
|
|
10782
|
+
}
|
|
10783
|
+
}
|
|
10784
|
+
clientName$.set(storedClientName);
|
|
10785
|
+
clientImage$.set(storedClientImage);
|
|
10786
|
+
}
|
|
10787
|
+
|
|
10788
|
+
// ../state-manager/src/sync/syncUtils.ts
|
|
10789
|
+
var import_noya_utils15 = require("@noya-app/noya-utils");
|
|
7656
10790
|
|
|
7657
10791
|
// ../state-manager/src/sync/localRpcHelpers.ts
|
|
7658
|
-
var
|
|
10792
|
+
var import_noya_utils16 = require("@noya-app/noya-utils");
|
|
10793
|
+
|
|
10794
|
+
// ../state-manager/src/sync/localStorageSync.ts
|
|
10795
|
+
var import_noya_utils18 = require("@noya-app/noya-utils");
|
|
10796
|
+
|
|
10797
|
+
// ../state-manager/src/serverScripts.ts
|
|
10798
|
+
var import_noya_utils17 = require("@noya-app/noya-utils");
|
|
7659
10799
|
|
|
7660
10800
|
// ../noya-keymap/src/hooks.ts
|
|
7661
10801
|
var import_react4 = require("react");
|
|
@@ -7767,11 +10907,21 @@ var MenuItemTree = (0, import_tree_visit3.defineTree)((node) => {
|
|
|
7767
10907
|
return node.type === "submenu" ? node.items : [];
|
|
7768
10908
|
});
|
|
7769
10909
|
|
|
10910
|
+
// ../state-manager/src/NoyaManager.ts
|
|
10911
|
+
var createMutatorParametersSchema = Type.Object({
|
|
10912
|
+
sourceCode: Type.String({
|
|
10913
|
+
description: "The source code of the mutator function."
|
|
10914
|
+
}),
|
|
10915
|
+
message: Type.String({
|
|
10916
|
+
description: `A message that summarizes the changes made to the document state.`
|
|
10917
|
+
})
|
|
10918
|
+
});
|
|
10919
|
+
|
|
7770
10920
|
// ../noya-multiplayer-react/src/ai.ts
|
|
7771
|
-
var
|
|
10921
|
+
var import_react61 = require("react");
|
|
7772
10922
|
|
|
7773
10923
|
// ../noya-multiplayer-react/src/NoyaStateContext.tsx
|
|
7774
|
-
var
|
|
10924
|
+
var import_observable22 = require("@noya-app/observable");
|
|
7775
10925
|
|
|
7776
10926
|
// ../noya-react-utils/src/components/AutoSizer.tsx
|
|
7777
10927
|
var React2 = __toESM(require("react"));
|
|
@@ -7953,7 +11103,7 @@ var FileDropTarget = memoGeneric(function FileDropTarget2({ children, onDropFile
|
|
|
7953
11103
|
var import_react8 = require("react");
|
|
7954
11104
|
|
|
7955
11105
|
// ../noya-react-utils/src/hooks/useDeepArray.ts
|
|
7956
|
-
var
|
|
11106
|
+
var import_noya_utils20 = require("@noya-app/noya-utils");
|
|
7957
11107
|
var import_react9 = require("react");
|
|
7958
11108
|
function useJsonMemo(value) {
|
|
7959
11109
|
const stringified = (0, import_react9.useMemo)(
|
|
@@ -7968,7 +11118,7 @@ function useJsonMemo(value) {
|
|
|
7968
11118
|
}
|
|
7969
11119
|
|
|
7970
11120
|
// ../noya-react-utils/src/hooks/useDeepState.ts
|
|
7971
|
-
var
|
|
11121
|
+
var import_noya_utils21 = require("@noya-app/noya-utils");
|
|
7972
11122
|
var import_react10 = require("react");
|
|
7973
11123
|
|
|
7974
11124
|
// ../noya-react-utils/src/hooks/useFetch.ts
|
|
@@ -7999,7 +11149,7 @@ var import_react17 = require("react");
|
|
|
7999
11149
|
var import_react18 = require("react");
|
|
8000
11150
|
|
|
8001
11151
|
// ../noya-react-utils/src/hooks/useShallowArray.ts
|
|
8002
|
-
var
|
|
11152
|
+
var import_noya_utils22 = require("@noya-app/noya-utils");
|
|
8003
11153
|
var import_react19 = require("react");
|
|
8004
11154
|
|
|
8005
11155
|
// ../noya-react-utils/src/hooks/useStableCallback.ts
|
|
@@ -8009,7 +11159,7 @@ var import_react20 = require("react");
|
|
|
8009
11159
|
var import_react21 = require("react");
|
|
8010
11160
|
|
|
8011
11161
|
// ../noya-react-utils/src/hooks/useUrlHashParameters.ts
|
|
8012
|
-
var
|
|
11162
|
+
var import_noya_utils23 = require("@noya-app/noya-utils");
|
|
8013
11163
|
var import_react22 = require("react");
|
|
8014
11164
|
|
|
8015
11165
|
// ../noya-react-utils/src/hooks/useWindowSize.ts
|
|
@@ -8072,13 +11222,13 @@ function downloadBlob(...params) {
|
|
|
8072
11222
|
}
|
|
8073
11223
|
|
|
8074
11224
|
// ../noya-multiplayer-react/src/NoyaStateContext.tsx
|
|
8075
|
-
var
|
|
11225
|
+
var import_react60 = __toESM(require("react"));
|
|
8076
11226
|
|
|
8077
11227
|
// ../noya-multiplayer-react/src/noyaApp.ts
|
|
8078
|
-
var
|
|
11228
|
+
var import_react58 = require("react");
|
|
8079
11229
|
|
|
8080
11230
|
// ../noya-multiplayer-react/src/hooks.ts
|
|
8081
|
-
var
|
|
11231
|
+
var import_react57 = require("react");
|
|
8082
11232
|
var import_client2 = require("react-dom/client");
|
|
8083
11233
|
|
|
8084
11234
|
// ../noya-multiplayer-react/src/components/ErrorOverlay.tsx
|
|
@@ -8156,12 +11306,12 @@ var ErrorOverlay = React6.memo(function ErrorOverlay2({
|
|
|
8156
11306
|
});
|
|
8157
11307
|
|
|
8158
11308
|
// ../noya-multiplayer-react/src/inspector/useStateInspector.tsx
|
|
8159
|
-
var
|
|
11309
|
+
var import_react56 = __toESM(require("react"));
|
|
8160
11310
|
var import_client = require("react-dom/client");
|
|
8161
11311
|
|
|
8162
11312
|
// ../noya-multiplayer-react/src/inspector/StateInspector.tsx
|
|
8163
|
-
var
|
|
8164
|
-
var
|
|
11313
|
+
var import_noya_utils24 = require("@noya-app/noya-utils");
|
|
11314
|
+
var import_react55 = __toESM(require("react"));
|
|
8165
11315
|
|
|
8166
11316
|
// ../../node_modules/react-inspector/dist/index.mjs
|
|
8167
11317
|
var import_react24 = __toESM(require("react"), 1);
|
|
@@ -9564,14 +12714,15 @@ function StateInspectorRow({
|
|
|
9564
12714
|
colorScheme,
|
|
9565
12715
|
selected,
|
|
9566
12716
|
style: style2,
|
|
9567
|
-
variant
|
|
12717
|
+
variant,
|
|
12718
|
+
bordered = true
|
|
9568
12719
|
}) {
|
|
9569
12720
|
const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
9570
12721
|
return /* @__PURE__ */ import_react46.default.createElement(
|
|
9571
12722
|
"div",
|
|
9572
12723
|
{
|
|
9573
12724
|
style: {
|
|
9574
|
-
borderBottom: `1px solid ${solidBorderColor}
|
|
12725
|
+
borderBottom: bordered ? `1px solid ${solidBorderColor}` : void 0,
|
|
9575
12726
|
fontSize: "12px",
|
|
9576
12727
|
fontFamily: "Menlo, monospace",
|
|
9577
12728
|
padding: "2px 12px 1px",
|
|
@@ -10014,6 +13165,105 @@ function HistorySection({
|
|
|
10014
13165
|
);
|
|
10015
13166
|
}
|
|
10016
13167
|
|
|
13168
|
+
// ../noya-multiplayer-react/src/inspector/sections/ServerScriptLogsSection.tsx
|
|
13169
|
+
var import_react51 = __toESM(require("react"));
|
|
13170
|
+
var levelColors = {
|
|
13171
|
+
error: "#f87171",
|
|
13172
|
+
warn: "#facc15",
|
|
13173
|
+
log: "#9ca3af"
|
|
13174
|
+
};
|
|
13175
|
+
function formatTimestamp(timestamp) {
|
|
13176
|
+
return new Date(timestamp).toLocaleTimeString();
|
|
13177
|
+
}
|
|
13178
|
+
function ServerScriptLogsSection({
|
|
13179
|
+
showLogs,
|
|
13180
|
+
setShowLogs,
|
|
13181
|
+
colorScheme,
|
|
13182
|
+
logs,
|
|
13183
|
+
containerRef,
|
|
13184
|
+
paused,
|
|
13185
|
+
onTogglePaused
|
|
13186
|
+
}) {
|
|
13187
|
+
const theme3 = getStateInspectorTheme(colorScheme);
|
|
13188
|
+
return /* @__PURE__ */ import_react51.default.createElement(
|
|
13189
|
+
StateInspectorDisclosureSection,
|
|
13190
|
+
{
|
|
13191
|
+
open: showLogs,
|
|
13192
|
+
setOpen: setShowLogs,
|
|
13193
|
+
title: "Server Script Logs",
|
|
13194
|
+
colorScheme,
|
|
13195
|
+
right: /* @__PURE__ */ import_react51.default.createElement(StateInspectorButton, { theme: theme3, onClick: onTogglePaused }, paused ? "Resume" : "Pause")
|
|
13196
|
+
},
|
|
13197
|
+
/* @__PURE__ */ import_react51.default.createElement(StateInspectorDisclosureRowInner, { ref: containerRef }, paused && /* @__PURE__ */ import_react51.default.createElement(
|
|
13198
|
+
"div",
|
|
13199
|
+
{
|
|
13200
|
+
style: {
|
|
13201
|
+
padding: "4px 12px",
|
|
13202
|
+
fontSize: "11px",
|
|
13203
|
+
opacity: 0.7
|
|
13204
|
+
}
|
|
13205
|
+
},
|
|
13206
|
+
"Log streaming paused"
|
|
13207
|
+
), logs.map((log) => /* @__PURE__ */ import_react51.default.createElement(StateInspectorRow, { key: log.id, colorScheme }, /* @__PURE__ */ import_react51.default.createElement(
|
|
13208
|
+
"div",
|
|
13209
|
+
{
|
|
13210
|
+
style: {
|
|
13211
|
+
display: "flex",
|
|
13212
|
+
gap: "6px",
|
|
13213
|
+
alignItems: "center",
|
|
13214
|
+
fontSize: "10px",
|
|
13215
|
+
color: "inherit",
|
|
13216
|
+
marginBottom: log.values.length ? "4px" : 0,
|
|
13217
|
+
textTransform: "uppercase"
|
|
13218
|
+
}
|
|
13219
|
+
},
|
|
13220
|
+
/* @__PURE__ */ import_react51.default.createElement("span", null, formatTimestamp(log.timestamp)),
|
|
13221
|
+
/* @__PURE__ */ import_react51.default.createElement("span", { style: { color: levelColors[log.level] } }, log.level),
|
|
13222
|
+
/* @__PURE__ */ import_react51.default.createElement(
|
|
13223
|
+
"span",
|
|
13224
|
+
{
|
|
13225
|
+
style: {
|
|
13226
|
+
fontFamily: "monospace",
|
|
13227
|
+
textTransform: "none",
|
|
13228
|
+
fontSize: "10px"
|
|
13229
|
+
}
|
|
13230
|
+
},
|
|
13231
|
+
log.scriptId
|
|
13232
|
+
)
|
|
13233
|
+
), /* @__PURE__ */ import_react51.default.createElement(
|
|
13234
|
+
"div",
|
|
13235
|
+
{
|
|
13236
|
+
style: {
|
|
13237
|
+
display: "flex",
|
|
13238
|
+
flexDirection: "column",
|
|
13239
|
+
gap: "4px"
|
|
13240
|
+
}
|
|
13241
|
+
},
|
|
13242
|
+
log.values.length > 0 ? log.values.map((value, index) => /* @__PURE__ */ import_react51.default.createElement(
|
|
13243
|
+
themedObjectInspector,
|
|
13244
|
+
{
|
|
13245
|
+
key: index,
|
|
13246
|
+
data: value,
|
|
13247
|
+
theme: theme3,
|
|
13248
|
+
expandLevel: 3
|
|
13249
|
+
}
|
|
13250
|
+
)) : /* @__PURE__ */ import_react51.default.createElement("span", { style: { fontSize: "11px", opacity: 0.7 } }, "No data")
|
|
13251
|
+
))), !logs?.length && /* @__PURE__ */ import_react51.default.createElement(
|
|
13252
|
+
"div",
|
|
13253
|
+
{
|
|
13254
|
+
style: {
|
|
13255
|
+
padding: "12px",
|
|
13256
|
+
fontSize: "12px",
|
|
13257
|
+
display: "flex",
|
|
13258
|
+
flexDirection: "column",
|
|
13259
|
+
gap: "4px"
|
|
13260
|
+
}
|
|
13261
|
+
},
|
|
13262
|
+
/* @__PURE__ */ import_react51.default.createElement("span", null, "No logs received")
|
|
13263
|
+
))
|
|
13264
|
+
);
|
|
13265
|
+
}
|
|
13266
|
+
|
|
10017
13267
|
// ../noya-multiplayer-react/src/inspector/zip/crc32.ts
|
|
10018
13268
|
var CRC_TABLE = (() => {
|
|
10019
13269
|
const t = new Uint32Array(256);
|
|
@@ -10538,15 +13788,15 @@ function decodeAll(buffer) {
|
|
|
10538
13788
|
}
|
|
10539
13789
|
|
|
10540
13790
|
// ../noya-multiplayer-react/src/inspector/StateInspectorTitleLabel.tsx
|
|
10541
|
-
var
|
|
13791
|
+
var import_react52 = __toESM(require("react"));
|
|
10542
13792
|
function StateInspectorTitleLabel({
|
|
10543
13793
|
children
|
|
10544
13794
|
}) {
|
|
10545
|
-
return /* @__PURE__ */
|
|
13795
|
+
return /* @__PURE__ */ import_react52.default.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
|
|
10546
13796
|
}
|
|
10547
13797
|
|
|
10548
13798
|
// ../noya-multiplayer-react/src/inspector/StateInspectorToggleButton.tsx
|
|
10549
|
-
var
|
|
13799
|
+
var import_react53 = __toESM(require("react"));
|
|
10550
13800
|
function StateInspectorToggleButton({
|
|
10551
13801
|
showInspector,
|
|
10552
13802
|
setShowInspector,
|
|
@@ -10554,7 +13804,7 @@ function StateInspectorToggleButton({
|
|
|
10554
13804
|
anchor
|
|
10555
13805
|
}) {
|
|
10556
13806
|
const isRightAnchor = anchor === "right";
|
|
10557
|
-
const rightIcon = /* @__PURE__ */
|
|
13807
|
+
const rightIcon = /* @__PURE__ */ import_react53.default.createElement(
|
|
10558
13808
|
"svg",
|
|
10559
13809
|
{
|
|
10560
13810
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -10564,7 +13814,7 @@ function StateInspectorToggleButton({
|
|
|
10564
13814
|
stroke: "currentColor",
|
|
10565
13815
|
className: "size-6"
|
|
10566
13816
|
},
|
|
10567
|
-
/* @__PURE__ */
|
|
13817
|
+
/* @__PURE__ */ import_react53.default.createElement(
|
|
10568
13818
|
"path",
|
|
10569
13819
|
{
|
|
10570
13820
|
strokeLinecap: "round",
|
|
@@ -10573,7 +13823,7 @@ function StateInspectorToggleButton({
|
|
|
10573
13823
|
}
|
|
10574
13824
|
)
|
|
10575
13825
|
);
|
|
10576
|
-
const leftIcon = /* @__PURE__ */
|
|
13826
|
+
const leftIcon = /* @__PURE__ */ import_react53.default.createElement(
|
|
10577
13827
|
"svg",
|
|
10578
13828
|
{
|
|
10579
13829
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -10583,7 +13833,7 @@ function StateInspectorToggleButton({
|
|
|
10583
13833
|
stroke: "currentColor",
|
|
10584
13834
|
className: "size-6"
|
|
10585
13835
|
},
|
|
10586
|
-
/* @__PURE__ */
|
|
13836
|
+
/* @__PURE__ */ import_react53.default.createElement(
|
|
10587
13837
|
"path",
|
|
10588
13838
|
{
|
|
10589
13839
|
strokeLinecap: "round",
|
|
@@ -10592,7 +13842,7 @@ function StateInspectorToggleButton({
|
|
|
10592
13842
|
}
|
|
10593
13843
|
)
|
|
10594
13844
|
);
|
|
10595
|
-
return /* @__PURE__ */
|
|
13845
|
+
return /* @__PURE__ */ import_react53.default.createElement(
|
|
10596
13846
|
"span",
|
|
10597
13847
|
{
|
|
10598
13848
|
role: "button",
|
|
@@ -10613,15 +13863,15 @@ function StateInspectorToggleButton({
|
|
|
10613
13863
|
setShowInspector(!showInspector);
|
|
10614
13864
|
}
|
|
10615
13865
|
},
|
|
10616
|
-
showInspector ? "Hide Inspector" : /* @__PURE__ */
|
|
13866
|
+
showInspector ? "Hide Inspector" : /* @__PURE__ */ import_react53.default.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
|
|
10617
13867
|
);
|
|
10618
13868
|
}
|
|
10619
13869
|
|
|
10620
13870
|
// ../noya-multiplayer-react/src/inspector/useLocalStorageState.tsx
|
|
10621
|
-
var
|
|
13871
|
+
var import_react54 = __toESM(require("react"));
|
|
10622
13872
|
var localStorage2 = typeof window !== "undefined" ? window.localStorage : null;
|
|
10623
13873
|
function useLocalStorageState(key, defaultValue) {
|
|
10624
|
-
const [state, setState] =
|
|
13874
|
+
const [state, setState] = import_react54.default.useState(() => {
|
|
10625
13875
|
const value = localStorage2?.getItem(key);
|
|
10626
13876
|
let result = defaultValue;
|
|
10627
13877
|
if (value) {
|
|
@@ -10646,29 +13896,32 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10646
13896
|
colorScheme = "light",
|
|
10647
13897
|
anchor = "right",
|
|
10648
13898
|
unstyled = false,
|
|
13899
|
+
advanced = false,
|
|
10649
13900
|
...props
|
|
10650
13901
|
}) {
|
|
10651
13902
|
const {
|
|
10652
13903
|
multiplayerStateManager,
|
|
10653
13904
|
assetManager,
|
|
10654
|
-
|
|
13905
|
+
userManager,
|
|
10655
13906
|
secretManager,
|
|
10656
|
-
|
|
13907
|
+
sharedConnectionDataManager,
|
|
10657
13908
|
connectionEventManager,
|
|
10658
13909
|
taskManager,
|
|
10659
13910
|
ioManager,
|
|
10660
13911
|
resourceManager,
|
|
10661
|
-
activityEventsManager
|
|
13912
|
+
activityEventsManager,
|
|
13913
|
+
logManager
|
|
10662
13914
|
} = noyaManager;
|
|
10663
|
-
const [didMount, setDidMount] =
|
|
13915
|
+
const [didMount, setDidMount] = import_react55.default.useState(false);
|
|
10664
13916
|
const tasks = useObservable2(taskManager.tasks$);
|
|
10665
13917
|
const inputs = useObservable2(ioManager.inputs$);
|
|
10666
13918
|
const outputTransforms = useObservable2(ioManager.outputTransforms$);
|
|
10667
|
-
(0,
|
|
13919
|
+
(0, import_react55.useLayoutEffect)(() => {
|
|
10668
13920
|
setDidMount(true);
|
|
10669
13921
|
}, []);
|
|
10670
|
-
const eventsContainerRef =
|
|
10671
|
-
const activityEventsContainerRef =
|
|
13922
|
+
const eventsContainerRef = import_react55.default.useRef(null);
|
|
13923
|
+
const activityEventsContainerRef = import_react55.default.useRef(null);
|
|
13924
|
+
const serverLogsContainerRef = import_react55.default.useRef(null);
|
|
10672
13925
|
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
10673
13926
|
"noya-multiplayer-react-show-inspector",
|
|
10674
13927
|
true
|
|
@@ -10693,8 +13946,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10693
13946
|
"noya-multiplayer-react-show-tasks",
|
|
10694
13947
|
false
|
|
10695
13948
|
);
|
|
10696
|
-
const [
|
|
10697
|
-
"noya-multiplayer-react-show-
|
|
13949
|
+
const [showShared, setShowShared] = useLocalStorageState(
|
|
13950
|
+
"noya-multiplayer-react-show-shared",
|
|
10698
13951
|
false
|
|
10699
13952
|
);
|
|
10700
13953
|
const [showAssets, setShowAssets] = useLocalStorageState(
|
|
@@ -10721,16 +13974,43 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10721
13974
|
"noya-multiplayer-react-show-activity-events",
|
|
10722
13975
|
false
|
|
10723
13976
|
);
|
|
13977
|
+
const [showServerLogs, setShowServerLogs] = useLocalStorageState(
|
|
13978
|
+
"noya-multiplayer-react-show-server-logs",
|
|
13979
|
+
false
|
|
13980
|
+
);
|
|
10724
13981
|
const connectionEvents = useObservable2(connectionEventManager.events$);
|
|
10725
|
-
(0,
|
|
13982
|
+
(0, import_react55.useEffect)(() => {
|
|
10726
13983
|
if (eventsContainerRef.current) {
|
|
10727
13984
|
eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
|
|
10728
13985
|
}
|
|
10729
13986
|
}, [connectionEvents]);
|
|
13987
|
+
const serverLogs = useObservable2(logManager.logs$);
|
|
13988
|
+
const [serverLogsPaused, setServerLogsPaused] = import_react55.default.useState(false);
|
|
13989
|
+
const [visibleServerLogs, setVisibleServerLogs] = import_react55.default.useState(
|
|
13990
|
+
serverLogs ?? []
|
|
13991
|
+
);
|
|
13992
|
+
const toggleServerLogsPaused = (0, import_react55.useCallback)(() => {
|
|
13993
|
+
setServerLogsPaused((value) => {
|
|
13994
|
+
if (!value) {
|
|
13995
|
+
setVisibleServerLogs(serverLogs ?? []);
|
|
13996
|
+
}
|
|
13997
|
+
return !value;
|
|
13998
|
+
});
|
|
13999
|
+
}, [serverLogs]);
|
|
14000
|
+
(0, import_react55.useEffect)(() => {
|
|
14001
|
+
if (serverLogsPaused) return;
|
|
14002
|
+
setVisibleServerLogs(serverLogs ?? []);
|
|
14003
|
+
}, [serverLogs, serverLogsPaused]);
|
|
14004
|
+
(0, import_react55.useEffect)(() => {
|
|
14005
|
+
if (!showServerLogs) return;
|
|
14006
|
+
if (serverLogsContainerRef.current) {
|
|
14007
|
+
serverLogsContainerRef.current.scrollTop = serverLogsContainerRef.current.scrollHeight;
|
|
14008
|
+
}
|
|
14009
|
+
}, [showServerLogs, visibleServerLogs]);
|
|
10730
14010
|
const multipeerStateInitialized = useObservable2(
|
|
10731
14011
|
multiplayerStateManager.isInitialized$
|
|
10732
14012
|
);
|
|
10733
|
-
const
|
|
14013
|
+
const shared = useObservable2(sharedConnectionDataManager.data$);
|
|
10734
14014
|
const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
|
|
10735
14015
|
const assets = useObservable2(assetManager.assets$);
|
|
10736
14016
|
const resources = useObservable2(resourceManager.resources$);
|
|
@@ -10738,8 +14018,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10738
14018
|
const assetsInitialized = useObservable2(assetManager.isInitialized$);
|
|
10739
14019
|
const secrets = useObservable2(secretManager.secrets$);
|
|
10740
14020
|
const secretsInitialized = useObservable2(secretManager.isInitialized$);
|
|
10741
|
-
const connectedUsers = useObservable2(
|
|
10742
|
-
const
|
|
14021
|
+
const connectedUsers = useObservable2(userManager.connectedUsers$);
|
|
14022
|
+
const connectionId = useObservable2(userManager.currentConnectionId$);
|
|
10743
14023
|
const state = useObservable2(multiplayerStateManager.optimisticState$);
|
|
10744
14024
|
const inputsInitialized = useObservable2(ioManager.inputsInitialized$);
|
|
10745
14025
|
const outputTransformsInitialized = useObservable2(
|
|
@@ -10766,11 +14046,11 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10766
14046
|
zIndex: 9999,
|
|
10767
14047
|
lineHeight: "13px"
|
|
10768
14048
|
};
|
|
10769
|
-
const handleExportAll = (0,
|
|
14049
|
+
const handleExportAll = (0, import_react55.useCallback)(async () => {
|
|
10770
14050
|
const buffer = await exportAll(noyaManager);
|
|
10771
14051
|
downloadBlob(new Blob([buffer]), "state.zip");
|
|
10772
14052
|
}, [noyaManager]);
|
|
10773
|
-
const handleImportAll = (0,
|
|
14053
|
+
const handleImportAll = (0, import_react55.useCallback)(async () => {
|
|
10774
14054
|
const file = await uploadFile();
|
|
10775
14055
|
const buffer = await file.arrayBuffer();
|
|
10776
14056
|
importAll(buffer, noyaManager, {
|
|
@@ -10783,7 +14063,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10783
14063
|
}, [noyaManager]);
|
|
10784
14064
|
if (!didMount) return null;
|
|
10785
14065
|
if (!showInspector) {
|
|
10786
|
-
return /* @__PURE__ */
|
|
14066
|
+
return /* @__PURE__ */ import_react55.default.createElement(
|
|
10787
14067
|
"div",
|
|
10788
14068
|
{
|
|
10789
14069
|
...props,
|
|
@@ -10795,7 +14075,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10795
14075
|
},
|
|
10796
14076
|
onClick: () => setShowInspector(true)
|
|
10797
14077
|
},
|
|
10798
|
-
/* @__PURE__ */
|
|
14078
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10799
14079
|
StateInspectorToggleButton,
|
|
10800
14080
|
{
|
|
10801
14081
|
showInspector,
|
|
@@ -10806,7 +14086,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10806
14086
|
)
|
|
10807
14087
|
);
|
|
10808
14088
|
}
|
|
10809
|
-
return /* @__PURE__ */
|
|
14089
|
+
return /* @__PURE__ */ import_react55.default.createElement(
|
|
10810
14090
|
"div",
|
|
10811
14091
|
{
|
|
10812
14092
|
...props,
|
|
@@ -10815,7 +14095,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10815
14095
|
...props.style
|
|
10816
14096
|
}
|
|
10817
14097
|
},
|
|
10818
|
-
/* @__PURE__ */
|
|
14098
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10819
14099
|
StateInspectorDisclosureSection,
|
|
10820
14100
|
{
|
|
10821
14101
|
isFirst: true,
|
|
@@ -10827,7 +14107,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10827
14107
|
flex: "0 0 auto",
|
|
10828
14108
|
maxHeight: "200px"
|
|
10829
14109
|
},
|
|
10830
|
-
right: /* @__PURE__ */
|
|
14110
|
+
right: /* @__PURE__ */ import_react55.default.createElement(
|
|
10831
14111
|
StateInspectorToggleButton,
|
|
10832
14112
|
{
|
|
10833
14113
|
showInspector,
|
|
@@ -10837,35 +14117,39 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10837
14117
|
}
|
|
10838
14118
|
)
|
|
10839
14119
|
},
|
|
10840
|
-
/* @__PURE__ */
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
colorScheme,
|
|
10845
|
-
variant: user.id === userId ? "up" : void 0
|
|
10846
|
-
},
|
|
10847
|
-
user.image && /* @__PURE__ */ import_react54.default.createElement(
|
|
10848
|
-
"img",
|
|
14120
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.map((user, index, array) => {
|
|
14121
|
+
const identifier = user.userId ?? user.connectionId;
|
|
14122
|
+
return /* @__PURE__ */ import_react55.default.createElement(
|
|
14123
|
+
StateInspectorRow,
|
|
10849
14124
|
{
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
14125
|
+
key: user.connectionId,
|
|
14126
|
+
colorScheme,
|
|
14127
|
+
variant: user.connectionId === connectionId ? "up" : void 0,
|
|
14128
|
+
bordered: index !== array.length - 1
|
|
14129
|
+
},
|
|
14130
|
+
user.image && /* @__PURE__ */ import_react55.default.createElement(
|
|
14131
|
+
"img",
|
|
14132
|
+
{
|
|
14133
|
+
src: user.image,
|
|
14134
|
+
alt: user.name,
|
|
14135
|
+
style: {
|
|
14136
|
+
width: "13px",
|
|
14137
|
+
height: "13px",
|
|
14138
|
+
borderRadius: "50%",
|
|
14139
|
+
marginRight: "4px",
|
|
14140
|
+
display: "inline-block",
|
|
14141
|
+
position: "relative",
|
|
14142
|
+
background: solidBorderColor,
|
|
14143
|
+
verticalAlign: "middle"
|
|
14144
|
+
}
|
|
10861
14145
|
}
|
|
10862
|
-
|
|
10863
|
-
|
|
10864
|
-
|
|
10865
|
-
|
|
10866
|
-
|
|
10867
|
-
|
|
10868
|
-
)
|
|
14146
|
+
),
|
|
14147
|
+
user.name,
|
|
14148
|
+
" (",
|
|
14149
|
+
ellipsis(identifier, 8, "middle"),
|
|
14150
|
+
")"
|
|
14151
|
+
);
|
|
14152
|
+
}), !connectedUsers && /* @__PURE__ */ import_react55.default.createElement(
|
|
10869
14153
|
"div",
|
|
10870
14154
|
{
|
|
10871
14155
|
style: {
|
|
@@ -10876,13 +14160,13 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10876
14160
|
gap: "4px"
|
|
10877
14161
|
}
|
|
10878
14162
|
},
|
|
10879
|
-
/* @__PURE__ */
|
|
14163
|
+
/* @__PURE__ */ import_react55.default.createElement("span", null, "No connected users")
|
|
10880
14164
|
))
|
|
10881
14165
|
),
|
|
10882
|
-
/* @__PURE__ */
|
|
14166
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10883
14167
|
StateInspectorDisclosureSection,
|
|
10884
14168
|
{
|
|
10885
|
-
title: /* @__PURE__ */
|
|
14169
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Data", /* @__PURE__ */ import_react55.default.createElement(
|
|
10886
14170
|
ColoredDot,
|
|
10887
14171
|
{
|
|
10888
14172
|
type: multipeerStateInitialized ? "success" : "error"
|
|
@@ -10891,7 +14175,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10891
14175
|
colorScheme,
|
|
10892
14176
|
setOpen: setShowData,
|
|
10893
14177
|
open: showData,
|
|
10894
|
-
right: /* @__PURE__ */
|
|
14178
|
+
right: /* @__PURE__ */ import_react55.default.createElement(
|
|
10895
14179
|
"span",
|
|
10896
14180
|
{
|
|
10897
14181
|
style: {
|
|
@@ -10899,9 +14183,9 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10899
14183
|
gap: "12px"
|
|
10900
14184
|
}
|
|
10901
14185
|
},
|
|
10902
|
-
/* @__PURE__ */
|
|
10903
|
-
/* @__PURE__ */
|
|
10904
|
-
/* @__PURE__ */
|
|
14186
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorButton, { theme: theme3, onClick: handleImportAll }, "Import"),
|
|
14187
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorButton, { theme: theme3, onClick: handleExportAll }, "Export"),
|
|
14188
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10905
14189
|
StateInspectorButton,
|
|
10906
14190
|
{
|
|
10907
14191
|
theme: theme3,
|
|
@@ -10913,14 +14197,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10913
14197
|
)
|
|
10914
14198
|
)
|
|
10915
14199
|
},
|
|
10916
|
-
/* @__PURE__ */
|
|
14200
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ import_react55.default.createElement(
|
|
10917
14201
|
themedObjectInspector,
|
|
10918
14202
|
{
|
|
10919
14203
|
name: multiplayerStateManager.schema ? "state" : void 0,
|
|
10920
14204
|
data: state,
|
|
10921
14205
|
theme: theme3
|
|
10922
14206
|
}
|
|
10923
|
-
)), multiplayerStateManager.schema && /* @__PURE__ */
|
|
14207
|
+
)), multiplayerStateManager.schema && /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ import_react55.default.createElement(
|
|
10924
14208
|
themedObjectInspector,
|
|
10925
14209
|
{
|
|
10926
14210
|
name: "schema",
|
|
@@ -10929,7 +14213,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10929
14213
|
}
|
|
10930
14214
|
)))
|
|
10931
14215
|
),
|
|
10932
|
-
/* @__PURE__ */
|
|
14216
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10933
14217
|
HistorySection,
|
|
10934
14218
|
{
|
|
10935
14219
|
showHistory,
|
|
@@ -10939,14 +14223,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10939
14223
|
multiplayerStateManager
|
|
10940
14224
|
}
|
|
10941
14225
|
),
|
|
10942
|
-
/* @__PURE__ */
|
|
14226
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
10943
14227
|
StateInspectorDisclosureSection,
|
|
10944
14228
|
{
|
|
10945
14229
|
open: showAssets,
|
|
10946
14230
|
setOpen: setShowAssets,
|
|
10947
|
-
title: /* @__PURE__ */
|
|
14231
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ import_react55.default.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
|
|
10948
14232
|
colorScheme,
|
|
10949
|
-
right: /* @__PURE__ */
|
|
14233
|
+
right: /* @__PURE__ */ import_react55.default.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ import_react55.default.createElement(
|
|
10950
14234
|
StateInspectorButton,
|
|
10951
14235
|
{
|
|
10952
14236
|
theme: theme3,
|
|
@@ -10961,7 +14245,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10961
14245
|
}
|
|
10962
14246
|
},
|
|
10963
14247
|
"Delete all"
|
|
10964
|
-
), /* @__PURE__ */
|
|
14248
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
10965
14249
|
StateInspectorButton,
|
|
10966
14250
|
{
|
|
10967
14251
|
theme: theme3,
|
|
@@ -10974,7 +14258,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10974
14258
|
}
|
|
10975
14259
|
},
|
|
10976
14260
|
"Reload"
|
|
10977
|
-
), /* @__PURE__ */
|
|
14261
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
10978
14262
|
StateInspectorButton,
|
|
10979
14263
|
{
|
|
10980
14264
|
theme: theme3,
|
|
@@ -10998,14 +14282,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
10998
14282
|
"Upload"
|
|
10999
14283
|
))
|
|
11000
14284
|
},
|
|
11001
|
-
/* @__PURE__ */
|
|
14285
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(
|
|
11002
14286
|
themedObjectInspector,
|
|
11003
14287
|
{
|
|
11004
14288
|
name: asset.id,
|
|
11005
14289
|
data: truncateAsset(asset),
|
|
11006
14290
|
theme: theme3
|
|
11007
14291
|
}
|
|
11008
|
-
), /* @__PURE__ */
|
|
14292
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
11009
14293
|
StateInspectorButton,
|
|
11010
14294
|
{
|
|
11011
14295
|
theme: theme3,
|
|
@@ -11014,14 +14298,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11014
14298
|
"Delete"
|
|
11015
14299
|
))))
|
|
11016
14300
|
),
|
|
11017
|
-
/* @__PURE__ */
|
|
14301
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11018
14302
|
StateInspectorDisclosureSection,
|
|
11019
14303
|
{
|
|
11020
|
-
title: /* @__PURE__ */
|
|
14304
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Resources (", resources.length, ")", /* @__PURE__ */ import_react55.default.createElement(ColoredDot, { type: resourcesInitialized ? "success" : "error" })),
|
|
11021
14305
|
colorScheme,
|
|
11022
14306
|
open: showResources,
|
|
11023
14307
|
setOpen: setShowResources,
|
|
11024
|
-
right: /* @__PURE__ */
|
|
14308
|
+
right: /* @__PURE__ */ import_react55.default.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ import_react55.default.createElement(
|
|
11025
14309
|
StateInspectorButton,
|
|
11026
14310
|
{
|
|
11027
14311
|
theme: theme3,
|
|
@@ -11036,12 +14320,12 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11036
14320
|
}
|
|
11037
14321
|
},
|
|
11038
14322
|
"Delete all"
|
|
11039
|
-
), /* @__PURE__ */
|
|
14323
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
11040
14324
|
StateInspectorButton,
|
|
11041
14325
|
{
|
|
11042
14326
|
theme: theme3,
|
|
11043
14327
|
onClick: async () => {
|
|
11044
|
-
const path2 = prompt("Enter directory path") || (0,
|
|
14328
|
+
const path2 = prompt("Enter directory path") || (0, import_noya_utils24.uuid)();
|
|
11045
14329
|
await resourceManager.createResource({
|
|
11046
14330
|
type: "directory",
|
|
11047
14331
|
path: path2
|
|
@@ -11049,7 +14333,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11049
14333
|
}
|
|
11050
14334
|
},
|
|
11051
14335
|
"Create Directory"
|
|
11052
|
-
), /* @__PURE__ */
|
|
14336
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
11053
14337
|
StateInspectorButton,
|
|
11054
14338
|
{
|
|
11055
14339
|
theme: theme3,
|
|
@@ -11057,9 +14341,9 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11057
14341
|
const file = await uploadFile();
|
|
11058
14342
|
resourceManager.createResource({
|
|
11059
14343
|
type: "asset",
|
|
11060
|
-
path: file.name || (0,
|
|
14344
|
+
path: file.name || (0, import_noya_utils24.uuid)(),
|
|
11061
14345
|
asset: {
|
|
11062
|
-
content:
|
|
14346
|
+
content: import_noya_utils24.Base64.encode(await file.arrayBuffer()),
|
|
11063
14347
|
contentType: file.type,
|
|
11064
14348
|
encoding: "base64"
|
|
11065
14349
|
}
|
|
@@ -11069,21 +14353,21 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11069
14353
|
"Create Asset"
|
|
11070
14354
|
))
|
|
11071
14355
|
},
|
|
11072
|
-
/* @__PURE__ */
|
|
14356
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, resources?.map((resource) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key: resource.id, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(
|
|
11073
14357
|
themedObjectInspector,
|
|
11074
14358
|
{
|
|
11075
14359
|
name: resource.path,
|
|
11076
14360
|
data: resource,
|
|
11077
14361
|
theme: theme3
|
|
11078
14362
|
}
|
|
11079
|
-
), /* @__PURE__ */
|
|
14363
|
+
), /* @__PURE__ */ import_react55.default.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ import_react55.default.createElement(
|
|
11080
14364
|
StateInspectorButton,
|
|
11081
14365
|
{
|
|
11082
14366
|
theme: theme3,
|
|
11083
14367
|
onClick: () => resourceManager.deleteResource({ id: resource.id })
|
|
11084
14368
|
},
|
|
11085
14369
|
"Delete"
|
|
11086
|
-
), /* @__PURE__ */
|
|
14370
|
+
), /* @__PURE__ */ import_react55.default.createElement(
|
|
11087
14371
|
StateInspectorButton,
|
|
11088
14372
|
{
|
|
11089
14373
|
theme: theme3,
|
|
@@ -11096,14 +14380,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11096
14380
|
"Rename"
|
|
11097
14381
|
)))))
|
|
11098
14382
|
),
|
|
11099
|
-
/* @__PURE__ */
|
|
14383
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11100
14384
|
StateInspectorDisclosureSection,
|
|
11101
14385
|
{
|
|
11102
|
-
title: /* @__PURE__ */
|
|
14386
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Secrets", /* @__PURE__ */ import_react55.default.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
|
|
11103
14387
|
colorScheme,
|
|
11104
14388
|
open: showSecrets,
|
|
11105
14389
|
setOpen: setShowSecrets,
|
|
11106
|
-
right: /* @__PURE__ */
|
|
14390
|
+
right: /* @__PURE__ */ import_react55.default.createElement(
|
|
11107
14391
|
StateInspectorButton,
|
|
11108
14392
|
{
|
|
11109
14393
|
theme: theme3,
|
|
@@ -11118,7 +14402,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11118
14402
|
"Create"
|
|
11119
14403
|
)
|
|
11120
14404
|
},
|
|
11121
|
-
/* @__PURE__ */
|
|
14405
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(themedObjectInspector, { data: secret, theme: theme3 }), /* @__PURE__ */ import_react55.default.createElement(
|
|
11122
14406
|
StateInspectorButton,
|
|
11123
14407
|
{
|
|
11124
14408
|
theme: theme3,
|
|
@@ -11127,16 +14411,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11127
14411
|
"Delete"
|
|
11128
14412
|
))))
|
|
11129
14413
|
),
|
|
11130
|
-
|
|
11131
|
-
/* @__PURE__ */ import_react54.default.createElement(
|
|
14414
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11132
14415
|
StateInspectorDisclosureSection,
|
|
11133
14416
|
{
|
|
11134
14417
|
open: showInputs,
|
|
11135
14418
|
setOpen: setShowInputs,
|
|
11136
|
-
title: /* @__PURE__ */
|
|
14419
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Inputs", /* @__PURE__ */ import_react55.default.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
|
|
11137
14420
|
colorScheme
|
|
11138
14421
|
},
|
|
11139
|
-
/* @__PURE__ */
|
|
14422
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(themedObjectInspector, { data: input, theme: theme3 }))), !inputs?.length && /* @__PURE__ */ import_react55.default.createElement(
|
|
11140
14423
|
"div",
|
|
11141
14424
|
{
|
|
11142
14425
|
style: {
|
|
@@ -11147,15 +14430,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11147
14430
|
gap: "4px"
|
|
11148
14431
|
}
|
|
11149
14432
|
},
|
|
11150
|
-
/* @__PURE__ */
|
|
14433
|
+
/* @__PURE__ */ import_react55.default.createElement("span", null, "No inputs")
|
|
11151
14434
|
))
|
|
11152
14435
|
),
|
|
11153
|
-
/* @__PURE__ */
|
|
14436
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11154
14437
|
StateInspectorDisclosureSection,
|
|
11155
14438
|
{
|
|
11156
14439
|
open: showOutputTransforms,
|
|
11157
14440
|
setOpen: setShowOutputTransforms,
|
|
11158
|
-
title: /* @__PURE__ */
|
|
14441
|
+
title: /* @__PURE__ */ import_react55.default.createElement(StateInspectorTitleLabel, null, "Output Transforms", /* @__PURE__ */ import_react55.default.createElement(
|
|
11159
14442
|
ColoredDot,
|
|
11160
14443
|
{
|
|
11161
14444
|
type: outputTransformsInitialized ? "success" : "error"
|
|
@@ -11163,7 +14446,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11163
14446
|
)),
|
|
11164
14447
|
colorScheme
|
|
11165
14448
|
},
|
|
11166
|
-
/* @__PURE__ */
|
|
14449
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(themedObjectInspector, { data: transform, theme: theme3 }))), !outputTransforms?.length && /* @__PURE__ */ import_react55.default.createElement(
|
|
11167
14450
|
"div",
|
|
11168
14451
|
{
|
|
11169
14452
|
style: {
|
|
@@ -11174,10 +14457,10 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11174
14457
|
gap: "4px"
|
|
11175
14458
|
}
|
|
11176
14459
|
},
|
|
11177
|
-
/* @__PURE__ */
|
|
14460
|
+
/* @__PURE__ */ import_react55.default.createElement("span", null, "No output transforms")
|
|
11178
14461
|
))
|
|
11179
14462
|
),
|
|
11180
|
-
/* @__PURE__ */
|
|
14463
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11181
14464
|
StateInspectorDisclosureSection,
|
|
11182
14465
|
{
|
|
11183
14466
|
title: "Tasks",
|
|
@@ -11185,7 +14468,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11185
14468
|
open: showTasks,
|
|
11186
14469
|
setOpen: setShowTasks
|
|
11187
14470
|
},
|
|
11188
|
-
/* @__PURE__ */
|
|
14471
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ import_react55.default.createElement(
|
|
11189
14472
|
StateInspectorRow,
|
|
11190
14473
|
{
|
|
11191
14474
|
key: task.id,
|
|
@@ -11194,7 +14477,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11194
14477
|
backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
|
|
11195
14478
|
}
|
|
11196
14479
|
},
|
|
11197
|
-
/* @__PURE__ */
|
|
14480
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
11198
14481
|
themedObjectInspector,
|
|
11199
14482
|
{
|
|
11200
14483
|
name: task.name,
|
|
@@ -11204,15 +14487,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11204
14487
|
)
|
|
11205
14488
|
)))
|
|
11206
14489
|
),
|
|
11207
|
-
/* @__PURE__ */
|
|
14490
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
11208
14491
|
StateInspectorDisclosureSection,
|
|
11209
14492
|
{
|
|
11210
|
-
open:
|
|
11211
|
-
setOpen:
|
|
11212
|
-
title: "
|
|
14493
|
+
open: showShared,
|
|
14494
|
+
setOpen: setShowShared,
|
|
14495
|
+
title: "Shared Connection Data",
|
|
11213
14496
|
colorScheme
|
|
11214
14497
|
},
|
|
11215
|
-
/* @__PURE__ */
|
|
14498
|
+
/* @__PURE__ */ import_react55.default.createElement(StateInspectorDisclosureRowInner, null, Object.entries(shared).map(([key, value]) => /* @__PURE__ */ import_react55.default.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ import_react55.default.createElement(
|
|
11216
14499
|
themedObjectInspector,
|
|
11217
14500
|
{
|
|
11218
14501
|
name: key,
|
|
@@ -11222,7 +14505,19 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11222
14505
|
}
|
|
11223
14506
|
))))
|
|
11224
14507
|
),
|
|
11225
|
-
/* @__PURE__ */
|
|
14508
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
14509
|
+
ServerScriptLogsSection,
|
|
14510
|
+
{
|
|
14511
|
+
colorScheme,
|
|
14512
|
+
showLogs: showServerLogs,
|
|
14513
|
+
setShowLogs: setShowServerLogs,
|
|
14514
|
+
logs: visibleServerLogs,
|
|
14515
|
+
paused: serverLogsPaused,
|
|
14516
|
+
onTogglePaused: toggleServerLogsPaused,
|
|
14517
|
+
containerRef: serverLogsContainerRef
|
|
14518
|
+
}
|
|
14519
|
+
),
|
|
14520
|
+
advanced && /* @__PURE__ */ import_react55.default.createElement(
|
|
11226
14521
|
ActivityEventsSection,
|
|
11227
14522
|
{
|
|
11228
14523
|
colorScheme,
|
|
@@ -11232,7 +14527,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11232
14527
|
activityEventsManager
|
|
11233
14528
|
}
|
|
11234
14529
|
),
|
|
11235
|
-
/* @__PURE__ */
|
|
14530
|
+
/* @__PURE__ */ import_react55.default.createElement(
|
|
11236
14531
|
EventsSection,
|
|
11237
14532
|
{
|
|
11238
14533
|
connectionEvents,
|
|
@@ -11244,7 +14539,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
11244
14539
|
)
|
|
11245
14540
|
);
|
|
11246
14541
|
});
|
|
11247
|
-
var truncateAsset = (0,
|
|
14542
|
+
var truncateAsset = (0, import_noya_utils24.memoize)((asset) => {
|
|
11248
14543
|
if (asset.url.startsWith("data:") || asset.url.startsWith("blob:")) {
|
|
11249
14544
|
return { ...asset, url: ellipsis(asset.url, 40) };
|
|
11250
14545
|
}
|
|
@@ -11253,7 +14548,7 @@ var truncateAsset = (0, import_noya_utils17.memoize)((asset) => {
|
|
|
11253
14548
|
|
|
11254
14549
|
// ../noya-multiplayer-react/src/hooks.ts
|
|
11255
14550
|
function useManagedHistory(stateManager) {
|
|
11256
|
-
return (0,
|
|
14551
|
+
return (0, import_react57.useSyncExternalStore)(
|
|
11257
14552
|
stateManager.historyEmittor.addListener,
|
|
11258
14553
|
stateManager.getHistorySnapshot,
|
|
11259
14554
|
stateManager.getHistorySnapshot
|
|
@@ -11261,15 +14556,15 @@ function useManagedHistory(stateManager) {
|
|
|
11261
14556
|
}
|
|
11262
14557
|
|
|
11263
14558
|
// ../noya-multiplayer-react/src/singleton.tsx
|
|
11264
|
-
var
|
|
14559
|
+
var import_react59 = __toESM(require("react"));
|
|
11265
14560
|
|
|
11266
14561
|
// ../noya-multiplayer-react/src/NoyaStateContext.tsx
|
|
11267
|
-
var AnyNoyaStateContext = (0,
|
|
14562
|
+
var AnyNoyaStateContext = (0, import_react60.createContext)(void 0);
|
|
11268
14563
|
var emptyArray = [];
|
|
11269
14564
|
function useActivityEventsForManager(streamFilter, activityEventsManager) {
|
|
11270
|
-
const [streamId, setStreamId] = (0,
|
|
14565
|
+
const [streamId, setStreamId] = (0, import_react60.useState)(void 0);
|
|
11271
14566
|
const stableStreamFilter = useJsonMemo(streamFilter);
|
|
11272
|
-
(0,
|
|
14567
|
+
(0, import_react60.useEffect)(() => {
|
|
11273
14568
|
if (!stableStreamFilter) return;
|
|
11274
14569
|
const streamId2 = activityEventsManager.subscribe(stableStreamFilter);
|
|
11275
14570
|
setStreamId(streamId2);
|
|
@@ -11283,29 +14578,29 @@ function useActivityEventsForManager(streamFilter, activityEventsManager) {
|
|
|
11283
14578
|
}
|
|
11284
14579
|
|
|
11285
14580
|
// ../noya-multiplayer-react/src/components/UserPointersOverlay.tsx
|
|
11286
|
-
var
|
|
11287
|
-
var
|
|
14581
|
+
var import_observable23 = require("@noya-app/observable");
|
|
14582
|
+
var import_react62 = __toESM(require("react"));
|
|
11288
14583
|
function shouldShow(hideAfter, updatedAt) {
|
|
11289
14584
|
return !!updatedAt && Date.now() - updatedAt < hideAfter;
|
|
11290
14585
|
}
|
|
11291
14586
|
var UserPointerInternal = memoGeneric(function UserPointerInternal2({
|
|
11292
14587
|
user,
|
|
11293
|
-
|
|
14588
|
+
sharedConnectionDataManager,
|
|
11294
14589
|
hideAfter = 5e3,
|
|
11295
14590
|
renderUserPointer
|
|
11296
14591
|
}) {
|
|
11297
|
-
const observable = (0,
|
|
11298
|
-
const metadata$ =
|
|
11299
|
-
const data$ =
|
|
11300
|
-
return
|
|
14592
|
+
const observable = (0, import_react62.useMemo)(() => {
|
|
14593
|
+
const metadata$ = sharedConnectionDataManager.metadata$.observePath([user.connectionId]).throttle(50);
|
|
14594
|
+
const data$ = sharedConnectionDataManager.data$.observePath([user.connectionId]).throttle(50);
|
|
14595
|
+
return import_observable23.Observable.combine([metadata$, data$], ([metadata2, data2]) => {
|
|
11301
14596
|
return { metadata: metadata2, data: data2 };
|
|
11302
14597
|
});
|
|
11303
|
-
}, [
|
|
14598
|
+
}, [sharedConnectionDataManager, user.connectionId]);
|
|
11304
14599
|
const { metadata, data } = useObservable2(observable);
|
|
11305
|
-
const [, setForceUpdate] = (0,
|
|
14600
|
+
const [, setForceUpdate] = (0, import_react62.useState)(0);
|
|
11306
14601
|
const updatedAt = metadata?.updatedAt ?? 0;
|
|
11307
14602
|
const show = shouldShow(hideAfter, updatedAt);
|
|
11308
|
-
(0,
|
|
14603
|
+
(0, import_react62.useEffect)(() => {
|
|
11309
14604
|
if (!show) return;
|
|
11310
14605
|
const timeoutId = setTimeout(() => {
|
|
11311
14606
|
setForceUpdate((prev) => prev + 1);
|
|
@@ -11314,27 +14609,29 @@ var UserPointerInternal = memoGeneric(function UserPointerInternal2({
|
|
|
11314
14609
|
}, [hideAfter, show, updatedAt]);
|
|
11315
14610
|
if (!data?.pointer) return null;
|
|
11316
14611
|
return renderUserPointer({
|
|
11317
|
-
userId: user.
|
|
14612
|
+
userId: user.connectionId,
|
|
11318
14613
|
name: user.name,
|
|
11319
14614
|
point: data.pointer,
|
|
11320
14615
|
visible: show
|
|
11321
14616
|
});
|
|
11322
14617
|
});
|
|
11323
14618
|
var UserPointersOverlay = memoGeneric(function UserPointers({
|
|
11324
|
-
|
|
11325
|
-
|
|
14619
|
+
userManager,
|
|
14620
|
+
sharedConnectionDataManager,
|
|
11326
14621
|
renderUserPointer
|
|
11327
14622
|
}) {
|
|
11328
|
-
const
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
14623
|
+
const currentConnectionId = useObservable2(
|
|
14624
|
+
sharedConnectionDataManager.currentConnectionId$
|
|
14625
|
+
);
|
|
14626
|
+
const connectedUsers = useObservable2(userManager.connectedUsers$);
|
|
14627
|
+
return /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, connectedUsers.map((user) => {
|
|
14628
|
+
if (user.connectionId === currentConnectionId) return null;
|
|
14629
|
+
return /* @__PURE__ */ import_react62.default.createElement(
|
|
11333
14630
|
UserPointerInternal,
|
|
11334
14631
|
{
|
|
11335
|
-
key: user.
|
|
14632
|
+
key: user.connectionId,
|
|
11336
14633
|
user,
|
|
11337
|
-
|
|
14634
|
+
sharedConnectionDataManager,
|
|
11338
14635
|
renderUserPointer
|
|
11339
14636
|
}
|
|
11340
14637
|
);
|
|
@@ -11343,15 +14640,15 @@ var UserPointersOverlay = memoGeneric(function UserPointers({
|
|
|
11343
14640
|
|
|
11344
14641
|
// src/react/tableHooks.ts
|
|
11345
14642
|
var import_observable_store = require("@noya-app/observable-store");
|
|
11346
|
-
var
|
|
14643
|
+
var import_react63 = require("react");
|
|
11347
14644
|
function useTable(table, {
|
|
11348
14645
|
where,
|
|
11349
14646
|
select
|
|
11350
14647
|
}, options = {}) {
|
|
11351
|
-
const stableSelect = (0,
|
|
14648
|
+
const stableSelect = (0, import_react63.useMemo)(() => {
|
|
11352
14649
|
return JSON.stringify(select);
|
|
11353
14650
|
}, [select]);
|
|
11354
|
-
const stableWhere = (0,
|
|
14651
|
+
const stableWhere = (0, import_react63.useMemo)(() => {
|
|
11355
14652
|
let cloneWithNoUndefined = {};
|
|
11356
14653
|
for (const [key, value] of Object.entries(where ?? {})) {
|
|
11357
14654
|
if (value !== void 0) {
|
|
@@ -11360,7 +14657,7 @@ function useTable(table, {
|
|
|
11360
14657
|
}
|
|
11361
14658
|
return JSON.stringify(cloneWithNoUndefined);
|
|
11362
14659
|
}, [where]);
|
|
11363
|
-
const observable = (0,
|
|
14660
|
+
const observable = (0, import_react63.useMemo)(() => {
|
|
11364
14661
|
const parsedSelect = JSON.parse(stableSelect);
|
|
11365
14662
|
const parsedWhere = JSON.parse(stableWhere);
|
|
11366
14663
|
if (!table) {
|
|
@@ -11387,18 +14684,18 @@ function useTable(table, {
|
|
|
11387
14684
|
}
|
|
11388
14685
|
);
|
|
11389
14686
|
}, [stableSelect, stableWhere, table, options.policy, options.debug]);
|
|
11390
|
-
(0,
|
|
14687
|
+
(0, import_react63.useEffect)(() => {
|
|
11391
14688
|
observable.start?.();
|
|
11392
14689
|
}, [observable]);
|
|
11393
14690
|
const { status, data } = useObservable2(observable);
|
|
11394
|
-
const optimisticUpdate = (0,
|
|
14691
|
+
const optimisticUpdate = (0, import_react63.useCallback)(
|
|
11395
14692
|
(entity, config) => {
|
|
11396
14693
|
if (!table) return;
|
|
11397
14694
|
table.optimisticUpdate(entity, config);
|
|
11398
14695
|
},
|
|
11399
14696
|
[table]
|
|
11400
14697
|
);
|
|
11401
|
-
return (0,
|
|
14698
|
+
return (0, import_react63.useMemo)(() => {
|
|
11402
14699
|
return {
|
|
11403
14700
|
status,
|
|
11404
14701
|
data,
|
|
@@ -11428,7 +14725,7 @@ function useFileListItem(id, select, options = {}) {
|
|
|
11428
14725
|
{ where: { id: id ?? null }, select },
|
|
11429
14726
|
options
|
|
11430
14727
|
);
|
|
11431
|
-
return (0,
|
|
14728
|
+
return (0, import_react63.useMemo)(() => {
|
|
11432
14729
|
return {
|
|
11433
14730
|
data: data.at(0),
|
|
11434
14731
|
status,
|
|
@@ -11458,7 +14755,7 @@ function useUser(id, select, options = {}) {
|
|
|
11458
14755
|
{ select, where: { id: id ?? null } },
|
|
11459
14756
|
options
|
|
11460
14757
|
);
|
|
11461
|
-
return (0,
|
|
14758
|
+
return (0, import_react63.useMemo)(() => {
|
|
11462
14759
|
return {
|
|
11463
14760
|
status,
|
|
11464
14761
|
data: data.at(0),
|