@lotics/app-sdk 0.115.1 → 0.115.3
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/dist/index.js +300 -122
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -716,19 +716,12 @@ function setKey(key, answer) {
|
|
|
716
716
|
// src/written.ts
|
|
717
717
|
import { useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
718
718
|
|
|
719
|
-
// ../shared/src/add_operator.ts
|
|
720
|
-
function addOrConcat(left, right, addNumbers) {
|
|
721
|
-
if (typeof left === "string" || typeof right === "string") {
|
|
722
|
-
return String(left ?? "") + String(right ?? "");
|
|
723
|
-
}
|
|
724
|
-
return addNumbers();
|
|
725
|
-
}
|
|
726
|
-
|
|
727
719
|
// ../shared/src/expression_limits.ts
|
|
728
720
|
var MAX_RESULT_LENGTH = 1e5;
|
|
729
721
|
var MAX_STRING_LENGTH = 1e7;
|
|
730
722
|
var MAX_RANDOM_LENGTH = 1e3;
|
|
731
723
|
var MAX_RUN_BUILT_BYTES = 512 * 1024 * 1024;
|
|
724
|
+
var MAX_IN_PLACE_BYTES = 1024 * 1024;
|
|
732
725
|
var MAX_PERSISTED_JSON_LENGTH = 64 * 1024 * 1024;
|
|
733
726
|
var ExpressionLimitError = class extends Error {
|
|
734
727
|
constructor(message2) {
|
|
@@ -808,21 +801,54 @@ function escapedLength(text2) {
|
|
|
808
801
|
function isLowSurrogate(code) {
|
|
809
802
|
return code >= 56320 && code <= 57343;
|
|
810
803
|
}
|
|
804
|
+
function textOf(value) {
|
|
805
|
+
if (!Array.isArray(value)) return ownText(value);
|
|
806
|
+
const parts = [];
|
|
807
|
+
walkJoined(value, (text2) => {
|
|
808
|
+
parts.push(text2);
|
|
809
|
+
return true;
|
|
810
|
+
});
|
|
811
|
+
return parts.join("");
|
|
812
|
+
}
|
|
811
813
|
function textLengthUpTo(value, max3) {
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
let length2 = Math.max(0, value.length - 1);
|
|
819
|
-
for (let index = 0; index < value.length && length2 <= max3; index++) {
|
|
820
|
-
const element = value[index];
|
|
821
|
-
if (element != null) length2 += textLength(element, max3 - length2, joining);
|
|
822
|
-
}
|
|
823
|
-
joining.delete(value);
|
|
814
|
+
if (!Array.isArray(value)) return ownText(value).length;
|
|
815
|
+
let length2 = 0;
|
|
816
|
+
walkJoined(value, (text2) => {
|
|
817
|
+
length2 += text2.length;
|
|
818
|
+
return length2 <= max3;
|
|
819
|
+
});
|
|
824
820
|
return length2;
|
|
825
821
|
}
|
|
822
|
+
function ownText(value) {
|
|
823
|
+
if (typeof value === "string") return value;
|
|
824
|
+
if (value instanceof Date) return Date.prototype.toString.call(value);
|
|
825
|
+
if (typeof value === "object" && value !== null) return Object.prototype.toString.call(value);
|
|
826
|
+
return String(value);
|
|
827
|
+
}
|
|
828
|
+
function walkJoined(array2, write2) {
|
|
829
|
+
const joining = /* @__PURE__ */ new Set([array2]);
|
|
830
|
+
const stack = [{ array: array2, at: 0 }];
|
|
831
|
+
while (stack.length > 0) {
|
|
832
|
+
const frame2 = stack[stack.length - 1];
|
|
833
|
+
if (frame2.at >= frame2.array.length) {
|
|
834
|
+
joining.delete(frame2.array);
|
|
835
|
+
stack.pop();
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
if (frame2.at > 0 && !write2(",")) return;
|
|
839
|
+
const element = frame2.array[frame2.at];
|
|
840
|
+
frame2.at += 1;
|
|
841
|
+
if (element === null || element === void 0) continue;
|
|
842
|
+
if (Array.isArray(element)) {
|
|
843
|
+
if (!joining.has(element)) {
|
|
844
|
+
joining.add(element);
|
|
845
|
+
stack.push({ array: element, at: 0 });
|
|
846
|
+
}
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
if (!write2(ownText(element))) return;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
826
852
|
function jsonPreview(value, max3) {
|
|
827
853
|
if (typeof value === "string") {
|
|
828
854
|
const text2 = JSON.stringify(value.slice(0, max3));
|
|
@@ -832,6 +858,14 @@ function jsonPreview(value, max3) {
|
|
|
832
858
|
return Array.isArray(value) ? `[\u2026 ${value.length} items]` : "{\u2026}";
|
|
833
859
|
}
|
|
834
860
|
|
|
861
|
+
// ../shared/src/add_operator.ts
|
|
862
|
+
function addOrConcat(left, right, addNumbers) {
|
|
863
|
+
if (typeof left === "string" || typeof right === "string") {
|
|
864
|
+
return textOf(left ?? "") + textOf(right ?? "");
|
|
865
|
+
}
|
|
866
|
+
return addNumbers();
|
|
867
|
+
}
|
|
868
|
+
|
|
835
869
|
// ../../node_modules/jexpr/lib/constants.js
|
|
836
870
|
var KEYWORDS = ["this"];
|
|
837
871
|
var UNARY_OPERATORS = ["+", "-", "!"];
|
|
@@ -1691,6 +1725,16 @@ __export(expression_array_exports, {
|
|
|
1691
1725
|
unique: () => unique,
|
|
1692
1726
|
uniqueBy: () => uniqueBy
|
|
1693
1727
|
});
|
|
1728
|
+
|
|
1729
|
+
// ../shared/src/own_property.ts
|
|
1730
|
+
function ownMember(value, key) {
|
|
1731
|
+
return Object.hasOwn(value, key) ? Reflect.get(value, key) : void 0;
|
|
1732
|
+
}
|
|
1733
|
+
function defineOwn(target, key, value) {
|
|
1734
|
+
Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
// ../shared/src/expression_array.ts
|
|
1694
1738
|
function getField(obj, field) {
|
|
1695
1739
|
if (obj == null) return void 0;
|
|
1696
1740
|
const parts = field.split(".");
|
|
@@ -1698,10 +1742,17 @@ function getField(obj, field) {
|
|
|
1698
1742
|
for (const part of parts) {
|
|
1699
1743
|
if (value == null) return void 0;
|
|
1700
1744
|
if (typeof value !== "object") return void 0;
|
|
1701
|
-
value = value
|
|
1745
|
+
value = ownMember(value, part);
|
|
1702
1746
|
}
|
|
1703
1747
|
return value;
|
|
1704
1748
|
}
|
|
1749
|
+
function countInto(result, key) {
|
|
1750
|
+
defineOwn(result, key, (Object.hasOwn(result, key) ? result[key] : 0) + 1);
|
|
1751
|
+
}
|
|
1752
|
+
function groupInto(result, key, item) {
|
|
1753
|
+
if (Object.hasOwn(result, key)) result[key].push(item);
|
|
1754
|
+
else defineOwn(result, key, [item]);
|
|
1755
|
+
}
|
|
1705
1756
|
function compareValues(a, b) {
|
|
1706
1757
|
if (a == null && b == null) return 0;
|
|
1707
1758
|
if (a == null) return 1;
|
|
@@ -1863,7 +1914,7 @@ function countBy(arr, fieldOrCb) {
|
|
|
1863
1914
|
const result2 = {};
|
|
1864
1915
|
for (const val of keys2) {
|
|
1865
1916
|
const key = val == null ? "null" : String(val);
|
|
1866
|
-
result2
|
|
1917
|
+
countInto(result2, key);
|
|
1867
1918
|
}
|
|
1868
1919
|
return result2;
|
|
1869
1920
|
});
|
|
@@ -1876,7 +1927,7 @@ function countBy(arr, fieldOrCb) {
|
|
|
1876
1927
|
for (const item of arr) {
|
|
1877
1928
|
const val = getField(item, field);
|
|
1878
1929
|
const key = val == null ? "null" : String(val);
|
|
1879
|
-
result
|
|
1930
|
+
countInto(result, key);
|
|
1880
1931
|
}
|
|
1881
1932
|
return result;
|
|
1882
1933
|
}
|
|
@@ -1996,7 +2047,7 @@ function groupBy(arr, fieldOrCb) {
|
|
|
1996
2047
|
const result2 = {};
|
|
1997
2048
|
for (let i = 0; i < arr.length; i++) {
|
|
1998
2049
|
const key = keys2[i] == null ? "null" : String(keys2[i]);
|
|
1999
|
-
(result2
|
|
2050
|
+
groupInto(result2, key, arr[i]);
|
|
2000
2051
|
}
|
|
2001
2052
|
return result2;
|
|
2002
2053
|
});
|
|
@@ -2009,10 +2060,7 @@ function groupBy(arr, fieldOrCb) {
|
|
|
2009
2060
|
for (const item of arr) {
|
|
2010
2061
|
const val = getField(item, field);
|
|
2011
2062
|
const key = val == null ? "null" : String(val);
|
|
2012
|
-
|
|
2013
|
-
result[key] = [];
|
|
2014
|
-
}
|
|
2015
|
-
result[key].push(item);
|
|
2063
|
+
groupInto(result, key, item);
|
|
2016
2064
|
}
|
|
2017
2065
|
return result;
|
|
2018
2066
|
}
|
|
@@ -2946,7 +2994,7 @@ function getNestedValue(obj, path) {
|
|
|
2946
2994
|
for (const part of parts) {
|
|
2947
2995
|
if (value == null) return void 0;
|
|
2948
2996
|
if (typeof value !== "object") return void 0;
|
|
2949
|
-
value = value
|
|
2997
|
+
value = ownMember(value, part);
|
|
2950
2998
|
}
|
|
2951
2999
|
return value;
|
|
2952
3000
|
}
|
|
@@ -3002,9 +3050,7 @@ function pick(obj, fields) {
|
|
|
3002
3050
|
const objRecord = obj;
|
|
3003
3051
|
for (const field of fields) {
|
|
3004
3052
|
const fieldStr = String(field);
|
|
3005
|
-
if (fieldStr
|
|
3006
|
-
result[fieldStr] = objRecord[fieldStr];
|
|
3007
|
-
}
|
|
3053
|
+
if (Object.hasOwn(objRecord, fieldStr)) defineOwn(result, fieldStr, objRecord[fieldStr]);
|
|
3008
3054
|
}
|
|
3009
3055
|
return result;
|
|
3010
3056
|
}
|
|
@@ -3022,10 +3068,8 @@ function omit(obj, fields) {
|
|
|
3022
3068
|
const result = {};
|
|
3023
3069
|
const objRecord = obj;
|
|
3024
3070
|
const fieldsSet = new Set(fields.map(String));
|
|
3025
|
-
for (const key
|
|
3026
|
-
if (!fieldsSet.has(key))
|
|
3027
|
-
result[key] = objRecord[key];
|
|
3028
|
-
}
|
|
3071
|
+
for (const key of Object.keys(objRecord)) {
|
|
3072
|
+
if (!fieldsSet.has(key)) defineOwn(result, key, objRecord[key]);
|
|
3029
3073
|
}
|
|
3030
3074
|
return result;
|
|
3031
3075
|
}
|
|
@@ -3153,7 +3197,7 @@ function toString(val) {
|
|
|
3153
3197
|
if (typeof val !== "string" && textLengthUpTo(val, MAX_STRING_LENGTH) > MAX_STRING_LENGTH) {
|
|
3154
3198
|
throw new ExpressionLimitError(`toString: result too long (max ${MAX_STRING_LENGTH} characters)`);
|
|
3155
3199
|
}
|
|
3156
|
-
return
|
|
3200
|
+
return textOf(val);
|
|
3157
3201
|
}
|
|
3158
3202
|
function isNull(val) {
|
|
3159
3203
|
return val === null || val === void 0;
|
|
@@ -21918,20 +21962,31 @@ function sameReading(a, b) {
|
|
|
21918
21962
|
function readingWords(reading) {
|
|
21919
21963
|
return reading === "link" ? "a link" : JSON.stringify(reading);
|
|
21920
21964
|
}
|
|
21921
|
-
function
|
|
21922
|
-
|
|
21923
|
-
|
|
21924
|
-
|
|
21925
|
-
if (
|
|
21926
|
-
const changed2 =
|
|
21927
|
-
return
|
|
21928
|
-
}
|
|
21929
|
-
function
|
|
21930
|
-
const {
|
|
21931
|
-
if (
|
|
21932
|
-
const
|
|
21965
|
+
function heldReading(stored) {
|
|
21966
|
+
return stored.byKeys ?? stored.stated;
|
|
21967
|
+
}
|
|
21968
|
+
function leftReading(written, stored) {
|
|
21969
|
+
if (stored === void 0) return { changed: written.stated, left: written.stated };
|
|
21970
|
+
const changed2 = sameReading(written.stated, stored.stated) ? void 0 : written.stated;
|
|
21971
|
+
return { changed: changed2, left: changed2 ?? heldReading(stored) ?? written.stated };
|
|
21972
|
+
}
|
|
21973
|
+
function keysRefusal(written, stored) {
|
|
21974
|
+
const { byKeys } = written;
|
|
21975
|
+
if (byKeys === void 0 || stored !== void 0 && sameReading(byKeys, stored.byKeys)) return void 0;
|
|
21976
|
+
const { changed: changed2, left } = leftReading(written, stored);
|
|
21977
|
+
if (sameReading(byKeys, left ?? DECIMAL)) return void 0;
|
|
21933
21978
|
const keys2 = KEYS_BEFORE_NOTATION.flatMap((name) => written.keys[name] ? [`${name} ${JSON.stringify(written.keys[name])}`] : []);
|
|
21934
|
-
|
|
21979
|
+
if (changed2 !== void 0) {
|
|
21980
|
+
const key = changed2 === "link" ? "link" : "notation";
|
|
21981
|
+
return `"${key}" says ${readingWords(changed2)} and ${keys2.join(", ")} ${keys2.length === 1 ? "says" : "say"} ${readingWords(byKeys)}, and the keys before "notation" are no longer read \u2014 state "${key}" alone`;
|
|
21982
|
+
}
|
|
21983
|
+
const state = byKeys === "link" ? '"link": true' : `"notation": ${JSON.stringify(byKeys)}`;
|
|
21984
|
+
return `${keys2.join(", ")} ${keys2.length === 1 ? "is" : "are"} no longer read \u2014 state ${state}`;
|
|
21985
|
+
}
|
|
21986
|
+
function settledReading(written, stored) {
|
|
21987
|
+
const refused = keysRefusal(written, stored);
|
|
21988
|
+
if (refused !== void 0) return { refusal: refused };
|
|
21989
|
+
return checkedReading(leftReading(written, stored).left ?? written.byKeys, stored === void 0 ? void 0 : heldReading(stored));
|
|
21935
21990
|
}
|
|
21936
21991
|
function checkedReading(reading, held2) {
|
|
21937
21992
|
const refused = changedCurrencyRefusal(reading, held2);
|
|
@@ -24900,7 +24955,7 @@ function figureIssue(path) {
|
|
|
24900
24955
|
for (const { key, message: message2 } of figureKeysRefusals(value)) ctx.addIssue({ code: "custom", message: message2, path: [...path, key] });
|
|
24901
24956
|
};
|
|
24902
24957
|
}
|
|
24903
|
-
var BEFORE_NOTATION = '
|
|
24958
|
+
var BEFORE_NOTATION = 'Replaced by "notation", and never read: naming another reading in it is refused.';
|
|
24904
24959
|
function notationStatedIssue(path) {
|
|
24905
24960
|
return (value, ctx) => {
|
|
24906
24961
|
if (value.notation === void 0) return;
|
|
@@ -27330,6 +27385,12 @@ var WorkflowExpressionBudgetError = class extends Error {
|
|
|
27330
27385
|
}
|
|
27331
27386
|
budget;
|
|
27332
27387
|
};
|
|
27388
|
+
var ExpressionNotCheapError = class extends Error {
|
|
27389
|
+
constructor() {
|
|
27390
|
+
super(`The expression walks or builds more than ${MAX_IN_PLACE_BYTES / 1024 / 1024}MB at once, past what an evaluation in place may.`);
|
|
27391
|
+
this.name = "ExpressionNotCheapError";
|
|
27392
|
+
}
|
|
27393
|
+
};
|
|
27333
27394
|
function budgetMessage(budget) {
|
|
27334
27395
|
switch (budget.exceeded) {
|
|
27335
27396
|
case "bytes":
|
|
@@ -27377,6 +27438,66 @@ function builtSize(value) {
|
|
|
27377
27438
|
if (typeof value === "object" && value !== null) return OBJECT_BYTES + Object.keys(value).length * SLOT_BYTES;
|
|
27378
27439
|
return 0;
|
|
27379
27440
|
}
|
|
27441
|
+
var LONGEST_NUMBER_TEXT = 24;
|
|
27442
|
+
function numberTextLength(value) {
|
|
27443
|
+
if (!Number.isSafeInteger(value)) return LONGEST_NUMBER_TEXT;
|
|
27444
|
+
let length2 = value < 0 ? 2 : 1;
|
|
27445
|
+
for (let rest = Math.abs(value); rest >= 10; rest = Math.floor(rest / 10)) length2 += 1;
|
|
27446
|
+
return length2;
|
|
27447
|
+
}
|
|
27448
|
+
function expandedSize(value, max3) {
|
|
27449
|
+
let bytes = 0;
|
|
27450
|
+
const pending = [value];
|
|
27451
|
+
while (pending.length > 0 && bytes <= max3) {
|
|
27452
|
+
const member = pending.pop();
|
|
27453
|
+
if (typeof member === "string") bytes += member.length * CHAR_BYTES;
|
|
27454
|
+
else if (typeof member === "number") bytes += numberTextLength(member) * CHAR_BYTES;
|
|
27455
|
+
else if (typeof member === "boolean") bytes += (member ? 4 : 5) * CHAR_BYTES;
|
|
27456
|
+
else if (typeof member === "bigint") bytes += String(member).length * CHAR_BYTES;
|
|
27457
|
+
else if (typeof member !== "object" || member === null) continue;
|
|
27458
|
+
else if (member instanceof Map) {
|
|
27459
|
+
bytes += OBJECT_BYTES + member.size * 2 * SLOT_BYTES;
|
|
27460
|
+
if (bytes <= max3) for (const [key, held2] of member) pending.push(key, held2);
|
|
27461
|
+
} else if (member instanceof Set) {
|
|
27462
|
+
bytes += OBJECT_BYTES + member.size * SLOT_BYTES;
|
|
27463
|
+
if (bytes <= max3) for (const held2 of member) pending.push(held2);
|
|
27464
|
+
} else if (Array.isArray(member)) {
|
|
27465
|
+
bytes += OBJECT_BYTES + member.length * SLOT_BYTES;
|
|
27466
|
+
if (bytes <= max3) for (let at2 = 0; at2 < member.length; at2++) pending.push(member[at2]);
|
|
27467
|
+
} else {
|
|
27468
|
+
const known = ownKeyBytes.get(member);
|
|
27469
|
+
if (known !== void 0 && bytes + known > max3) {
|
|
27470
|
+
bytes += known;
|
|
27471
|
+
continue;
|
|
27472
|
+
}
|
|
27473
|
+
const keys2 = Object.keys(member);
|
|
27474
|
+
let own = OBJECT_BYTES + keys2.length * SLOT_BYTES;
|
|
27475
|
+
for (const key of keys2) own += key.length * CHAR_BYTES;
|
|
27476
|
+
ownKeyBytes.set(member, own);
|
|
27477
|
+
bytes += own;
|
|
27478
|
+
if (bytes <= max3) for (const key of keys2) pending.push(Reflect.get(member, key));
|
|
27479
|
+
}
|
|
27480
|
+
}
|
|
27481
|
+
return bytes;
|
|
27482
|
+
}
|
|
27483
|
+
var ownKeyBytes = /* @__PURE__ */ new WeakMap();
|
|
27484
|
+
var OBJECT_TEXT_LENGTH = 64;
|
|
27485
|
+
function writtenSize(value, max3) {
|
|
27486
|
+
let bytes = 0;
|
|
27487
|
+
const pending = [value];
|
|
27488
|
+
while (pending.length > 0 && bytes <= max3) {
|
|
27489
|
+
const member = pending.pop();
|
|
27490
|
+
if (typeof member === "string") bytes += member.length * CHAR_BYTES;
|
|
27491
|
+
else if (typeof member === "number") bytes += numberTextLength(member) * CHAR_BYTES;
|
|
27492
|
+
else if (typeof member === "boolean") bytes += (member ? 4 : 5) * CHAR_BYTES;
|
|
27493
|
+
else if (typeof member === "bigint") bytes += String(member).length * CHAR_BYTES;
|
|
27494
|
+
else if (Array.isArray(member)) {
|
|
27495
|
+
bytes += OBJECT_BYTES + member.length * SLOT_BYTES;
|
|
27496
|
+
if (bytes <= max3) for (let at2 = 0; at2 < member.length; at2++) pending.push(member[at2]);
|
|
27497
|
+
} else if (typeof member === "object" && member !== null) bytes += OBJECT_TEXT_LENGTH * CHAR_BYTES;
|
|
27498
|
+
}
|
|
27499
|
+
return bytes;
|
|
27500
|
+
}
|
|
27380
27501
|
var PARSED_NODE_BYTES = 40;
|
|
27381
27502
|
var OPEN_BRACKET = "[".charCodeAt(0);
|
|
27382
27503
|
var OPEN_BRACE = "{".charCodeAt(0);
|
|
@@ -27390,6 +27511,22 @@ function parsedSize(text2) {
|
|
|
27390
27511
|
}
|
|
27391
27512
|
return text2.length * CHAR_BYTES + nodes * PARSED_NODE_BYTES;
|
|
27392
27513
|
}
|
|
27514
|
+
function assertCheap(budget, ...values2) {
|
|
27515
|
+
if (!budget.bounded) return;
|
|
27516
|
+
let bytes = 0;
|
|
27517
|
+
for (const value of values2) {
|
|
27518
|
+
bytes += writtenSize(value, MAX_IN_PLACE_BYTES - bytes);
|
|
27519
|
+
if (bytes > MAX_IN_PLACE_BYTES) throw new ExpressionNotCheapError();
|
|
27520
|
+
}
|
|
27521
|
+
}
|
|
27522
|
+
function charge(ctx, bytes) {
|
|
27523
|
+
const budget = ctx.evaluation_budget;
|
|
27524
|
+
assertUnsettled(budget);
|
|
27525
|
+
if (Date.now() > ctx.run_budget.deadline_ms) throw new WorkflowTimeBudgetError(ctx.run_budget.subject, ctx.run_budget.budget_ms);
|
|
27526
|
+
if (budget.bounded && budget.built + bytes > MAX_IN_PLACE_BYTES) throw new ExpressionNotCheapError();
|
|
27527
|
+
budget.built += bytes;
|
|
27528
|
+
chargeBuilt(ctx.run_budget, bytes);
|
|
27529
|
+
}
|
|
27393
27530
|
function callbackWorkers() {
|
|
27394
27531
|
let free = LINK_FETCH_CONCURRENCY - 1;
|
|
27395
27532
|
return {
|
|
@@ -27403,10 +27540,16 @@ function callbackWorkers() {
|
|
|
27403
27540
|
}
|
|
27404
27541
|
};
|
|
27405
27542
|
}
|
|
27406
|
-
function evaluateWorkflowExpression(expr2, ctx) {
|
|
27407
|
-
const budget = { workers: callbackWorkers(), settled: false };
|
|
27543
|
+
function evaluateWorkflowExpression(expr2, ctx, options = {}) {
|
|
27544
|
+
const budget = { workers: callbackWorkers(), bounded: options.bounded === true, built: 0, settled: false };
|
|
27408
27545
|
return evaluateExpression(expr2, { ...ctx, evaluation_budget: budget }).finally(() => {
|
|
27409
27546
|
budget.settled = true;
|
|
27547
|
+
}).then((answer) => {
|
|
27548
|
+
if (budget.bounded && expandedSize(answer, MAX_IN_PLACE_BYTES) > MAX_IN_PLACE_BYTES) throw new ExpressionNotCheapError();
|
|
27549
|
+
return answer;
|
|
27550
|
+
}).catch((error51) => {
|
|
27551
|
+
if (budget.bounded && ctx.run_budget.host === "shared") ctx.run_budget.built_bytes -= budget.built;
|
|
27552
|
+
throw error51;
|
|
27410
27553
|
});
|
|
27411
27554
|
}
|
|
27412
27555
|
async function evaluateExpression(expr2, ctx) {
|
|
@@ -27432,15 +27575,13 @@ async function evaluateExpression(expr2, ctx) {
|
|
|
27432
27575
|
return evaluateLambda(expr2.params, expr2.body, ctx, []);
|
|
27433
27576
|
case "array_literal": {
|
|
27434
27577
|
const elements = await Promise.all(expr2.elements.map((el) => evaluateExpression(el, ctx)));
|
|
27435
|
-
|
|
27578
|
+
charge(ctx, builtSize(elements));
|
|
27436
27579
|
return elements;
|
|
27437
27580
|
}
|
|
27438
27581
|
case "object_literal": {
|
|
27439
27582
|
const out = {};
|
|
27440
|
-
for (const entry of expr2.entries)
|
|
27441
|
-
|
|
27442
|
-
}
|
|
27443
|
-
chargeBuilt(ctx.run_budget, builtSize(out));
|
|
27583
|
+
for (const entry of expr2.entries) defineOwn(out, entry.key, await evaluateExpression(entry.value, ctx));
|
|
27584
|
+
charge(ctx, builtSize(out));
|
|
27444
27585
|
return out;
|
|
27445
27586
|
}
|
|
27446
27587
|
default:
|
|
@@ -27461,9 +27602,7 @@ function assertUnsettled(budget) {
|
|
|
27461
27602
|
function evaluateLambda(params, body, ctx, items) {
|
|
27462
27603
|
const call = async (...args) => {
|
|
27463
27604
|
const frame2 = {};
|
|
27464
|
-
for (let i = 0; i < params.length; i++)
|
|
27465
|
-
frame2[params[i]] = args[i];
|
|
27466
|
-
}
|
|
27605
|
+
for (let i = 0; i < params.length; i++) defineOwn(frame2, params[i], args[i]);
|
|
27467
27606
|
const stack = ctx.lambda_params ?? [];
|
|
27468
27607
|
const newStack = [...stack, frame2];
|
|
27469
27608
|
const innerCtx = {
|
|
@@ -27531,16 +27670,14 @@ function resolveReadRoot(source, ctx) {
|
|
|
27531
27670
|
case "foreach_index":
|
|
27532
27671
|
return resolveForeachFrame(ctx, void 0, "foreach_index").index;
|
|
27533
27672
|
case "step_output": {
|
|
27534
|
-
if (!(source.step_id
|
|
27673
|
+
if (!Object.hasOwn(ctx.step_outputs, source.step_id)) {
|
|
27535
27674
|
throw new WorkflowEvalError(
|
|
27536
27675
|
`Read from step_output "${source.step_id}", but no such step has run`,
|
|
27537
27676
|
{ kind: "read", at: "step_output", extra: { step_id: source.step_id } }
|
|
27538
27677
|
);
|
|
27539
27678
|
}
|
|
27540
27679
|
const stored = ctx.step_outputs[source.step_id];
|
|
27541
|
-
if (stored && typeof stored === "object" && "output"
|
|
27542
|
-
return stored.output;
|
|
27543
|
-
}
|
|
27680
|
+
if (stored && typeof stored === "object" && Object.hasOwn(stored, "output")) return ownMember(stored, "output");
|
|
27544
27681
|
return stored;
|
|
27545
27682
|
}
|
|
27546
27683
|
case "runtime":
|
|
@@ -27550,7 +27687,7 @@ function resolveReadRoot(source, ctx) {
|
|
|
27550
27687
|
if (stack !== void 0) {
|
|
27551
27688
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
27552
27689
|
const frame2 = stack[i];
|
|
27553
|
-
if (source.name
|
|
27690
|
+
if (Object.hasOwn(frame2, source.name)) return frame2[source.name];
|
|
27554
27691
|
}
|
|
27555
27692
|
}
|
|
27556
27693
|
throw new WorkflowEvalError(
|
|
@@ -27563,7 +27700,7 @@ function resolveReadRoot(source, ctx) {
|
|
|
27563
27700
|
if (stack !== void 0) {
|
|
27564
27701
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
27565
27702
|
const frame2 = stack[i];
|
|
27566
|
-
if (source.name
|
|
27703
|
+
if (Object.hasOwn(frame2, source.name)) return frame2[source.name];
|
|
27567
27704
|
}
|
|
27568
27705
|
}
|
|
27569
27706
|
throw new WorkflowEvalError(
|
|
@@ -27665,63 +27802,74 @@ async function coerceFieldDisplay(value, field, ctx) {
|
|
|
27665
27802
|
if (value === null || value === void 0) return value;
|
|
27666
27803
|
switch (field.type) {
|
|
27667
27804
|
case "select":
|
|
27668
|
-
return coerceSelectDisplay(value, field.options);
|
|
27805
|
+
return coerceSelectDisplay(value, field.options, ctx);
|
|
27669
27806
|
// One of its own options, named as a select's is.
|
|
27670
27807
|
case "formula":
|
|
27671
|
-
return field.formula.options === void 0 ? value : coerceSelectDisplay(value, field.formula.options);
|
|
27808
|
+
return field.formula.options === void 0 ? value : coerceSelectDisplay(value, field.formula.options, ctx);
|
|
27672
27809
|
case "select_record_link":
|
|
27673
27810
|
return coerceRecordLinkDisplay(value, field, ctx);
|
|
27674
27811
|
case "select_member":
|
|
27675
27812
|
return coerceMemberDisplay(value, ctx);
|
|
27676
27813
|
case "lookup":
|
|
27677
|
-
return field.lookup_field_options ? coerceOptionKeysDeep(value, field.lookup_field_options) : value;
|
|
27814
|
+
return field.lookup_field_options ? coerceOptionKeysDeep(value, field.lookup_field_options, ctx) : value;
|
|
27678
27815
|
default:
|
|
27679
27816
|
return value;
|
|
27680
27817
|
}
|
|
27681
27818
|
}
|
|
27682
|
-
function coerceSelectDisplay(value, options) {
|
|
27819
|
+
function coerceSelectDisplay(value, options, ctx) {
|
|
27683
27820
|
const optionMap = new Map(options.map((o) => [o.key, o.name]));
|
|
27684
27821
|
const resolve = (key) => {
|
|
27685
27822
|
if (typeof key !== "string") return "";
|
|
27686
27823
|
return optionMap.get(key) ?? key;
|
|
27687
27824
|
};
|
|
27688
|
-
if (Array.isArray(value)) return value
|
|
27689
|
-
|
|
27825
|
+
if (!Array.isArray(value)) return resolve(value);
|
|
27826
|
+
assertCheap(ctx.evaluation_budget, value);
|
|
27827
|
+
const names = value.map(resolve);
|
|
27828
|
+
charge(ctx, builtSize(names));
|
|
27829
|
+
return names;
|
|
27690
27830
|
}
|
|
27691
|
-
function coerceOptionKeysDeep(value, options) {
|
|
27831
|
+
function coerceOptionKeysDeep(value, options, ctx) {
|
|
27832
|
+
assertCheap(ctx.evaluation_budget, value);
|
|
27692
27833
|
const optionMap = new Map(options.map((o) => [o.key, o.name]));
|
|
27693
27834
|
const resolve = (v) => {
|
|
27694
|
-
if (Array.isArray(v))
|
|
27835
|
+
if (Array.isArray(v)) {
|
|
27836
|
+
const resolved = v.map(resolve);
|
|
27837
|
+
charge(ctx, builtSize(resolved));
|
|
27838
|
+
return resolved;
|
|
27839
|
+
}
|
|
27695
27840
|
if (typeof v === "string") return optionMap.get(v) ?? v;
|
|
27696
27841
|
return v;
|
|
27697
27842
|
};
|
|
27698
27843
|
return resolve(value);
|
|
27699
27844
|
}
|
|
27700
27845
|
async function coerceMemberDisplay(value, ctx) {
|
|
27846
|
+
if (Array.isArray(value)) assertCheap(ctx.evaluation_budget, value);
|
|
27701
27847
|
const ids = Array.isArray(value) ? value.filter((v) => typeof v === "string") : typeof value === "string" ? [value] : [];
|
|
27702
27848
|
if (ids.length === 0) return Array.isArray(value) ? [] : "";
|
|
27703
27849
|
const nameMap = await ctx.member_lookup(ids);
|
|
27704
27850
|
const names = new Set(nameMap.values());
|
|
27705
27851
|
const resolve = (id) => nameMap.get(id) ?? (names.has(id) ? id : "");
|
|
27706
|
-
|
|
27852
|
+
if (!Array.isArray(value)) return resolve(ids[0]);
|
|
27853
|
+
const shown = value.map((v) => resolve(textOf(v)));
|
|
27854
|
+
charge(ctx, builtSize(shown));
|
|
27855
|
+
return shown;
|
|
27707
27856
|
}
|
|
27708
27857
|
async function coerceRecordLinkDisplay(value, field, ctx) {
|
|
27709
27858
|
if (!Array.isArray(value)) return value;
|
|
27859
|
+
assertCheap(ctx.evaluation_budget, value);
|
|
27710
27860
|
const displayFieldKeys = field.display_field_keys ?? [];
|
|
27711
|
-
|
|
27712
|
-
value.map(
|
|
27713
|
-
|
|
27714
|
-
|
|
27715
|
-
|
|
27716
|
-
|
|
27717
|
-
|
|
27718
|
-
|
|
27719
|
-
|
|
27720
|
-
const v = data[key];
|
|
27721
|
-
return v === null || v === void 0 ? "" : String(v);
|
|
27722
|
-
}).filter((s) => s !== "").join(" ");
|
|
27723
|
-
})
|
|
27861
|
+
const rows = await fetchRecordsBounded(
|
|
27862
|
+
value.map((id) => typeof id === "string" ? id : null),
|
|
27863
|
+
`Showing "${field.key}"`,
|
|
27864
|
+
ctx
|
|
27865
|
+
);
|
|
27866
|
+
const shown = rows.map((row2) => row2 === null ? [] : displayFieldKeys.map((key) => row2[key]));
|
|
27867
|
+
assertCheap(ctx.evaluation_budget, shown);
|
|
27868
|
+
const texts = shown.map(
|
|
27869
|
+
(values2) => values2.filter((v) => v !== null && v !== void 0).map(textOf).filter((text2) => text2 !== "").join(" ")
|
|
27724
27870
|
);
|
|
27871
|
+
charge(ctx, texts.reduce((bytes, text2) => bytes + builtSize(text2), builtSize(texts)));
|
|
27872
|
+
return texts;
|
|
27725
27873
|
}
|
|
27726
27874
|
function advanceTable(segment, currentTable, ctx) {
|
|
27727
27875
|
if (segment.at === "linked" && currentTable) {
|
|
@@ -27751,7 +27899,7 @@ async function walkSegment(value, segment, ctx) {
|
|
|
27751
27899
|
return void 0;
|
|
27752
27900
|
}
|
|
27753
27901
|
if (typeof value !== "object") return void 0;
|
|
27754
|
-
return value
|
|
27902
|
+
return ownMember(value, segment.key);
|
|
27755
27903
|
}
|
|
27756
27904
|
case "index": {
|
|
27757
27905
|
if (value === null || value === void 0) return void 0;
|
|
@@ -27761,7 +27909,7 @@ async function walkSegment(value, segment, ctx) {
|
|
|
27761
27909
|
}
|
|
27762
27910
|
if (typeof value === "object") {
|
|
27763
27911
|
const key = typeof segment.index === "number" ? String(segment.index) : await resolveObjectKeyExpression(segment.index, ctx);
|
|
27764
|
-
return value
|
|
27912
|
+
return ownMember(value, key);
|
|
27765
27913
|
}
|
|
27766
27914
|
throw new WorkflowEvalError(
|
|
27767
27915
|
`Cannot index ${typeof value} \u2014 only an array or an object can be read by index.`,
|
|
@@ -27779,9 +27927,8 @@ async function resolveObjectKeyExpression(expr2, ctx) {
|
|
|
27779
27927
|
throw new WorkflowEvalError(
|
|
27780
27928
|
// Bounded: the value is whatever the expression produced — a whole record,
|
|
27781
27929
|
// a page of rows — and the message goes into a persisted execution row and
|
|
27782
|
-
// an author-facing error.
|
|
27783
|
-
|
|
27784
|
-
`Computed object key must evaluate to a string, got ${value === null ? "null" : typeof value}: ${jsonPreview(value, VALUE_PREVIEW_LENGTH)}`,
|
|
27930
|
+
// an author-facing error.
|
|
27931
|
+
`Computed object key must evaluate to a string, got ${describeValue(value)}`,
|
|
27785
27932
|
{ kind: "read", at: "index" }
|
|
27786
27933
|
);
|
|
27787
27934
|
}
|
|
@@ -27790,7 +27937,7 @@ async function resolveIndexExpression(expr2, ctx, context) {
|
|
|
27790
27937
|
const value = await evaluateExpression(expr2, ctx);
|
|
27791
27938
|
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
27792
27939
|
throw new WorkflowEvalError(
|
|
27793
|
-
`Computed ${context} must evaluate to a non-negative integer, got ${
|
|
27940
|
+
`Computed ${context} must evaluate to a non-negative integer, got ${describeValue(value)}`,
|
|
27794
27941
|
{ kind: "read", at: "index" }
|
|
27795
27942
|
);
|
|
27796
27943
|
}
|
|
@@ -27804,17 +27951,17 @@ async function walkLinked(value, segment, ctx) {
|
|
|
27804
27951
|
{ kind: "read", at: "linked", extra: { via: segment.via } }
|
|
27805
27952
|
);
|
|
27806
27953
|
}
|
|
27807
|
-
const
|
|
27808
|
-
const ids = extractLinkIds(linkValue, segment.via);
|
|
27954
|
+
const ids = linkIds(ownMember(value, segment.via), segment.via);
|
|
27809
27955
|
if (segment.index === "each") {
|
|
27810
|
-
|
|
27956
|
+
assertCheap(ctx.evaluation_budget, ids);
|
|
27957
|
+
return fetchRecordsBounded(ids.map((id) => assertLinkId(id, segment.via)), `linked(...) on "${segment.via}"`, ctx);
|
|
27811
27958
|
}
|
|
27812
27959
|
const idx = typeof segment.index === "number" ? segment.index : await resolveIndexExpression(segment.index, ctx, `linked index via "${segment.via}"`);
|
|
27813
27960
|
const target = ids[idx];
|
|
27814
27961
|
if (target === void 0) return void 0;
|
|
27815
|
-
return fetchRecordData(target, ctx);
|
|
27962
|
+
return fetchRecordData(assertLinkId(target, segment.via), ctx);
|
|
27816
27963
|
}
|
|
27817
|
-
function
|
|
27964
|
+
function linkIds(value, via) {
|
|
27818
27965
|
if (value === void 0 || value === null) return [];
|
|
27819
27966
|
if (!Array.isArray(value)) {
|
|
27820
27967
|
throw new WorkflowEvalError(
|
|
@@ -27822,16 +27969,17 @@ function extractLinkIds(value, via) {
|
|
|
27822
27969
|
{ kind: "read", at: "linked", extra: { via } }
|
|
27823
27970
|
);
|
|
27824
27971
|
}
|
|
27825
|
-
for (const item of value) {
|
|
27826
|
-
if (typeof item !== "string") {
|
|
27827
|
-
throw new WorkflowEvalError(
|
|
27828
|
-
`Linked field "${via}" contains a non-string item \u2014 record data must be normalized before evaluation`,
|
|
27829
|
-
{ kind: "read", at: "linked", extra: { via, item_type: typeof item } }
|
|
27830
|
-
);
|
|
27831
|
-
}
|
|
27832
|
-
}
|
|
27833
27972
|
return value;
|
|
27834
27973
|
}
|
|
27974
|
+
function assertLinkId(item, via) {
|
|
27975
|
+
if (typeof item !== "string") {
|
|
27976
|
+
throw new WorkflowEvalError(
|
|
27977
|
+
`Linked field "${via}" contains a non-string item \u2014 record data must be normalized before evaluation`,
|
|
27978
|
+
{ kind: "read", at: "linked", extra: { via, item_type: typeof item } }
|
|
27979
|
+
);
|
|
27980
|
+
}
|
|
27981
|
+
return item;
|
|
27982
|
+
}
|
|
27835
27983
|
async function fetchRecordData(recordId, ctx) {
|
|
27836
27984
|
if (ctx.record_cache.has(recordId)) {
|
|
27837
27985
|
return ctx.record_cache.get(recordId) ?? null;
|
|
@@ -27843,18 +27991,18 @@ async function fetchRecordData(recordId, ctx) {
|
|
|
27843
27991
|
}
|
|
27844
27992
|
var LINK_FETCH_CONCURRENCY = 20;
|
|
27845
27993
|
var MAX_LINK_FAN_OUT = 1e4;
|
|
27846
|
-
async function fetchRecordsBounded(ids,
|
|
27994
|
+
async function fetchRecordsBounded(ids, reading, ctx) {
|
|
27847
27995
|
if (ids.length > MAX_LINK_FAN_OUT) {
|
|
27848
27996
|
throw new WorkflowEvalError(
|
|
27849
|
-
|
|
27850
|
-
{ kind: "read", at: "linked", extra: {
|
|
27997
|
+
`${reading} would fetch ${ids.length} rows, over the cap of ${MAX_LINK_FAN_OUT}. Index one row \u2014 linked(...)[i] \u2014 or narrow the link.`,
|
|
27998
|
+
{ kind: "read", at: "linked", extra: { reading } }
|
|
27851
27999
|
);
|
|
27852
28000
|
}
|
|
27853
28001
|
const results = [];
|
|
27854
28002
|
for (let i = 0; i < ids.length; i += LINK_FETCH_CONCURRENCY) {
|
|
27855
28003
|
for (let pause = checkClock(ctx); pause !== null; pause = checkClock(ctx)) await pause;
|
|
27856
28004
|
const chunk = ids.slice(i, i + LINK_FETCH_CONCURRENCY);
|
|
27857
|
-
results.push(...await Promise.all(chunk.map((id) => fetchRecordData(id, ctx))));
|
|
28005
|
+
results.push(...await Promise.all(chunk.map((id) => id === null ? null : fetchRecordData(id, ctx))));
|
|
27858
28006
|
}
|
|
27859
28007
|
return results;
|
|
27860
28008
|
}
|
|
@@ -27874,12 +28022,12 @@ async function evaluateCall(fn, args, ctx) {
|
|
|
27874
28022
|
);
|
|
27875
28023
|
for (let pause = checkClock(ctx); pause !== null; pause = checkClock(ctx)) await pause;
|
|
27876
28024
|
const cost = helperCost(fn);
|
|
27877
|
-
if (cost === "parses")
|
|
28025
|
+
if (cost === "parses") charge(ctx, parsedSize(evaluatedArgs[0]));
|
|
27878
28026
|
const answer = await helper(...evaluatedArgs);
|
|
27879
28027
|
if (cost !== "builds" && cost !== "nested") return answer;
|
|
27880
28028
|
const handedBack = evaluatedArgs.indexOf(answer);
|
|
27881
28029
|
if (handedBack !== -1) return evaluatedArgs[handedBack];
|
|
27882
|
-
|
|
28030
|
+
charge(ctx, builtSize(answer) + (cost === "nested" ? builtSize(evaluatedArgs[0]) : 0));
|
|
27883
28031
|
return answer;
|
|
27884
28032
|
}
|
|
27885
28033
|
async function evaluateBinary(op, leftExpr, rightExpr, ctx) {
|
|
@@ -27900,9 +28048,9 @@ async function evaluateBinary(op, leftExpr, rightExpr, ctx) {
|
|
|
27900
28048
|
for (let pause = checkClock(ctx); pause !== null; pause = checkClock(ctx)) await pause;
|
|
27901
28049
|
switch (op) {
|
|
27902
28050
|
case "eq":
|
|
27903
|
-
return looseEq(left, right);
|
|
27904
28051
|
case "neq":
|
|
27905
|
-
|
|
28052
|
+
assertCheap(ctx.evaluation_budget, looselyComparedText(left, right));
|
|
28053
|
+
return looseEq(left, right) === (op === "eq");
|
|
27906
28054
|
case "seq":
|
|
27907
28055
|
return strictEq(left, right);
|
|
27908
28056
|
case "sneq":
|
|
@@ -27917,10 +28065,11 @@ async function evaluateBinary(op, leftExpr, rightExpr, ctx) {
|
|
|
27917
28065
|
return compareOrdered(left, right) <= 0;
|
|
27918
28066
|
case "add": {
|
|
27919
28067
|
if (typeof left === "string" || typeof right === "string") {
|
|
28068
|
+
assertCheap(ctx.evaluation_budget, left, right);
|
|
27920
28069
|
assertTextWithin("+", typeof left === "string" ? null : left, typeof right === "string" ? null : right);
|
|
27921
28070
|
}
|
|
27922
28071
|
const sum2 = addOrConcat(left, right, () => assertNumber(left, "add", "left") + assertNumber(right, "add", "right"));
|
|
27923
|
-
|
|
28072
|
+
charge(ctx, builtSize(sum2));
|
|
27924
28073
|
return sum2;
|
|
27925
28074
|
}
|
|
27926
28075
|
case "sub":
|
|
@@ -27944,8 +28093,21 @@ async function evaluateBinary(op, leftExpr, rightExpr, ctx) {
|
|
|
27944
28093
|
}
|
|
27945
28094
|
}
|
|
27946
28095
|
function looseEq(a, b) {
|
|
28096
|
+
if (isComposite(a) && b !== null && b !== void 0 && !isComposite(b)) return looseEq(textOf(a), b);
|
|
28097
|
+
if (isComposite(b) && a !== null && a !== void 0 && !isComposite(a)) return looseEq(a, textOf(b));
|
|
27947
28098
|
return a == b;
|
|
27948
28099
|
}
|
|
28100
|
+
function isComposite(value) {
|
|
28101
|
+
return typeof value === "object" && value !== null;
|
|
28102
|
+
}
|
|
28103
|
+
function looselyComparedText(a, b) {
|
|
28104
|
+
if (Array.isArray(a) && isScalar(b)) return a;
|
|
28105
|
+
if (Array.isArray(b) && isScalar(a)) return b;
|
|
28106
|
+
return null;
|
|
28107
|
+
}
|
|
28108
|
+
function isScalar(value) {
|
|
28109
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint";
|
|
28110
|
+
}
|
|
27949
28111
|
function strictEq(a, b) {
|
|
27950
28112
|
return a === b;
|
|
27951
28113
|
}
|
|
@@ -27979,8 +28141,14 @@ function describeValue(value) {
|
|
|
27979
28141
|
if (typeof value === "string") return `string ${jsonPreview(value, VALUE_PREVIEW_LENGTH)}`;
|
|
27980
28142
|
if (typeof value === "number") return `number ${String(value)}`;
|
|
27981
28143
|
if (typeof value === "boolean") return `boolean ${String(value)}`;
|
|
27982
|
-
|
|
27983
|
-
|
|
28144
|
+
if (!Array.isArray(value)) return typeof value;
|
|
28145
|
+
let length2 = 0;
|
|
28146
|
+
for (let at2 = 0; at2 < value.length && length2 <= VALUE_PREVIEW_LENGTH; at2++) {
|
|
28147
|
+
const element = value[at2];
|
|
28148
|
+
if (element !== null && element !== void 0 && !isScalar(element)) return "array";
|
|
28149
|
+
length2 += (typeof element === "string" ? element.length : LONGEST_NUMBER_TEXT) + 1;
|
|
28150
|
+
}
|
|
28151
|
+
return value.length > 0 && length2 <= VALUE_PREVIEW_LENGTH ? `array ${value.join(",")}` : "array";
|
|
27984
28152
|
}
|
|
27985
28153
|
async function evaluateUnary(op, argExpr, ctx) {
|
|
27986
28154
|
const value = await evaluateExpression(argExpr, ctx);
|
|
@@ -28002,9 +28170,10 @@ async function evaluateTemplate(parts, ctx) {
|
|
|
28002
28170
|
parts.map((part) => part.t === "text" ? part.s : evaluateExpression(part.e, ctx))
|
|
28003
28171
|
);
|
|
28004
28172
|
for (let pause = checkClock(ctx); pause !== null; pause = checkClock(ctx)) await pause;
|
|
28173
|
+
assertCheap(ctx.evaluation_budget, ...evaluated2);
|
|
28005
28174
|
assertTextWithin("template", ...evaluated2);
|
|
28006
28175
|
const text2 = evaluated2.map(stringifyForTemplate).join("");
|
|
28007
|
-
|
|
28176
|
+
charge(ctx, builtSize(text2));
|
|
28008
28177
|
return text2;
|
|
28009
28178
|
}
|
|
28010
28179
|
function assertTextWithin(writer, ...values2) {
|
|
@@ -28018,8 +28187,7 @@ function assertTextWithin(writer, ...values2) {
|
|
|
28018
28187
|
}
|
|
28019
28188
|
function stringifyForTemplate(value) {
|
|
28020
28189
|
if (value === null || value === void 0) return "";
|
|
28021
|
-
|
|
28022
|
-
return String(value);
|
|
28190
|
+
return textOf(value);
|
|
28023
28191
|
}
|
|
28024
28192
|
|
|
28025
28193
|
// ../shared/src/id.ts
|
|
@@ -28079,6 +28247,11 @@ function knownCells(tables, tableId, cells) {
|
|
|
28079
28247
|
},
|
|
28080
28248
|
has(target, key) {
|
|
28081
28249
|
return isField(key) || Reflect.has(target, key);
|
|
28250
|
+
},
|
|
28251
|
+
// An expression reads only what a row holds itself (`ownMember`).
|
|
28252
|
+
getOwnPropertyDescriptor(target, key) {
|
|
28253
|
+
if (isField(key) && !Object.hasOwn(target, key)) unread(key);
|
|
28254
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
28082
28255
|
}
|
|
28083
28256
|
}
|
|
28084
28257
|
);
|
|
@@ -28088,6 +28261,11 @@ function modelled(stepId, output) {
|
|
|
28088
28261
|
get(target, key) {
|
|
28089
28262
|
if (typeof key === "string" && key !== "then" && !(key in target)) unread(`${stepId}.${key}`);
|
|
28090
28263
|
return Reflect.get(target, key);
|
|
28264
|
+
},
|
|
28265
|
+
// An expression reads only what an output holds itself (`ownMember`).
|
|
28266
|
+
getOwnPropertyDescriptor(target, key) {
|
|
28267
|
+
if (typeof key === "string" && key !== "then" && !Object.hasOwn(target, key)) unread(`${stepId}.${key}`);
|
|
28268
|
+
return Reflect.getOwnPropertyDescriptor(target, key);
|
|
28091
28269
|
}
|
|
28092
28270
|
});
|
|
28093
28271
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lotics/app-sdk",
|
|
3
|
-
"version": "0.115.
|
|
3
|
+
"version": "0.115.3",
|
|
4
4
|
"description": "The SDK a Lotics custom-code app reads and writes through \u2014 typed hooks over the host bridge, cell readers, mount() and AppRouter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|