@camstack/types 1.2.268 → 1.2.270
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/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/capability-definition.d.ts +8 -1
- package/dist/capabilities/composer.cap.d.ts +6 -0
- package/dist/capabilities/core-blocks.cap.d.ts +54 -3
- package/dist/capabilities/device-manager.cap.d.ts +4 -4
- package/dist/capabilities/doorbell.cap.d.ts +4 -0
- package/dist/capabilities/media-player.cap.d.ts +4 -4
- package/dist/capabilities/recording-archive.cap.d.ts +5 -3
- package/dist/catalogs/sensor-active-state.d.ts +25 -1
- package/dist/composition/composition-events.d.ts +42 -0
- package/dist/composition/composition-report.d.ts +22 -10
- package/dist/composition/composition.d.ts +8 -0
- package/dist/composition/evaluate-field.d.ts +8 -0
- package/dist/composition/expression-kinds.d.ts +1 -0
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/plan-result.d.ts +2 -0
- package/dist/{composition-QlOB7QTG.js → composition-BAH3n-zq.js} +412 -14
- package/dist/{composition-CPFIlFfw.mjs → composition-D5BQywfe.mjs} +311 -15
- package/dist/expression/ast.d.ts +2 -0
- package/dist/expression/builtins.d.ts +9 -0
- package/dist/expression/evaluator.d.ts +8 -2
- package/dist/expression/expression-source.d.ts +26 -4
- package/dist/expression/index.d.ts +6 -6
- package/dist/index.d.ts +3 -3
- package/dist/index.js +335 -329
- package/dist/index.mjs +313 -319
- package/dist/interfaces/recording-config.d.ts +3 -3
- package/dist/node.js +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{sleep-BSzia-xT.js → sleep-Bg0IB7gg.js} +4 -15
- package/dist/{sleep-jkRQgtSc.mjs → sleep-E6eD4yQS.mjs} +4 -15
- package/package.json +1 -1
|
@@ -714,6 +714,197 @@ function replaceWithSortedKeys(_key, value) {
|
|
|
714
714
|
return value;
|
|
715
715
|
}
|
|
716
716
|
//#endregion
|
|
717
|
+
//#region src/catalogs/sensor-active-state.ts
|
|
718
|
+
/**
|
|
719
|
+
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
720
|
+
* valutatore puro del suo FRONTE.
|
|
721
|
+
*
|
|
722
|
+
* Viveva dentro il builtin virtual-doorbell
|
|
723
|
+
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
724
|
+
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
725
|
+
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
726
|
+
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
727
|
+
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
728
|
+
* SPOSTA qui e il doorbell la ri-esporta.
|
|
729
|
+
*
|
|
730
|
+
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
731
|
+
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
732
|
+
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
733
|
+
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
734
|
+
*/
|
|
735
|
+
/**
|
|
736
|
+
* Known binary / switch source caps → the boolean slice field whose
|
|
737
|
+
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
738
|
+
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
739
|
+
* state, connectivity's connected flag) are deliberately excluded — a
|
|
740
|
+
* reconnect is not a doorbell press, and it is not a recording either.
|
|
741
|
+
*/
|
|
742
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
743
|
+
contact: "entryOpen",
|
|
744
|
+
binary: "on",
|
|
745
|
+
switch: "on",
|
|
746
|
+
motion: "detected",
|
|
747
|
+
flood: "flooded",
|
|
748
|
+
gas: "detected",
|
|
749
|
+
smoke: "detected",
|
|
750
|
+
"carbon-monoxide": "detected",
|
|
751
|
+
vibration: "detected",
|
|
752
|
+
tamper: "tampered"
|
|
753
|
+
};
|
|
754
|
+
/**
|
|
755
|
+
* The same caps → the slice field carrying the ms-epoch timestamp of the
|
|
756
|
+
* last transition. Every source cap MUST appear here (guarded by a spec):
|
|
757
|
+
* without a transition timestamp the evaluator cannot tell a genuine rise
|
|
758
|
+
* from a boot-time hydration when the FIRST slice it ever sees is already
|
|
759
|
+
* active, and errs towards silence — swallowing the rise.
|
|
760
|
+
*
|
|
761
|
+
* These timestamps are UPSTREAM ones, not ingest ones: the Home Assistant
|
|
762
|
+
* provider derives them from `state.last_changed`, so they survive our own
|
|
763
|
+
* restarts and correctly read as "hours ago" for a state that has been
|
|
764
|
+
* active for hours. `motion` names its rise timestamp `lastDetectedAt`.
|
|
765
|
+
*/
|
|
766
|
+
var SOURCE_CAP_CHANGED_AT_FIELD = {
|
|
767
|
+
contact: "lastChangedAt",
|
|
768
|
+
binary: "lastChangedAt",
|
|
769
|
+
switch: "lastChangedAt",
|
|
770
|
+
motion: "lastDetectedAt",
|
|
771
|
+
flood: "lastChangedAt",
|
|
772
|
+
gas: "lastChangedAt",
|
|
773
|
+
smoke: "lastChangedAt",
|
|
774
|
+
"carbon-monoxide": "lastChangedAt",
|
|
775
|
+
vibration: "lastChangedAt",
|
|
776
|
+
tamper: "lastChangedAt"
|
|
777
|
+
};
|
|
778
|
+
/** Cap names whose presence in a device's bindings qualify it as a source. */
|
|
779
|
+
var SOURCE_CAPS = Object.keys(SOURCE_CAP_ACTIVE_FIELD);
|
|
780
|
+
/**
|
|
781
|
+
* Device `type` values (from `DeviceType`) that can host a binary/switch
|
|
782
|
+
* source cap. Used by the camera's `device-multiselect` picker as the
|
|
783
|
+
* CLIENT-SIDE filter, alongside `SOURCE_CAPS`.
|
|
784
|
+
*
|
|
785
|
+
* Why types and not caps alone: the shared picker filters
|
|
786
|
+
* `deviceManager.listAll` rows client-side, and those rows carry only the
|
|
787
|
+
* device's advertised `features` — NOT its registered cap list. On the live
|
|
788
|
+
* cluster binary sensors and switches advertise EMPTY features (features
|
|
789
|
+
* mirror only a handful of caps like `motion-trigger`), so a caps-only
|
|
790
|
+
* filter matched against `features` would list nothing (the very bug this
|
|
791
|
+
* replaced, which relied on the now-empty `getAllBindings`). Matching by
|
|
792
|
+
* `type` is the reliable client-side signal; the union with `SOURCE_CAPS`
|
|
793
|
+
* still captures any device that DOES advertise a source-cap feature.
|
|
794
|
+
* `sensor` covers contact/motion/flood/gas/smoke/CO/vibration/tamper,
|
|
795
|
+
* `switch` covers switches, `control` covers generic binary actuators.
|
|
796
|
+
*/
|
|
797
|
+
var SOURCE_DEVICE_TYPES = [
|
|
798
|
+
"sensor",
|
|
799
|
+
"switch",
|
|
800
|
+
"control"
|
|
801
|
+
];
|
|
802
|
+
/** True when a cap is a recognised binary/switch source. */
|
|
803
|
+
function isSourceCap(capName) {
|
|
804
|
+
return Object.prototype.hasOwnProperty.call(SOURCE_CAP_ACTIVE_FIELD, capName);
|
|
805
|
+
}
|
|
806
|
+
/** Extract the "active" boolean a source cap's slice carries, or null when
|
|
807
|
+
* the cap is unknown or the field is missing / non-boolean. */
|
|
808
|
+
function sliceActiveValue(capName, slice) {
|
|
809
|
+
const field = SOURCE_CAP_ACTIVE_FIELD[capName];
|
|
810
|
+
if (field === void 0) return null;
|
|
811
|
+
const raw = slice[field];
|
|
812
|
+
return typeof raw === "boolean" ? raw : null;
|
|
813
|
+
}
|
|
814
|
+
/** Ms-epoch transition timestamp a source cap's slice carries, or null when
|
|
815
|
+
* it is absent, non-numeric or the zero "never observed" sentinel. */
|
|
816
|
+
function sliceChangedAt(capName, slice) {
|
|
817
|
+
const field = SOURCE_CAP_CHANGED_AT_FIELD[capName];
|
|
818
|
+
if (field === void 0) return null;
|
|
819
|
+
const raw = slice[field];
|
|
820
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) return null;
|
|
821
|
+
return raw;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* How recent a source's own transition timestamp must be for a FIRST
|
|
825
|
+
* sighting that is already active to count as a genuine rise rather than a
|
|
826
|
+
* hydration of long-standing state.
|
|
827
|
+
*/
|
|
828
|
+
var DEFAULT_FIRST_SIGHTING_FRESHNESS_MS = 3e4;
|
|
829
|
+
/**
|
|
830
|
+
* The source-independent edge rule. The caller supplies an already extracted
|
|
831
|
+
* boolean level and source timestamp; this function owns first-sighting
|
|
832
|
+
* freshness and false-to-true detection.
|
|
833
|
+
*/
|
|
834
|
+
function evaluateSensorLevelEdge(input) {
|
|
835
|
+
const timestamp = input.changedAt;
|
|
836
|
+
const freshFloor = Math.max(input.startedAtMs, input.nowMs - input.firstSightingFreshnessMs);
|
|
837
|
+
const firstRise = input.priorLevel === void 0 && input.level && timestamp !== null && Number.isFinite(timestamp) && timestamp >= freshFloor;
|
|
838
|
+
const transitionRise = input.priorLevel === false && input.level && timestamp !== null && Number.isFinite(timestamp);
|
|
839
|
+
if ((firstRise || transitionRise) && timestamp !== null) return {
|
|
840
|
+
kind: "rise",
|
|
841
|
+
timestamp
|
|
842
|
+
};
|
|
843
|
+
return {
|
|
844
|
+
kind: "none",
|
|
845
|
+
nextPriorLevel: input.level
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
|
|
850
|
+
* porta `prior`, `nowMs` e il proprio `startedAtMs`.
|
|
851
|
+
*
|
|
852
|
+
* Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
|
|
853
|
+
* fronte solo se il timestamp UPSTREAM della transizione è posteriore a
|
|
854
|
+
* `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
|
|
855
|
+
* servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
|
|
856
|
+
* stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
|
|
857
|
+
* iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
|
|
858
|
+
* adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
|
|
859
|
+
* SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
|
|
860
|
+
*/
|
|
861
|
+
function evaluateSensorEdge(input) {
|
|
862
|
+
const value = sliceActiveValue(input.capName, input.slice);
|
|
863
|
+
if (value === null) return {
|
|
864
|
+
edge: "none",
|
|
865
|
+
value: null,
|
|
866
|
+
reason: isSourceCap(input.capName) ? "non-boolean-value" : "unknown-cap"
|
|
867
|
+
};
|
|
868
|
+
if (evaluateSensorLevelEdge({
|
|
869
|
+
level: value,
|
|
870
|
+
changedAt: sliceChangedAt(input.capName, input.slice),
|
|
871
|
+
priorLevel: input.prior,
|
|
872
|
+
startedAtMs: input.startedAtMs,
|
|
873
|
+
nowMs: input.nowMs,
|
|
874
|
+
firstSightingFreshnessMs: input.firstSightingFreshnessMs
|
|
875
|
+
}).kind === "rise") return {
|
|
876
|
+
edge: "rising",
|
|
877
|
+
value: true
|
|
878
|
+
};
|
|
879
|
+
if (input.prior === void 0) {
|
|
880
|
+
if (!value) return {
|
|
881
|
+
edge: "none",
|
|
882
|
+
value,
|
|
883
|
+
reason: "baseline-seeded-inactive"
|
|
884
|
+
};
|
|
885
|
+
return {
|
|
886
|
+
edge: "none",
|
|
887
|
+
value,
|
|
888
|
+
reason: "baseline-seeded-stale-active"
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
if (input.prior === value) return {
|
|
892
|
+
edge: "none",
|
|
893
|
+
value,
|
|
894
|
+
reason: "no-change"
|
|
895
|
+
};
|
|
896
|
+
if (!value) return {
|
|
897
|
+
edge: "none",
|
|
898
|
+
value,
|
|
899
|
+
reason: "falling-edge"
|
|
900
|
+
};
|
|
901
|
+
return {
|
|
902
|
+
edge: "none",
|
|
903
|
+
value,
|
|
904
|
+
reason: "missing-timestamp"
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
//#endregion
|
|
717
908
|
//#region src/expression/errors.ts
|
|
718
909
|
/**
|
|
719
910
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
@@ -740,6 +931,9 @@ var ExpressionEvalError = class extends Error {
|
|
|
740
931
|
};
|
|
741
932
|
//#endregion
|
|
742
933
|
//#region src/expression/builtins.ts
|
|
934
|
+
function isStatefulBuiltin(name) {
|
|
935
|
+
return name === "rose" || name === "count";
|
|
936
|
+
}
|
|
743
937
|
function asFiniteNumber(value, name, index) {
|
|
744
938
|
if (typeof value !== "number" || !Number.isFinite(value)) throw new ExpressionEvalError(`${name}: argument ${index + 1} must be a finite number`);
|
|
745
939
|
return value;
|
|
@@ -775,6 +969,37 @@ function toNumberOrNull(value) {
|
|
|
775
969
|
const parsed = Number(trimmed);
|
|
776
970
|
return Number.isFinite(parsed) ? parsed : null;
|
|
777
971
|
}
|
|
972
|
+
var DEFAULT_ROSE_DEBOUNCE_MS = 2e3;
|
|
973
|
+
function evaluateRose(level, changedAt, debounceMs, call, field, env) {
|
|
974
|
+
const active = asBoolean(level, "rose", 0);
|
|
975
|
+
const timestamp = typeof changedAt === "number" && Number.isFinite(changedAt) ? changedAt : null;
|
|
976
|
+
const debounce = debounceMs === void 0 ? DEFAULT_ROSE_DEBOUNCE_MS : asFiniteNumber(debounceMs, "rose", 2);
|
|
977
|
+
if (debounce < 0) throw new ExpressionEvalError("rose: debounce must be a non-negative finite number");
|
|
978
|
+
const verdict = evaluateSensorLevelEdge({
|
|
979
|
+
level: active,
|
|
980
|
+
changedAt: timestamp,
|
|
981
|
+
priorLevel: call.priorLevel,
|
|
982
|
+
startedAtMs: env.startedAtMs,
|
|
983
|
+
nowMs: env.nowMs,
|
|
984
|
+
firstSightingFreshnessMs: DEFAULT_FIRST_SIGHTING_FRESHNESS_MS
|
|
985
|
+
});
|
|
986
|
+
call.priorLevel = verdict.kind === "rise" ? true : verdict.nextPriorLevel;
|
|
987
|
+
if (verdict.kind === "none") return env.currentOutput;
|
|
988
|
+
if (field.acceptedEdgeAt !== null && verdict.timestamp - field.acceptedEdgeAt < debounce) return env.currentOutput;
|
|
989
|
+
field.acceptedEdgeAt = verdict.timestamp;
|
|
990
|
+
return verdict.timestamp;
|
|
991
|
+
}
|
|
992
|
+
function evaluateCount(input, call, currentOutput) {
|
|
993
|
+
const currentCount = typeof currentOutput === "number" && Number.isFinite(currentOutput) && currentOutput >= 0 ? currentOutput : 0;
|
|
994
|
+
if (typeof input !== "number" || !Number.isFinite(input)) return currentCount;
|
|
995
|
+
if (call.highWater === null) {
|
|
996
|
+
call.highWater = input;
|
|
997
|
+
return currentCount;
|
|
998
|
+
}
|
|
999
|
+
if (input <= call.highWater) return currentCount;
|
|
1000
|
+
call.highWater = input;
|
|
1001
|
+
return currentCount + 1;
|
|
1002
|
+
}
|
|
778
1003
|
var INF = Number.POSITIVE_INFINITY;
|
|
779
1004
|
var table = {
|
|
780
1005
|
min: {
|
|
@@ -914,6 +1139,20 @@ var table = {
|
|
|
914
1139
|
const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
|
|
915
1140
|
return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
|
|
916
1141
|
}
|
|
1142
|
+
},
|
|
1143
|
+
rose: {
|
|
1144
|
+
minArgs: 2,
|
|
1145
|
+
maxArgs: 3,
|
|
1146
|
+
apply: () => {
|
|
1147
|
+
throw new ExpressionEvalError("rose: stateful evaluation context is required");
|
|
1148
|
+
}
|
|
1149
|
+
},
|
|
1150
|
+
count: {
|
|
1151
|
+
minArgs: 1,
|
|
1152
|
+
maxArgs: 1,
|
|
1153
|
+
apply: () => {
|
|
1154
|
+
throw new ExpressionEvalError("count: stateful evaluation context is required");
|
|
1155
|
+
}
|
|
917
1156
|
}
|
|
918
1157
|
};
|
|
919
1158
|
/** Frozen, null-prototype builtin table. */
|
|
@@ -1397,22 +1636,28 @@ function step(ctx) {
|
|
|
1397
1636
|
ctx.steps += 1;
|
|
1398
1637
|
if (ctx.steps > ctx.maxSteps) throw new ExpressionEvalError("expression evaluation step budget exceeded");
|
|
1399
1638
|
}
|
|
1400
|
-
function
|
|
1639
|
+
function childPath(path, child) {
|
|
1640
|
+
return `${path}/${child}`;
|
|
1641
|
+
}
|
|
1642
|
+
function evalNode(node, ctx, path) {
|
|
1401
1643
|
step(ctx);
|
|
1402
1644
|
switch (node.kind) {
|
|
1403
1645
|
case "literal": return node.value;
|
|
1404
1646
|
case "identifier":
|
|
1405
1647
|
if (!(node.name in ctx.scope)) throw new ExpressionEvalError(`unknown identifier: ${node.name}`);
|
|
1406
1648
|
return ctx.scope[node.name];
|
|
1407
|
-
case "unary": return evalUnary(node.op, evalNode(node.operand, ctx));
|
|
1408
|
-
case "binary": return evalBinary(node.op, evalNode(node.left, ctx), evalNode(node.right, ctx));
|
|
1649
|
+
case "unary": return evalUnary(node.op, evalNode(node.operand, ctx, childPath(path, "operand")));
|
|
1650
|
+
case "binary": return evalBinary(node.op, evalNode(node.left, ctx, childPath(path, "left")), evalNode(node.right, ctx, childPath(path, "right")));
|
|
1409
1651
|
case "logical": {
|
|
1410
|
-
const left = evalNode(node.left, ctx);
|
|
1411
|
-
if (node.op === "&&") return truthy(left) ? evalNode(node.right, ctx) : left;
|
|
1412
|
-
return truthy(left) ? left : evalNode(node.right, ctx);
|
|
1652
|
+
const left = evalNode(node.left, ctx, childPath(path, "left"));
|
|
1653
|
+
if (node.op === "&&") return truthy(left) ? evalNode(node.right, ctx, childPath(path, "right")) : left;
|
|
1654
|
+
return truthy(left) ? left : evalNode(node.right, ctx, childPath(path, "right"));
|
|
1655
|
+
}
|
|
1656
|
+
case "conditional": return truthy(evalNode(node.test, ctx, childPath(path, "test"))) ? evalNode(node.consequent, ctx, childPath(path, "consequent")) : evalNode(node.alternate, ctx, childPath(path, "alternate"));
|
|
1657
|
+
case "call": {
|
|
1658
|
+
const args = node.args.map((arg, index) => evalNode(arg, ctx, childPath(path, `arg:${index}`)));
|
|
1659
|
+
return invokeCall(node.callee, args, path, ctx);
|
|
1413
1660
|
}
|
|
1414
|
-
case "conditional": return truthy(evalNode(node.test, ctx)) ? evalNode(node.consequent, ctx) : evalNode(node.alternate, ctx);
|
|
1415
|
-
case "call": return evalCall(node.callee, node.args.map((a) => evalNode(a, ctx)), ctx.hooks);
|
|
1416
1661
|
}
|
|
1417
1662
|
}
|
|
1418
1663
|
function evalUnary(op, operand) {
|
|
@@ -1443,11 +1688,19 @@ function evalBinary(op, left, right) {
|
|
|
1443
1688
|
throw new ExpressionEvalError(`"${op}" requires two numbers or two strings`);
|
|
1444
1689
|
}
|
|
1445
1690
|
}
|
|
1446
|
-
function
|
|
1691
|
+
function invokeCall(callee, args, path, ctx) {
|
|
1447
1692
|
if (!Object.prototype.hasOwnProperty.call(EXPRESSION_BUILTINS, callee)) throw new ExpressionEvalError(`unknown function: ${callee}`);
|
|
1448
1693
|
const builtin = EXPRESSION_BUILTINS[callee];
|
|
1449
1694
|
if (args.length < builtin.minArgs || args.length > builtin.maxArgs) throw new ExpressionEvalError(`${callee}: wrong number of arguments (${args.length})`);
|
|
1450
|
-
|
|
1695
|
+
if (isStatefulBuiltin(callee)) {
|
|
1696
|
+
if (ctx.invokeStateful === void 0) throw new ExpressionEvalError(`${callee}: stateful evaluation context is required`);
|
|
1697
|
+
return ctx.invokeStateful({
|
|
1698
|
+
name: callee,
|
|
1699
|
+
path,
|
|
1700
|
+
args
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
return builtin.apply(args, ctx.hooks);
|
|
1451
1704
|
}
|
|
1452
1705
|
/** Evaluate an AST node against a scope. Throws `ExpressionEvalError` on any
|
|
1453
1706
|
* runtime failure (unknown identifier, type mismatch, non-finite result,
|
|
@@ -1457,11 +1710,47 @@ function evaluateAst(node, scope, opts) {
|
|
|
1457
1710
|
scope,
|
|
1458
1711
|
hooks: opts?.hooks ?? EMPTY_HOOKS,
|
|
1459
1712
|
maxSteps: opts?.maxSteps ?? 4096,
|
|
1713
|
+
...opts?.invokeStateful === void 0 ? {} : { invokeStateful: opts.invokeStateful },
|
|
1460
1714
|
steps: 0
|
|
1461
|
-
});
|
|
1715
|
+
}, "root");
|
|
1462
1716
|
}
|
|
1463
1717
|
//#endregion
|
|
1464
1718
|
//#region src/expression/expression-source.ts
|
|
1719
|
+
function createStatefulExpressionMemory() {
|
|
1720
|
+
return {
|
|
1721
|
+
calls: /* @__PURE__ */ new Map(),
|
|
1722
|
+
acceptedEdgeAt: null
|
|
1723
|
+
};
|
|
1724
|
+
}
|
|
1725
|
+
function cloneStatefulExpressionMemory(memory) {
|
|
1726
|
+
return {
|
|
1727
|
+
calls: new Map([...memory.calls].map(([path, call]) => [path, { ...call }])),
|
|
1728
|
+
acceptedEdgeAt: memory.acceptedEdgeAt
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
function evaluateStatefulExpressionCall(invocation, memory, env) {
|
|
1732
|
+
const existing = memory.calls.get(invocation.path);
|
|
1733
|
+
switch (invocation.name) {
|
|
1734
|
+
case "rose": {
|
|
1735
|
+
const call = existing?.kind === "rose" ? existing : { kind: "rose" };
|
|
1736
|
+
memory.calls.set(invocation.path, call);
|
|
1737
|
+
const currentOutput = env.currentOutput === null || typeof env.currentOutput === "number" && Number.isFinite(env.currentOutput) ? env.currentOutput : null;
|
|
1738
|
+
return evaluateRose(invocation.args[0], invocation.args[1], invocation.args[2], call, memory, {
|
|
1739
|
+
currentOutput,
|
|
1740
|
+
startedAtMs: env.startedAtMs,
|
|
1741
|
+
nowMs: env.nowMs
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
case "count": {
|
|
1745
|
+
const call = existing?.kind === "count" ? existing : {
|
|
1746
|
+
kind: "count",
|
|
1747
|
+
highWater: null
|
|
1748
|
+
};
|
|
1749
|
+
memory.calls.set(invocation.path, call);
|
|
1750
|
+
return evaluateCount(invocation.args[0], call, env.currentOutput);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1465
1754
|
/** The `now` epoch-ms binding is auto-injected into every evaluation and is a
|
|
1466
1755
|
* reserved binding name (authors may not rebind it). */
|
|
1467
1756
|
var EXPRESSION_INJECTED_NOW = "now";
|
|
@@ -1504,9 +1793,10 @@ function validateExpressionSource(src) {
|
|
|
1504
1793
|
/**
|
|
1505
1794
|
* Shared read-path evaluation. Builds a null-proto scope from `bindingValues`
|
|
1506
1795
|
* plus the injected `now` (supplied by the caller for determinism and
|
|
1507
|
-
* testability), compiles via the LRU, and evaluates.
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
1796
|
+
* testability), compiles via the LRU, and evaluates. Stateful calls are
|
|
1797
|
+
* delegated through `opts.invokeStateful` with their stable AST path. Any
|
|
1798
|
+
* failure (parse or eval) returns `{ ok: false }` — the caller treats that as
|
|
1799
|
+
* "skip this derivation", never as a throw that takes the pass down.
|
|
1510
1800
|
*/
|
|
1511
1801
|
function evaluateExpressionSource(expr, bindingValues, now, opts) {
|
|
1512
1802
|
const compiled = compileExpressionSafe(expr);
|
|
@@ -1650,6 +1940,7 @@ var CompositionItemEntrySchema = z.object({
|
|
|
1650
1940
|
var CompositionFieldsFeatureSchema = z.object({
|
|
1651
1941
|
kind: z.literal("fields"),
|
|
1652
1942
|
cap: z.string().min(1),
|
|
1943
|
+
enabled: z.boolean().optional(),
|
|
1653
1944
|
fields: z.record(z.string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
|
|
1654
1945
|
/**
|
|
1655
1946
|
* Items of the cap's item array, keyed by item key (D663). Naming `items`
|
|
@@ -1663,9 +1954,14 @@ var CompositionFieldsFeatureSchema = z.object({
|
|
|
1663
1954
|
var CompositionPassthroughFeatureSchema = z.object({
|
|
1664
1955
|
kind: z.literal("passthrough"),
|
|
1665
1956
|
cap: z.string().min(1),
|
|
1957
|
+
enabled: z.boolean().optional(),
|
|
1666
1958
|
source: CompositionSourceRefSchema
|
|
1667
1959
|
});
|
|
1668
1960
|
var CompositionFeatureSchema = z.discriminatedUnion("kind", [CompositionFieldsFeatureSchema, CompositionPassthroughFeatureSchema]);
|
|
1961
|
+
/** Only an explicit `false` disables a feature; omitted preserves the existing wire default. */
|
|
1962
|
+
function compositionFeatureEnabled(feature) {
|
|
1963
|
+
return feature.enabled !== false;
|
|
1964
|
+
}
|
|
1669
1965
|
/**
|
|
1670
1966
|
* A NEW device. It has no `name` of its own: the block's name IS the device's
|
|
1671
1967
|
* name (2026-08-08). A second copy here would be a second writer of one string (D62).
|
|
@@ -1756,4 +2052,4 @@ function featureSources(feature) {
|
|
|
1756
2052
|
return featureFieldEntries(feature).map((e) => e.source);
|
|
1757
2053
|
}
|
|
1758
2054
|
//#endregion
|
|
1759
|
-
export {
|
|
2055
|
+
export { MAX_EXPRESSION_AST_NODES as $, compositionFeatureEnabled as A, invocationFromEncodeProfile as At, createStatefulExpressionMemory as B, CompositionTargetSchema as C, Fmp4BoxSplitter as Ct, MAX_COMPOSITION_ITEMS as D, buildFfmpegArgs as Dt, MAX_COMPOSITION_FIELDS_PER_FEATURE as E, buildAudioArgs as Et, featureFieldEntries as F, createExpressionScope as G, evaluateStatefulExpressionCall as H, featureSources as I, compileExpressionSafe as J, evaluateAst as K, fieldReads as L, compositionReadKey as M, logBannerArgs as Mt, compositionSliceKey as N, pickVideoEncoder as Nt, composedDeviceRef as O, buildInputArgs as Ot, compositionSourceKey as P, resolveStreamMaps as Pt, EXPRESSION_IDENTIFIER_RE as Q, EXPRESSION_INJECTED_NOW as R, CompositionSourceRefSchema as S, canonicalHash as St, MAX_COMPOSITION_FEATURES as T, audioPlanFromEncodeProfile as Tt, toExpressionValue as U, evaluateExpressionSource as V, validateExpressionSource as W, tokenize as X, parseExpression as Y, EXPRESSION_COMPILE_CACHE_CAPACITY as Z, CompositionItemEntrySchema as _, evaluateSensorEdge as _t, CUSTOMIZATION_BLOCK_NAME_PREFIX as a, EXPRESSION_BUILTINS as at, CompositionPassthroughFeatureSchema as b, sliceActiveValue as bt, CompositionCommandTargetSchema as c, evaluateRose as ct, CompositionFeatureSchema as d, ExpressionParseError as dt, MAX_EXPRESSION_BINDINGS as et, CompositionFieldReadSchema as f, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as ft, CompositionFromSourceSchema as g, SOURCE_DEVICE_TYPES as gt, CompositionForwardCommandSchema as h, SOURCE_CAP_CHANGED_AT_FIELD as ht, COMPOSITION_ITEM_KEY_RE as i, RESERVED_BINDING_NAMES as it, compositionItemFieldPath as j, isSoftwareDecode as jt, composedDeviceStableId as k, buildVideoArgs as kt, CompositionExistingTargetSchema as l, isStatefulBuiltin as lt, CompositionFieldsFeatureSchema as m, SOURCE_CAP_ACTIVE_FIELD as mt, COMPOSER_ADDON_ID as n, MAX_EXPRESSION_EVAL_STEPS as nt, CompositionBindingSchema as o, EXPRESSION_BUILTIN_NAMES as ot, CompositionFieldSourceSchema as p, SOURCE_CAPS as pt, compileExpression as q, COMPOSITION_ITEM_ARRAY_PATH as r, MAX_EXPRESSION_SOURCE_LENGTH as rt, CompositionCodeSourceSchema as s, evaluateCount as st, COMPOSED_DEVICE_STABLE_ID_PREFIX as t, MAX_EXPRESSION_CALL_ARGS as tt, CompositionExpressionSourceSchema as u, ExpressionEvalError as ut, CompositionLiteralBindingSchema as v, evaluateSensorLevelEdge as vt, MAX_COMPOSITION_CODE_LENGTH as w, AUDIO_PRESETS as wt, CompositionSchema as x, sliceChangedAt as xt, CompositionNewTargetSchema as y, isSourceCap as yt, cloneStatefulExpressionMemory as z };
|
package/dist/expression/ast.d.ts
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
*/
|
|
15
15
|
/** The only value types the engine produces or consumes. */
|
|
16
16
|
export type ExpressionValue = number | string | boolean | null;
|
|
17
|
+
/** Stable structural address of a node within one parsed expression AST. */
|
|
18
|
+
export type ExpressionNodePath = string;
|
|
17
19
|
export type ExpressionBinaryOperator = '+' | '-' | '*' | '/' | '%' | '==' | '!=' | '<' | '<=' | '>' | '>=';
|
|
18
20
|
export type ExpressionLogicalOperator = '&&' | '||';
|
|
19
21
|
export type ExpressionUnaryOperator = '-' | '!';
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* closed rather than emitting a garbage value.
|
|
17
17
|
*/
|
|
18
18
|
import type { ExpressionValue } from './ast.js';
|
|
19
|
+
import type { CountCallState, RoseCallState, StatefulExpressionMemory } from './expression-source.js';
|
|
19
20
|
/** Optional runtime hooks the evaluator threads through to builtins. */
|
|
20
21
|
export interface ExpressionEvalHooks {
|
|
21
22
|
/** Convert `value` from unit `from` to unit `to`; `null` when the pair is
|
|
@@ -40,6 +41,14 @@ export interface ExpressionBuiltin {
|
|
|
40
41
|
readonly maxArgs: number;
|
|
41
42
|
readonly apply: (args: readonly ExpressionValue[], hooks: ExpressionEvalHooks) => ExpressionValue;
|
|
42
43
|
}
|
|
44
|
+
export type StatefulExpressionBuiltin = 'rose' | 'count';
|
|
45
|
+
export declare function isStatefulBuiltin(name: string): name is StatefulExpressionBuiltin;
|
|
46
|
+
export declare function evaluateRose(level: unknown, changedAt: unknown, debounceMs: unknown, call: RoseCallState, field: StatefulExpressionMemory, env: {
|
|
47
|
+
readonly currentOutput: number | null;
|
|
48
|
+
readonly startedAtMs: number;
|
|
49
|
+
readonly nowMs: number;
|
|
50
|
+
}): number | null;
|
|
51
|
+
export declare function evaluateCount(input: unknown, call: CountCallState, currentOutput: unknown): number;
|
|
43
52
|
/** Frozen, null-prototype builtin table. */
|
|
44
53
|
export declare const EXPRESSION_BUILTINS: Readonly<Record<string, ExpressionBuiltin>>;
|
|
45
54
|
/** The set of valid builtin names — used by the parser to reject unknown
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { type ExpressionEvalHooks } from './builtins.js';
|
|
2
|
-
import type { ExpressionNode, ExpressionValue } from './ast.js';
|
|
1
|
+
import { type ExpressionEvalHooks, type StatefulExpressionBuiltin } from './builtins.js';
|
|
2
|
+
import type { ExpressionNode, ExpressionNodePath, ExpressionValue } from './ast.js';
|
|
3
|
+
export interface StatefulCallInvocation {
|
|
4
|
+
readonly name: StatefulExpressionBuiltin;
|
|
5
|
+
readonly path: ExpressionNodePath;
|
|
6
|
+
readonly args: readonly ExpressionValue[];
|
|
7
|
+
}
|
|
3
8
|
export interface ExpressionEvalOptions {
|
|
4
9
|
readonly hooks?: ExpressionEvalHooks;
|
|
5
10
|
readonly maxSteps?: number;
|
|
11
|
+
readonly invokeStateful?: (call: StatefulCallInvocation) => ExpressionValue;
|
|
6
12
|
}
|
|
7
13
|
/** Build a null-prototype scope from own-enumerable binding entries. Inherited
|
|
8
14
|
* keys of the input (e.g. from a `{__proto__: {...}}` payload) are NOT copied,
|
|
@@ -9,7 +9,28 @@
|
|
|
9
9
|
* positions (derive a value, gate a trigger, compute an argument).
|
|
10
10
|
*/
|
|
11
11
|
import type { ExpressionValue } from './ast.js';
|
|
12
|
-
import { type ExpressionEvalOptions } from './evaluator.js';
|
|
12
|
+
import { type ExpressionEvalOptions, type StatefulCallInvocation } from './evaluator.js';
|
|
13
|
+
export interface RoseCallState {
|
|
14
|
+
readonly kind: 'rose';
|
|
15
|
+
priorLevel?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface CountCallState {
|
|
18
|
+
readonly kind: 'count';
|
|
19
|
+
highWater: number | null;
|
|
20
|
+
}
|
|
21
|
+
export type StatefulCallState = RoseCallState | CountCallState;
|
|
22
|
+
export interface StatefulExpressionMemory {
|
|
23
|
+
readonly calls: Map<string, StatefulCallState>;
|
|
24
|
+
acceptedEdgeAt: number | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function createStatefulExpressionMemory(): StatefulExpressionMemory;
|
|
27
|
+
export declare function cloneStatefulExpressionMemory(memory: StatefulExpressionMemory): StatefulExpressionMemory;
|
|
28
|
+
export interface StatefulExpressionEnvironment {
|
|
29
|
+
readonly currentOutput: unknown;
|
|
30
|
+
readonly startedAtMs: number;
|
|
31
|
+
readonly nowMs: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function evaluateStatefulExpressionCall(invocation: StatefulCallInvocation, memory: StatefulExpressionMemory, env: StatefulExpressionEnvironment): ExpressionValue;
|
|
13
34
|
/** The `now` epoch-ms binding is auto-injected into every evaluation and is a
|
|
14
35
|
* reserved binding name (authors may not rebind it). */
|
|
15
36
|
export declare const EXPRESSION_INJECTED_NOW = "now";
|
|
@@ -46,8 +67,9 @@ export type EvaluateExpressionSourceResult = {
|
|
|
46
67
|
/**
|
|
47
68
|
* Shared read-path evaluation. Builds a null-proto scope from `bindingValues`
|
|
48
69
|
* plus the injected `now` (supplied by the caller for determinism and
|
|
49
|
-
* testability), compiles via the LRU, and evaluates.
|
|
50
|
-
*
|
|
51
|
-
*
|
|
70
|
+
* testability), compiles via the LRU, and evaluates. Stateful calls are
|
|
71
|
+
* delegated through `opts.invokeStateful` with their stable AST path. Any
|
|
72
|
+
* failure (parse or eval) returns `{ ok: false }` — the caller treats that as
|
|
73
|
+
* "skip this derivation", never as a throw that takes the pass down.
|
|
52
74
|
*/
|
|
53
75
|
export declare function evaluateExpressionSource(expr: string, bindingValues: Readonly<Record<string, ExpressionValue>>, now: number, opts?: ExpressionEvalOptions): EvaluateExpressionSourceResult;
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
* the deep modules (e.g. `../expression/compile.js`), never through this file
|
|
10
10
|
* OR the root barrel (see biome-plugins/no-types-barrel-leaf-import.grit).
|
|
11
11
|
*/
|
|
12
|
-
export type { ExpressionBinaryNode, ExpressionBinaryOperator, ExpressionCallNode, ExpressionConditionalNode, ExpressionIdentifierNode, ExpressionLiteralNode, ExpressionLogicalNode, ExpressionLogicalOperator, ExpressionNode, ExpressionUnaryNode, ExpressionUnaryOperator, ExpressionValue, } from './ast.js';
|
|
12
|
+
export type { ExpressionBinaryNode, ExpressionBinaryOperator, ExpressionCallNode, ExpressionConditionalNode, ExpressionIdentifierNode, ExpressionLiteralNode, ExpressionLogicalNode, ExpressionLogicalOperator, ExpressionNode, ExpressionNodePath, ExpressionUnaryNode, ExpressionUnaryOperator, ExpressionValue, } from './ast.js';
|
|
13
13
|
export type { ExpressionBindingSource, ExpressionFieldBinding, ExpressionGlobalBinding, ExpressionLiteralBinding, ExpressionSource, } from './binding-source.js';
|
|
14
14
|
export { ExpressionBindingSourceSchema, ExpressionFieldBindingSchema, ExpressionGlobalBindingSchema, ExpressionLiteralBindingSchema, ExpressionSourceSchema, } from './binding-source.js';
|
|
15
|
-
export type { ExpressionBuiltin, ExpressionEvalHooks } from './builtins.js';
|
|
16
|
-
export { EXPRESSION_BUILTIN_NAMES, EXPRESSION_BUILTINS, } from './builtins.js';
|
|
15
|
+
export type { ExpressionBuiltin, ExpressionEvalHooks, StatefulExpressionBuiltin, } from './builtins.js';
|
|
16
|
+
export { evaluateCount, evaluateRose, EXPRESSION_BUILTIN_NAMES, EXPRESSION_BUILTINS, isStatefulBuiltin, } from './builtins.js';
|
|
17
17
|
export type { CompileResult } from './compile.js';
|
|
18
18
|
export { compileExpression, compileExpressionSafe } from './compile.js';
|
|
19
19
|
export { ExpressionEvalError, ExpressionParseError } from './errors.js';
|
|
20
|
-
export type { ExpressionEvalOptions } from './evaluator.js';
|
|
20
|
+
export type { ExpressionEvalOptions, StatefulCallInvocation } from './evaluator.js';
|
|
21
21
|
export { createExpressionScope, evaluateAst } from './evaluator.js';
|
|
22
|
-
export type { EvaluateExpressionSourceResult, ExpressionSourceInput, } from './expression-source.js';
|
|
23
|
-
export { EXPRESSION_INJECTED_NOW, evaluateExpressionSource, toExpressionValue, validateExpressionSource, } from './expression-source.js';
|
|
22
|
+
export type { CountCallState, EvaluateExpressionSourceResult, ExpressionSourceInput, RoseCallState, StatefulCallState, StatefulExpressionEnvironment, StatefulExpressionMemory, } from './expression-source.js';
|
|
23
|
+
export { cloneStatefulExpressionMemory, createStatefulExpressionMemory, EXPRESSION_INJECTED_NOW, evaluateExpressionSource, evaluateStatefulExpressionCall, toExpressionValue, validateExpressionSource, } from './expression-source.js';
|
|
24
24
|
export { EXPRESSION_COMPILE_CACHE_CAPACITY, EXPRESSION_IDENTIFIER_RE, MAX_EXPRESSION_AST_NODES, MAX_EXPRESSION_BINDINGS, MAX_EXPRESSION_CALL_ARGS, MAX_EXPRESSION_EVAL_STEPS, MAX_EXPRESSION_SOURCE_LENGTH, RESERVED_BINDING_NAMES, } from './limits.js';
|
|
25
25
|
export type { ParsedExpression } from './parser.js';
|
|
26
26
|
export { parseExpression } from './parser.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -150,7 +150,7 @@ export { COCO_80_LABELS, COCO_TO_MACRO, DETECTION_MACRO_CLASSES, isDetectionMacr
|
|
|
150
150
|
export { DEVICE_STATE_READERS, readDeviceStateFrom, stateVocabularyFor, } from './catalogs/device-state-vocabulary.js';
|
|
151
151
|
export { colorForKind, DEFAULT_EVENT_COLOR, EVENT_TAXONOMY, type EventTaxonomyCategory, type EventTaxonomyEntry, type EventTaxonomyLevel, getTaxonomyEntry, subKindsOf, TAXONOMY_COLORS, } from './catalogs/event-taxonomy.js';
|
|
152
152
|
export { buildNcTaxonomy, NC_TAXONOMY, type NcTaxonomy, type NcTaxonomyEntry, NcTaxonomyEntrySchema, NcTaxonomySchema, } from './catalogs/nc-taxonomy.js';
|
|
153
|
-
export { DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, evaluateSensorEdge, isSourceCap, type SensorEdgeIgnoreReason, type SensorEdgeInput, type SensorEdgeVerdict, SOURCE_CAP_ACTIVE_FIELD, SOURCE_CAP_CHANGED_AT_FIELD, SOURCE_CAPS, SOURCE_DEVICE_TYPES, sliceActiveValue, sliceChangedAt, } from './catalogs/sensor-active-state.js';
|
|
153
|
+
export { DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, evaluateSensorEdge, evaluateSensorLevelEdge, isSourceCap, type SensorEdgeIgnoreReason, type SensorEdgeInput, type SensorEdgeVerdict, type SensorLevelEdgeInput, type SensorLevelEdgeVerdict, SOURCE_CAP_ACTIVE_FIELD, SOURCE_CAP_CHANGED_AT_FIELD, SOURCE_CAPS, SOURCE_DEVICE_TYPES, sliceActiveValue, sliceChangedAt, } from './catalogs/sensor-active-state.js';
|
|
154
154
|
export * from './constants.js';
|
|
155
155
|
export type { AccessoryKindValue } from './device/accessory.js';
|
|
156
156
|
export { ACCESSORY_LABEL, AccessoryKind, accessoryStableId, } from './device/accessory.js';
|
|
@@ -201,8 +201,8 @@ export type { DeviceConfigEntry } from './device/zod-to-config-ui.js';
|
|
|
201
201
|
export { zodEntriesToConfigUI } from './device/zod-to-config-ui.js';
|
|
202
202
|
export { EventCategory, isOwnerOnlyEventCategory, OWNER_ONLY_EVENT_CATEGORIES, publicEventCategories, } from './enums/event-category.js';
|
|
203
203
|
export * from './enums/index.js';
|
|
204
|
-
export type { CompileResult, EvaluateExpressionSourceResult, ExpressionBinaryOperator, ExpressionBindingSource, ExpressionBuiltin, ExpressionEvalHooks, ExpressionEvalOptions, ExpressionFieldBinding, ExpressionGlobalBinding, ExpressionLiteralBinding, ExpressionLogicalOperator, ExpressionNode, ExpressionSource, ExpressionSourceInput, ExpressionUnaryOperator, ExpressionValue, Keyword, ParsedExpression, Punctuator, Token, } from './expression/index.js';
|
|
205
|
-
export { compileExpression, compileExpressionSafe, createExpressionScope, EXPRESSION_BUILTIN_NAMES, EXPRESSION_BUILTINS, EXPRESSION_COMPILE_CACHE_CAPACITY, EXPRESSION_IDENTIFIER_RE, EXPRESSION_INJECTED_NOW, ExpressionBindingSourceSchema, ExpressionEvalError, ExpressionFieldBindingSchema, ExpressionGlobalBindingSchema, ExpressionLiteralBindingSchema, ExpressionParseError, ExpressionSourceSchema, evaluateAst, evaluateExpressionSource, MAX_EXPRESSION_AST_NODES, MAX_EXPRESSION_BINDINGS, MAX_EXPRESSION_CALL_ARGS, MAX_EXPRESSION_EVAL_STEPS, MAX_EXPRESSION_SOURCE_LENGTH, parseExpression, RESERVED_BINDING_NAMES, toExpressionValue, tokenize, validateExpressionSource, } from './expression/index.js';
|
|
204
|
+
export type { CompileResult, EvaluateExpressionSourceResult, ExpressionBinaryOperator, ExpressionBindingSource, ExpressionBuiltin, ExpressionEvalHooks, ExpressionEvalOptions, ExpressionFieldBinding, ExpressionGlobalBinding, ExpressionLiteralBinding, ExpressionLogicalOperator, ExpressionNode, ExpressionNodePath, ExpressionSource, ExpressionSourceInput, ExpressionUnaryOperator, ExpressionValue, CountCallState, RoseCallState, StatefulCallState, StatefulCallInvocation, StatefulExpressionEnvironment, StatefulExpressionMemory, StatefulExpressionBuiltin, Keyword, ParsedExpression, Punctuator, Token, } from './expression/index.js';
|
|
205
|
+
export { compileExpression, compileExpressionSafe, cloneStatefulExpressionMemory, createExpressionScope, createStatefulExpressionMemory, EXPRESSION_BUILTIN_NAMES, EXPRESSION_BUILTINS, EXPRESSION_COMPILE_CACHE_CAPACITY, EXPRESSION_IDENTIFIER_RE, EXPRESSION_INJECTED_NOW, ExpressionBindingSourceSchema, ExpressionEvalError, ExpressionFieldBindingSchema, ExpressionGlobalBindingSchema, ExpressionLiteralBindingSchema, ExpressionParseError, ExpressionSourceSchema, evaluateAst, evaluateCount, evaluateExpressionSource, evaluateRose, evaluateStatefulExpressionCall, isStatefulBuiltin, MAX_EXPRESSION_AST_NODES, MAX_EXPRESSION_BINDINGS, MAX_EXPRESSION_CALL_ARGS, MAX_EXPRESSION_EVAL_STEPS, MAX_EXPRESSION_SOURCE_LENGTH, parseExpression, RESERVED_BINDING_NAMES, toExpressionValue, tokenize, validateExpressionSource, } from './expression/index.js';
|
|
206
206
|
export type { AddonApi, AppRouter } from './generated/addon-api.js';
|
|
207
207
|
export type { CapNameWithStatus, CapStatusTypeMap } from './generated/cap-status-types.js';
|
|
208
208
|
export { CAP_NAMES_WITH_STATUS } from './generated/cap-status-types.js';
|