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