@mark1russell7/coeval 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/build/index.d.ts +330 -224
- package/build/index.d.ts.map +1 -1
- package/build/index.js +361 -91
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/deref.ts +10 -6
- package/src/evaluate.ts +80 -4
- package/src/formula.ts +91 -19
- package/src/index.ts +3 -0
- package/src/parts.ts +42 -5
- package/src/static.ts +182 -48
- package/src/stdlib.ts +6 -2
- package/src/world.ts +39 -3
package/build/index.js
CHANGED
|
@@ -450,6 +450,9 @@ function entriesAsJson(entries) {
|
|
|
450
450
|
}
|
|
451
451
|
function describeShape(shape) {
|
|
452
452
|
if (shape === void 0 || shape.shape === "none") return "none";
|
|
453
|
+
if (shape.shape === "text") return "a text";
|
|
454
|
+
if (shape.shape === "number") return "a number";
|
|
455
|
+
if (shape.shape === "one") return `one of ${JSON.stringify(shape.values)}`;
|
|
453
456
|
if (shape.shape === "term") return `a part${shape.of === void 0 ? "" : ` of ${shape.of}`}`;
|
|
454
457
|
if (shape.shape === "deep") return "each document in the value";
|
|
455
458
|
if (shape.shape === "list") return `a list${shape.of === void 0 ? "" : ` of ${shape.of}`}`;
|
|
@@ -940,7 +943,7 @@ function resolve(nav, ctx, path, options = {}) {
|
|
|
940
943
|
return reached === void 0 ? void 0 : adopt(reached.thing);
|
|
941
944
|
}
|
|
942
945
|
});
|
|
943
|
-
if (!result.ok) return failed("#N/A", result.reason);
|
|
946
|
+
if (!result.ok) return failed(result.code ?? "#N/A", result.reason);
|
|
944
947
|
here = adopt(result.thing);
|
|
945
948
|
hops?.push({
|
|
946
949
|
step: envelope,
|
|
@@ -1033,6 +1036,22 @@ const NO_SLOTS = Object.freeze([]);
|
|
|
1033
1036
|
function hasSlots(template) {
|
|
1034
1037
|
return template.t !== "data";
|
|
1035
1038
|
}
|
|
1039
|
+
/** This function gives the reason why a value is not data of a shape, or `undefined` when it is. */
|
|
1040
|
+
function dataFault(spec, item) {
|
|
1041
|
+
if (spec.shape === "text") return typeof item === "string" ? void 0 : "The value must be a text.";
|
|
1042
|
+
if (spec.shape === "one") return spec.values.some((value) => docEquals(value, item)) ? void 0 : `The value must be one of ${JSON.stringify(spec.values)}.`;
|
|
1043
|
+
if (typeof item !== "number") return "The value must be a number.";
|
|
1044
|
+
if (spec.whole === true && !Number.isInteger(item)) return "The value must be a whole number.";
|
|
1045
|
+
if (spec.min !== void 0 && !(item >= spec.min)) return `The value must be ${String(spec.min)} or more.`;
|
|
1046
|
+
if (spec.max !== void 0 && !(item <= spec.max)) return `The value must be ${String(spec.max)} or less.`;
|
|
1047
|
+
}
|
|
1048
|
+
/** This function stops a split when a part has a type that its position does not permit. */
|
|
1049
|
+
function kindFault(kinds, item, of, path) {
|
|
1050
|
+
const type = isEnvelope(item) ? typePath(item.type) : of === void 0 ? void 0 : [of];
|
|
1051
|
+
if (type !== void 0 && kinds.some((kind) => kind.length <= type.length && kind.every((key, index) => String(key) === String(type[index])))) return;
|
|
1052
|
+
const names = kinds.map((kind) => kind.join(".")).join(", ");
|
|
1053
|
+
throw new Bad(`${isEnvelope(item) ? `The kind ${typeName(item.type)} is not permitted here.` : "A value without an envelope is not permitted here."} The permitted kinds are ${names}.`, path);
|
|
1054
|
+
}
|
|
1036
1055
|
/**
|
|
1037
1056
|
* This function splits a value into its parts, by the shape that its kind declares. The evaluator, the view and
|
|
1038
1057
|
* the static kit use the same split, thus each one sees the same parts.
|
|
@@ -1049,12 +1068,13 @@ function splitParts(shape, value) {
|
|
|
1049
1068
|
fill: () => value
|
|
1050
1069
|
};
|
|
1051
1070
|
const parts = [];
|
|
1052
|
-
const slot = (item, path, of) => {
|
|
1071
|
+
const slot = (item, path, of, address = false) => {
|
|
1053
1072
|
parts.push({
|
|
1054
1073
|
path,
|
|
1055
1074
|
key: path.join("."),
|
|
1056
1075
|
item,
|
|
1057
|
-
...of === void 0 ? {} : { of }
|
|
1076
|
+
...of === void 0 ? {} : { of },
|
|
1077
|
+
...address ? { address: true } : {}
|
|
1058
1078
|
});
|
|
1059
1079
|
return {
|
|
1060
1080
|
t: "slot",
|
|
@@ -1093,17 +1113,33 @@ function splitParts(shape, value) {
|
|
|
1093
1113
|
t: "data",
|
|
1094
1114
|
value: item
|
|
1095
1115
|
};
|
|
1096
|
-
if (spec.shape === "
|
|
1116
|
+
if (spec.shape === "text" || spec.shape === "number" || spec.shape === "one") {
|
|
1117
|
+
const reason = dataFault(spec, item);
|
|
1118
|
+
if (reason !== void 0) throw new Bad(reason, path);
|
|
1119
|
+
return {
|
|
1120
|
+
t: "data",
|
|
1121
|
+
value: item
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
if (spec.shape === "term") {
|
|
1125
|
+
if (spec.kinds !== void 0) kindFault(spec.kinds, item, spec.of, path);
|
|
1126
|
+
return slot(item, path, spec.of, spec.address === true);
|
|
1127
|
+
}
|
|
1097
1128
|
if (spec.shape === "deep") return deep(item, path, spec.of);
|
|
1098
1129
|
if (spec.shape === "list") {
|
|
1099
1130
|
if (!Array.isArray(item)) throw new Bad("The value must be a list.", path);
|
|
1131
|
+
const list = item;
|
|
1132
|
+
if (spec.distinct === true) {
|
|
1133
|
+
const twice = list.findIndex((child, index) => list.slice(0, index).some((before) => docEquals(before, child)));
|
|
1134
|
+
if (twice !== -1) throw new Bad("The items of the list must be different.", [...path, twice]);
|
|
1135
|
+
}
|
|
1100
1136
|
const each = spec.item ?? {
|
|
1101
1137
|
shape: "term",
|
|
1102
1138
|
...spec.of === void 0 ? {} : { of: spec.of }
|
|
1103
1139
|
};
|
|
1104
1140
|
return {
|
|
1105
1141
|
t: "list",
|
|
1106
|
-
items:
|
|
1142
|
+
items: list.map((child, index) => walk(each, child, [...path, index]))
|
|
1107
1143
|
};
|
|
1108
1144
|
}
|
|
1109
1145
|
if (!isRecord(item)) throw new Bad("The value must be a record.", path);
|
|
@@ -1124,6 +1160,7 @@ function splitParts(shape, value) {
|
|
|
1124
1160
|
}])) : spec.fields;
|
|
1125
1161
|
const fields = [];
|
|
1126
1162
|
for (const key of Object.keys(item)) {
|
|
1163
|
+
if (spec.closed === true && !Object.hasOwn(named, key)) throw new Bad(`The field ${key} is not a field of this kind.`, [...path, key]);
|
|
1127
1164
|
const fieldShape = Object.hasOwn(named, key) ? named[key] : spec.rest;
|
|
1128
1165
|
fields.push([key, walk(fieldShape, item[key], [...path, key])]);
|
|
1129
1166
|
}
|
|
@@ -1244,6 +1281,52 @@ function narrow(parent, next) {
|
|
|
1244
1281
|
caps
|
|
1245
1282
|
};
|
|
1246
1283
|
}
|
|
1284
|
+
/** No capabilities. One list serves each masked part. */
|
|
1285
|
+
const NO_CAPS = Object.freeze([]);
|
|
1286
|
+
/** No capability rules. One list serves each part that no rule narrows. */
|
|
1287
|
+
const NO_RULES = Object.freeze([]);
|
|
1288
|
+
/**
|
|
1289
|
+
* This function gives the capabilities that two lists both permit. An effect is permitted by the result when each
|
|
1290
|
+
* list permits it. When the list `b` permits each capability of `a`, the result is the list `a` itself.
|
|
1291
|
+
*
|
|
1292
|
+
* @param a - The first list, for example the capabilities of a document.
|
|
1293
|
+
* @param b - The second list, for example the list of a rule `only`.
|
|
1294
|
+
* @returns The capabilities that both lists permit.
|
|
1295
|
+
*/
|
|
1296
|
+
function intersectCaps(a, b) {
|
|
1297
|
+
if (a.every((cap) => permits(b, cap))) return a;
|
|
1298
|
+
const out = [];
|
|
1299
|
+
for (const cap of b) if (permits(a, cap)) out.push(cap);
|
|
1300
|
+
for (const cap of a) if (permits(b, cap) && !permits(out, cap)) out.push(cap);
|
|
1301
|
+
return out;
|
|
1302
|
+
}
|
|
1303
|
+
/** This function gives the capability rules of a kind that cover a part and change its capabilities. */
|
|
1304
|
+
function rulesFor(rules, path) {
|
|
1305
|
+
if (rules === void 0 || rules.length === 0) return NO_RULES;
|
|
1306
|
+
const out = rules.filter((rule) => rule.rule !== "same" && (rule.in === void 0 || rule.in.some((pattern) => pathMatches(path, pattern))));
|
|
1307
|
+
return out.length === 0 ? NO_RULES : out;
|
|
1308
|
+
}
|
|
1309
|
+
/** This function applies the rules that cover a part to the capabilities of its document. */
|
|
1310
|
+
function capsUnder(rules, caps) {
|
|
1311
|
+
let out = caps;
|
|
1312
|
+
for (const rule of rules) {
|
|
1313
|
+
if (rule.rule === "mask") return NO_CAPS;
|
|
1314
|
+
if (rule.rule === "only") out = intersectCaps(out, rule.caps);
|
|
1315
|
+
}
|
|
1316
|
+
return out;
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* This function gives the capabilities that a kind gives one of its parts, by the capability rules of its contract.
|
|
1320
|
+
* The kernel and the static kit both use it, thus a run and a check narrow the same way.
|
|
1321
|
+
*
|
|
1322
|
+
* @param rules - The capability rules of the kind (`Kind.caps`).
|
|
1323
|
+
* @param path - The path of the part in the value of the document.
|
|
1324
|
+
* @param caps - The capabilities of the document.
|
|
1325
|
+
* @returns The capabilities of the part: the same list or a smaller one.
|
|
1326
|
+
*/
|
|
1327
|
+
function partCaps(rules, path, caps) {
|
|
1328
|
+
return capsUnder(rulesFor(rules, path), caps);
|
|
1329
|
+
}
|
|
1247
1330
|
function selfLabel(self) {
|
|
1248
1331
|
try {
|
|
1249
1332
|
if (isHostThing(self)) return self.label;
|
|
@@ -1591,7 +1674,7 @@ const NO_META = Object.freeze({
|
|
|
1591
1674
|
answer: NO_ANSWER,
|
|
1592
1675
|
side: "derive"
|
|
1593
1676
|
});
|
|
1594
|
-
function compileNode(c, value, place, declared, depth) {
|
|
1677
|
+
function compileNode(c, value, place, declared, depth, address = false) {
|
|
1595
1678
|
const envelope = isEnvelope(value) ? value : void 0;
|
|
1596
1679
|
const doc = envelope ?? {
|
|
1597
1680
|
type: declared ?? "?",
|
|
@@ -1639,7 +1722,9 @@ function compileNode(c, value, place, declared, depth) {
|
|
|
1639
1722
|
}
|
|
1640
1723
|
const parts = split.parts.map((slot) => {
|
|
1641
1724
|
const item = slot.item;
|
|
1642
|
-
const
|
|
1725
|
+
const own = compileNode(c, item, place.concat(slot.path), slot.of, depth + 1, slot.address === true);
|
|
1726
|
+
const rules = rulesFor(kind?.caps, slot.path);
|
|
1727
|
+
const compiled = rules.length === 0 ? own : gated(rules, own);
|
|
1643
1728
|
const header = typeof item?.name === "string" && isEnvelope(item) ? item.name : void 0;
|
|
1644
1729
|
return header === void 0 ? {
|
|
1645
1730
|
key: slot.key,
|
|
@@ -1663,7 +1748,8 @@ function compileNode(c, value, place, declared, depth) {
|
|
|
1663
1748
|
parts,
|
|
1664
1749
|
place,
|
|
1665
1750
|
machine: c.machine,
|
|
1666
|
-
fill: fillOf(split, doc)
|
|
1751
|
+
fill: fillOf(split, doc),
|
|
1752
|
+
...address ? { address: true } : {}
|
|
1667
1753
|
};
|
|
1668
1754
|
if (runner !== void 0) {
|
|
1669
1755
|
const run = placedRun(isCompiledRunner(runner) ? runner.compileRun(input) : interpretRun(runner, input, split.fill), place, name);
|
|
@@ -1682,6 +1768,25 @@ function placedCode(inner, place, name) {
|
|
|
1682
1768
|
}
|
|
1683
1769
|
};
|
|
1684
1770
|
}
|
|
1771
|
+
/**
|
|
1772
|
+
* This function gives the code of a part that capability rules cover. The code narrows the context of the part by
|
|
1773
|
+
* the rules before the part starts.
|
|
1774
|
+
*/
|
|
1775
|
+
function gated(rules, part) {
|
|
1776
|
+
const inner = part.code;
|
|
1777
|
+
const steps = part.run;
|
|
1778
|
+
const under = (ctx) => {
|
|
1779
|
+
const caps = capsUnder(rules, ctx.caps);
|
|
1780
|
+
return caps === ctx.caps || caps.length === 0 && ctx.caps.length === 0 ? ctx : {
|
|
1781
|
+
...ctx,
|
|
1782
|
+
caps
|
|
1783
|
+
};
|
|
1784
|
+
};
|
|
1785
|
+
return {
|
|
1786
|
+
code: (ctx, rt) => inner(under(ctx), rt),
|
|
1787
|
+
run: (ctx, rt) => steps(under(ctx), rt)
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1685
1790
|
/** This function gives the steps of a runner, with the place of each error and of each exception. */
|
|
1686
1791
|
function placedRun(inner, place, name) {
|
|
1687
1792
|
return function* (ctx, rt) {
|
|
@@ -1708,6 +1813,7 @@ function fillOf(split, doc) {
|
|
|
1708
1813
|
}
|
|
1709
1814
|
function interpret(fn, input, fill) {
|
|
1710
1815
|
const { kind, typePath, doc, data, place } = input;
|
|
1816
|
+
const address = input.address === true ? { address: true } : {};
|
|
1711
1817
|
const compiled = input.parts;
|
|
1712
1818
|
const hasParts = compiled.length > 0;
|
|
1713
1819
|
return (ctx, rt) => {
|
|
@@ -1726,6 +1832,7 @@ function interpret(fn, input, fill) {
|
|
|
1726
1832
|
parts,
|
|
1727
1833
|
context: ctx,
|
|
1728
1834
|
place,
|
|
1835
|
+
...address,
|
|
1729
1836
|
resolve: (path, options) => rt.resolve(ctx, path, options),
|
|
1730
1837
|
effect: (effectKind, payload) => rt.effect(ctx, effectKind, payload, place),
|
|
1731
1838
|
fill: input.fill
|
|
@@ -2106,6 +2213,7 @@ const STD_WORLD = {
|
|
|
2106
2213
|
view: "view.op"
|
|
2107
2214
|
},
|
|
2108
2215
|
parts: { shape: "list" },
|
|
2216
|
+
caps: [{ rule: "mask" }],
|
|
2109
2217
|
summary: "It evaluates its part without capabilities, thus an effect in it fails."
|
|
2110
2218
|
},
|
|
2111
2219
|
log: {
|
|
@@ -2118,6 +2226,7 @@ const STD_WORLD = {
|
|
|
2118
2226
|
of: "text"
|
|
2119
2227
|
},
|
|
2120
2228
|
side: "run",
|
|
2229
|
+
effects: ["log"],
|
|
2121
2230
|
summary: "It writes the result of its part to the log. This is an effect."
|
|
2122
2231
|
},
|
|
2123
2232
|
write: {
|
|
@@ -2130,6 +2239,7 @@ const STD_WORLD = {
|
|
|
2130
2239
|
fields: ["value"]
|
|
2131
2240
|
},
|
|
2132
2241
|
side: "run",
|
|
2242
|
+
effects: ["write"],
|
|
2133
2243
|
summary: "It writes the result of its part to the store, at its key. This is an effect."
|
|
2134
2244
|
}
|
|
2135
2245
|
},
|
|
@@ -2307,13 +2417,10 @@ const STD_RUNNERS = {
|
|
|
2307
2417
|
}
|
|
2308
2418
|
return ok(last);
|
|
2309
2419
|
},
|
|
2310
|
-
"control.pure": function* ({ parts
|
|
2420
|
+
"control.pure": function* ({ parts }) {
|
|
2311
2421
|
const only = parts[0];
|
|
2312
2422
|
if (only === void 0) return fail("#VALUE!", "pure needs one part.");
|
|
2313
|
-
return yield* only.evaluate(
|
|
2314
|
-
...context,
|
|
2315
|
-
caps: []
|
|
2316
|
-
});
|
|
2423
|
+
return yield* only.evaluate();
|
|
2317
2424
|
},
|
|
2318
2425
|
"control.if": function* ({ parts }) {
|
|
2319
2426
|
const test = parts.find((part) => part.key === "test");
|
|
@@ -2811,34 +2918,91 @@ function withoutNames(options) {
|
|
|
2811
2918
|
const { names: _host, ...rest } = options;
|
|
2812
2919
|
return rest;
|
|
2813
2920
|
}
|
|
2921
|
+
/** This function gives the keys of a trail, from its start. It keeps the result in the trail. */
|
|
2922
|
+
function keysOf(trail) {
|
|
2923
|
+
if (trail === void 0) return [];
|
|
2924
|
+
if (trail.full !== void 0) return trail.full;
|
|
2925
|
+
const steps = [];
|
|
2926
|
+
let here = trail;
|
|
2927
|
+
while (here !== void 0 && here.full === void 0) {
|
|
2928
|
+
steps.push(here);
|
|
2929
|
+
here = here.up;
|
|
2930
|
+
}
|
|
2931
|
+
const keys = here?.full === void 0 ? [] : [...here.full];
|
|
2932
|
+
for (let index = steps.length - 1; index >= 0; index -= 1) for (const key of steps[index].keys) keys.push(key);
|
|
2933
|
+
trail.full = keys;
|
|
2934
|
+
return keys;
|
|
2935
|
+
}
|
|
2936
|
+
/** A visit with its paths as trails. It makes the keys of a path only when a reader asks for them. */
|
|
2937
|
+
var Visit = class {
|
|
2938
|
+
doc;
|
|
2939
|
+
declared;
|
|
2940
|
+
depth;
|
|
2941
|
+
names;
|
|
2942
|
+
later;
|
|
2943
|
+
slot;
|
|
2944
|
+
parent;
|
|
2945
|
+
kind;
|
|
2946
|
+
typePath;
|
|
2947
|
+
address;
|
|
2948
|
+
caps;
|
|
2949
|
+
#place;
|
|
2950
|
+
#at;
|
|
2951
|
+
constructor(place, at, doc, declared, depth, names, later, slot, parent, kind, typePath, address, caps) {
|
|
2952
|
+
this.doc = doc;
|
|
2953
|
+
this.declared = declared;
|
|
2954
|
+
this.depth = depth;
|
|
2955
|
+
this.names = names;
|
|
2956
|
+
this.later = later;
|
|
2957
|
+
this.slot = slot;
|
|
2958
|
+
this.parent = parent;
|
|
2959
|
+
this.kind = kind;
|
|
2960
|
+
this.typePath = typePath;
|
|
2961
|
+
this.address = address;
|
|
2962
|
+
this.caps = caps;
|
|
2963
|
+
this.#place = place;
|
|
2964
|
+
this.#at = at;
|
|
2965
|
+
}
|
|
2966
|
+
get place() {
|
|
2967
|
+
return keysOf(this.#place);
|
|
2968
|
+
}
|
|
2969
|
+
get at() {
|
|
2970
|
+
return keysOf(this.#at);
|
|
2971
|
+
}
|
|
2972
|
+
};
|
|
2814
2973
|
/**
|
|
2815
2974
|
* This function visits each document of a document: the root and each part at each depth, by the contracts of the
|
|
2816
|
-
* kinds. A part of a kind that the world does not have is not visited.
|
|
2817
|
-
*
|
|
2975
|
+
* kinds. A part of a kind that the world does not have is not visited. With capabilities in the options, the walk
|
|
2976
|
+
* narrows them for each part by the rules of its kind, as a run does. The walk uses no stack of the host for the
|
|
2977
|
+
* depth, thus a deep document cannot overflow it. The time and the memory of a walk are linear in the size of the
|
|
2978
|
+
* document. A visit makes the keys of its place and of its path only when a reader asks for them.
|
|
2818
2979
|
*
|
|
2819
2980
|
* @param world - The world of the kinds.
|
|
2820
2981
|
* @param doc - The document, as JSON.
|
|
2821
2982
|
* @param visit - The function that gets each document. It gives `"skip"` to not visit the parts of a document.
|
|
2822
|
-
* @param options - The type of a bare root value, the names
|
|
2983
|
+
* @param options - The type of a bare root value, the names, the capabilities and a function for the problems.
|
|
2823
2984
|
*/
|
|
2824
2985
|
function walk(world, doc, visit, options = {}) {
|
|
2825
|
-
const names = options.names === void 0 || options.names.length === 0 ? NO_NAMES : new Set(options.names);
|
|
2826
2986
|
const stack = [{
|
|
2827
2987
|
value: doc,
|
|
2828
|
-
place:
|
|
2829
|
-
at:
|
|
2988
|
+
place: void 0,
|
|
2989
|
+
at: void 0,
|
|
2830
2990
|
declared: options.declaredType,
|
|
2831
2991
|
depth: 0,
|
|
2832
|
-
names,
|
|
2833
|
-
later: NO_NAMES
|
|
2992
|
+
names: options.names === void 0 || options.names.length === 0 ? NO_NAMES : new Set(options.names),
|
|
2993
|
+
later: NO_NAMES,
|
|
2994
|
+
address: false,
|
|
2995
|
+
slot: [],
|
|
2996
|
+
parent: void 0,
|
|
2997
|
+
caps: options.caps
|
|
2834
2998
|
}];
|
|
2835
2999
|
while (stack.length > 0) {
|
|
2836
3000
|
const item = stack.pop();
|
|
2837
3001
|
const envelope = isEnvelope(item.value) ? item.value : void 0;
|
|
2838
3002
|
if (envelope === void 0 && item.declared === void 0) {
|
|
2839
3003
|
options.problem?.({
|
|
2840
|
-
place: item.place,
|
|
2841
|
-
at: item.at,
|
|
3004
|
+
place: keysOf(item.place),
|
|
3005
|
+
at: keysOf(item.at),
|
|
2842
3006
|
code: "#PART?",
|
|
2843
3007
|
reason: "The value has no envelope, and its position declares no type."
|
|
2844
3008
|
});
|
|
@@ -2850,50 +3014,50 @@ function walk(world, doc, visit, options = {}) {
|
|
|
2850
3014
|
};
|
|
2851
3015
|
const found = lookupKind(world, doc.type);
|
|
2852
3016
|
const kind = found.ok ? found.kind : void 0;
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
at: item.at,
|
|
2856
|
-
doc,
|
|
2857
|
-
declared: envelope === void 0,
|
|
2858
|
-
depth: item.depth,
|
|
2859
|
-
names: item.names,
|
|
2860
|
-
later: item.later
|
|
2861
|
-
} : {
|
|
2862
|
-
place: item.place,
|
|
2863
|
-
at: item.at,
|
|
2864
|
-
doc,
|
|
2865
|
-
declared: envelope === void 0,
|
|
2866
|
-
kind,
|
|
2867
|
-
typePath: found.ok ? found.path : [],
|
|
2868
|
-
depth: item.depth,
|
|
2869
|
-
names: item.names,
|
|
2870
|
-
later: item.later
|
|
2871
|
-
}) === "skip" || kind === void 0) continue;
|
|
3017
|
+
const here = new Visit(item.place, item.at, doc, envelope === void 0, item.depth, item.names, item.later, item.slot, item.parent, kind, found.ok ? found.path : void 0, item.address ? true : void 0, item.caps);
|
|
3018
|
+
if (visit(here) === "skip" || kind === void 0) continue;
|
|
2872
3019
|
const split = splitParts(kind.parts, doc.value);
|
|
3020
|
+
const base = envelope === void 0 ? item.at : {
|
|
3021
|
+
up: item.at,
|
|
3022
|
+
keys: ["value"]
|
|
3023
|
+
};
|
|
2873
3024
|
if (!split.ok) {
|
|
2874
3025
|
const at = split.at.length === 0 ? "" : ` (at ${split.at.join(".")})`;
|
|
3026
|
+
const where = keysOf({
|
|
3027
|
+
up: base,
|
|
3028
|
+
keys: split.at
|
|
3029
|
+
});
|
|
2875
3030
|
options.problem?.({
|
|
2876
|
-
place: item.place,
|
|
2877
|
-
at:
|
|
3031
|
+
place: keysOf(item.place),
|
|
3032
|
+
at: where,
|
|
2878
3033
|
code: "#VALUE!",
|
|
2879
3034
|
reason: `${split.reason}${at} The kind is ${typeName(doc.type)}.`
|
|
2880
3035
|
});
|
|
2881
3036
|
continue;
|
|
2882
3037
|
}
|
|
2883
3038
|
const { sees, later } = scopesOf(kind.scope, doc.value, split.parts);
|
|
2884
|
-
const base = envelope === void 0 ? item.at : [...item.at, "value"];
|
|
2885
3039
|
for (let index = split.parts.length - 1; index >= 0; index -= 1) {
|
|
2886
3040
|
const slot = split.parts[index];
|
|
2887
3041
|
const extra = sees[index] ?? [];
|
|
2888
3042
|
const hidden = later[index] ?? [];
|
|
2889
3043
|
stack.push({
|
|
2890
3044
|
value: slot.item,
|
|
2891
|
-
place:
|
|
2892
|
-
|
|
3045
|
+
place: slot.path.length === 0 ? item.place : {
|
|
3046
|
+
up: item.place,
|
|
3047
|
+
keys: slot.path
|
|
3048
|
+
},
|
|
3049
|
+
at: slot.path.length === 0 ? base : {
|
|
3050
|
+
up: base,
|
|
3051
|
+
keys: slot.path
|
|
3052
|
+
},
|
|
2893
3053
|
declared: slot.of,
|
|
2894
3054
|
depth: item.depth + 1,
|
|
2895
3055
|
names: extra.length === 0 ? item.names : /* @__PURE__ */ new Set([...item.names, ...extra]),
|
|
2896
|
-
later: hidden.length === 0 ? item.later : /* @__PURE__ */ new Set([...item.later, ...hidden])
|
|
3056
|
+
later: hidden.length === 0 ? item.later : /* @__PURE__ */ new Set([...item.later, ...hidden]),
|
|
3057
|
+
address: slot.address === true,
|
|
3058
|
+
slot: slot.path,
|
|
3059
|
+
parent: here,
|
|
3060
|
+
caps: item.caps === void 0 || kind.caps === void 0 ? item.caps : partCaps(kind.caps, slot.path, item.caps)
|
|
2897
3061
|
});
|
|
2898
3062
|
}
|
|
2899
3063
|
}
|
|
@@ -2901,7 +3065,7 @@ function walk(world, doc, visit, options = {}) {
|
|
|
2901
3065
|
/**
|
|
2902
3066
|
* This function finds each reference of a document: each document of the type `ref` that a walk reaches. A
|
|
2903
3067
|
* reference to a name that a kind around it binds is not free. The others are what the document reads from
|
|
2904
|
-
* outside: its dependencies.
|
|
3068
|
+
* outside: its dependencies. When the kind `ref` has parts, the walk also finds the references in its step documents.
|
|
2905
3069
|
*
|
|
2906
3070
|
* @param world - The world of the kinds.
|
|
2907
3071
|
* @param doc - The document, as JSON.
|
|
@@ -2915,15 +3079,25 @@ function refsOf(world, doc, options = {}) {
|
|
|
2915
3079
|
const path = v.doc.value;
|
|
2916
3080
|
const root = typeof path[0] === "string" ? path[0] : "";
|
|
2917
3081
|
const first = path[1];
|
|
2918
|
-
const
|
|
2919
|
-
out.push({
|
|
2920
|
-
place: v.place,
|
|
2921
|
-
at: v.at,
|
|
3082
|
+
const use = {
|
|
2922
3083
|
path,
|
|
2923
3084
|
root,
|
|
2924
|
-
free: !
|
|
3085
|
+
free: !(root === "names" && isKey(first) && v.names.has(String(first))),
|
|
3086
|
+
address: v.address === true
|
|
3087
|
+
};
|
|
3088
|
+
Object.defineProperty(use, "place", {
|
|
3089
|
+
enumerable: true,
|
|
3090
|
+
get: () => v.place
|
|
2925
3091
|
});
|
|
2926
|
-
|
|
3092
|
+
Object.defineProperty(use, "at", {
|
|
3093
|
+
enumerable: true,
|
|
3094
|
+
get: () => v.at
|
|
3095
|
+
});
|
|
3096
|
+
Object.defineProperty(use, "visit", {
|
|
3097
|
+
enumerable: false,
|
|
3098
|
+
value: v
|
|
3099
|
+
});
|
|
3100
|
+
out.push(use);
|
|
2927
3101
|
}, options.names === void 0 ? options : withoutNames(options));
|
|
2928
3102
|
return out;
|
|
2929
3103
|
}
|
|
@@ -2971,6 +3145,15 @@ function mapRefs(world, doc, change, options = {}) {
|
|
|
2971
3145
|
return out;
|
|
2972
3146
|
}
|
|
2973
3147
|
/**
|
|
3148
|
+
* This function gives the reason of a `#CAP!`. When a kind around the document narrowed the capabilities, the
|
|
3149
|
+
* reason names the nearest such kind.
|
|
3150
|
+
*/
|
|
3151
|
+
function capReason(v, kind) {
|
|
3152
|
+
const text = kind.join(".");
|
|
3153
|
+
for (let up = v.parent; up !== void 0; up = up.parent) if (up.caps !== void 0 && permits(up.caps, kind)) return `The capabilities do not permit the effect ${text} here. The kind ${typeName(up.doc.type)} around it narrows them for its parts.`;
|
|
3154
|
+
return `The capabilities do not permit the effect ${text}.`;
|
|
3155
|
+
}
|
|
3156
|
+
/**
|
|
2974
3157
|
* This function checks a document before an evaluation, by the contracts of its kinds. It finds the problems
|
|
2975
3158
|
* that an evaluation finds when it reaches them:
|
|
2976
3159
|
*
|
|
@@ -2981,7 +3164,7 @@ function mapRefs(world, doc, change, options = {}) {
|
|
|
2981
3164
|
* - `#DEPTH!`: too much nesting.
|
|
2982
3165
|
* - `#REF!` and `#STEP?`: a bad path.
|
|
2983
3166
|
* - `#NAME?`: a name that nothing binds.
|
|
2984
|
-
* - `#CAP!`: an effect that the capabilities do not permit.
|
|
3167
|
+
* - `#CAP!`: an effect that the capabilities of its document do not permit. A kind around the document can narrow them.
|
|
2985
3168
|
*
|
|
2986
3169
|
* @param machine - The world and the code of the evaluators.
|
|
2987
3170
|
* @param doc - The document, as JSON.
|
|
@@ -2999,7 +3182,8 @@ function check(machine, doc, options = {}) {
|
|
|
2999
3182
|
issues.push({
|
|
3000
3183
|
code: "#DEPTH!",
|
|
3001
3184
|
place: v.place,
|
|
3002
|
-
reason: `The nesting is deeper than ${maxDepth} documents
|
|
3185
|
+
reason: `The nesting is deeper than ${maxDepth} documents.`,
|
|
3186
|
+
at: v.at
|
|
3003
3187
|
});
|
|
3004
3188
|
return "skip";
|
|
3005
3189
|
}
|
|
@@ -3009,7 +3193,8 @@ function check(machine, doc, options = {}) {
|
|
|
3009
3193
|
issues.push({
|
|
3010
3194
|
code: "#KIND?",
|
|
3011
3195
|
place: v.place,
|
|
3012
|
-
reason: `The world has no kind ${typeName(v.doc.type)}
|
|
3196
|
+
reason: `The world has no kind ${typeName(v.doc.type)}.`,
|
|
3197
|
+
at: v.at
|
|
3013
3198
|
});
|
|
3014
3199
|
return "skip";
|
|
3015
3200
|
}
|
|
@@ -3017,31 +3202,48 @@ function check(machine, doc, options = {}) {
|
|
|
3017
3202
|
if (name === void 0 || !has(machine.evaluators, name) && !has(machine.runners, name)) issues.push({
|
|
3018
3203
|
code: "#NOEVAL",
|
|
3019
3204
|
place: v.place,
|
|
3020
|
-
reason: `No rung gives an evaluator for ${typeName(v.doc.type)}
|
|
3205
|
+
reason: `No rung gives an evaluator for ${typeName(v.doc.type)}.`,
|
|
3206
|
+
at: v.at
|
|
3021
3207
|
});
|
|
3022
|
-
|
|
3208
|
+
const caps = v.caps;
|
|
3209
|
+
if (caps !== void 0 && v.kind?.effects !== void 0) {
|
|
3023
3210
|
const kinds = v.kind.effects === "type" ? [v.typePath ?? []] : v.kind.effects.map((kind) => kind.split("."));
|
|
3024
|
-
for (const kind of kinds) if (!permits(
|
|
3211
|
+
for (const kind of kinds) if (!permits(caps, kind)) issues.push({
|
|
3025
3212
|
code: "#CAP!",
|
|
3026
3213
|
place: v.place,
|
|
3027
|
-
reason:
|
|
3214
|
+
reason: capReason(v, kind),
|
|
3215
|
+
at: v.at
|
|
3028
3216
|
});
|
|
3029
3217
|
}
|
|
3030
|
-
|
|
3218
|
+
const isPath = isRef(v.doc);
|
|
3219
|
+
if (!isPath && v.typePath?.length === 1 && v.typePath[0] === "ref") issues.push({
|
|
3220
|
+
code: "#VALUE!",
|
|
3221
|
+
place: v.place,
|
|
3222
|
+
reason: "The value of ref is a path: a list that starts with a root.",
|
|
3223
|
+
at: [...v.at, ...v.declared ? [] : ["value"]]
|
|
3224
|
+
});
|
|
3225
|
+
if (!isPath) return void 0;
|
|
3031
3226
|
const path = v.doc.value;
|
|
3032
3227
|
const root = path[0];
|
|
3228
|
+
const stepAt = (index) => [
|
|
3229
|
+
...v.at,
|
|
3230
|
+
"value",
|
|
3231
|
+
...index < path.length ? [index] : []
|
|
3232
|
+
];
|
|
3033
3233
|
if (typeof root !== "string" || !ROOTS.includes(root)) {
|
|
3034
3234
|
issues.push({
|
|
3035
3235
|
code: "#REF!",
|
|
3036
3236
|
place: v.place,
|
|
3037
|
-
reason: `A path starts with a root: ${ROOTS.join(", ")}
|
|
3237
|
+
reason: `A path starts with a root: ${ROOTS.join(", ")}.`,
|
|
3238
|
+
at: stepAt(0)
|
|
3038
3239
|
});
|
|
3039
3240
|
return "skip";
|
|
3040
3241
|
}
|
|
3041
3242
|
if (!roots.includes(root)) issues.push({
|
|
3042
3243
|
code: "#REF!",
|
|
3043
3244
|
place: v.place,
|
|
3044
|
-
reason: `The root ${root} is not open here. The open roots are ${roots.join(", ")}
|
|
3245
|
+
reason: `The root ${root} is not open here. The open roots are ${roots.join(", ")}.`,
|
|
3246
|
+
at: stepAt(0)
|
|
3045
3247
|
});
|
|
3046
3248
|
const first = path[1];
|
|
3047
3249
|
if (root === "names" && !anyName && isKey(first) && !v.names.has(String(first))) {
|
|
@@ -3049,33 +3251,38 @@ function check(machine, doc, options = {}) {
|
|
|
3049
3251
|
issues.push({
|
|
3050
3252
|
code: "#NAME?",
|
|
3051
3253
|
place: v.place,
|
|
3052
|
-
reason: later ? `The name ${String(first)} is bound by a later step.` : `Nothing binds the name ${String(first)}
|
|
3254
|
+
reason: later ? `The name ${String(first)} is bound by a later step.` : `Nothing binds the name ${String(first)}.`,
|
|
3255
|
+
at: stepAt(1)
|
|
3053
3256
|
});
|
|
3054
3257
|
}
|
|
3055
|
-
path.
|
|
3056
|
-
if (isKey(step)) return;
|
|
3258
|
+
path.forEach((step, index) => {
|
|
3259
|
+
if (index === 0 || isKey(step)) return;
|
|
3057
3260
|
const found = isEnvelope(step) ? lookupKind(machine.world, step.type) : void 0;
|
|
3058
3261
|
const walker = found?.ok === true && Object.hasOwn(found.kind.verbs, "step") ? found.kind.verbs["step"] : void 0;
|
|
3059
3262
|
if (walker === void 0 || !has(machine.walkers, walker)) issues.push({
|
|
3060
3263
|
code: "#STEP?",
|
|
3061
3264
|
place: v.place,
|
|
3062
|
-
reason: "A step is a key, or a document of a kind with the verb step."
|
|
3265
|
+
reason: "A step is a key, or a document of a kind with the verb step.",
|
|
3266
|
+
at: stepAt(index)
|
|
3063
3267
|
});
|
|
3064
3268
|
});
|
|
3065
|
-
return "skip";
|
|
3066
3269
|
}, {
|
|
3067
3270
|
...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
|
|
3068
3271
|
...Array.isArray(options.names) ? { names: options.names } : {},
|
|
3272
|
+
...options.caps === void 0 ? {} : { caps: options.caps },
|
|
3069
3273
|
problem: (problem) => issues.push({
|
|
3070
3274
|
code: problem.code,
|
|
3071
3275
|
place: problem.place,
|
|
3072
|
-
reason: problem.reason
|
|
3276
|
+
reason: problem.reason,
|
|
3277
|
+
at: problem.at
|
|
3073
3278
|
})
|
|
3074
3279
|
});
|
|
3075
3280
|
return issues;
|
|
3076
3281
|
}
|
|
3077
3282
|
//#endregion
|
|
3078
3283
|
//#region src/formula.ts
|
|
3284
|
+
/** The mark of a field that the profile leaves out of a record. */
|
|
3285
|
+
const SKIPPED = Symbol("skipped");
|
|
3079
3286
|
/** The value of a name whose binding failed. A reference to the name gives the error. */
|
|
3080
3287
|
var Held = class {
|
|
3081
3288
|
error;
|
|
@@ -3127,6 +3334,16 @@ function setOwn(target, key, value) {
|
|
|
3127
3334
|
function compiled(compile) {
|
|
3128
3335
|
return { compile };
|
|
3129
3336
|
}
|
|
3337
|
+
/** This function evaluates parts in order. It gives the value of each part, or the first error. */
|
|
3338
|
+
function valuesOf(parts, ctx, rt) {
|
|
3339
|
+
const values = new Array(parts.length);
|
|
3340
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
3341
|
+
const result = parts[index].code(ctx, rt);
|
|
3342
|
+
if (!result.ok) return result;
|
|
3343
|
+
values[index] = result.value;
|
|
3344
|
+
}
|
|
3345
|
+
return values;
|
|
3346
|
+
}
|
|
3130
3347
|
function partsOf(value) {
|
|
3131
3348
|
return isRecord(value) ? value : {};
|
|
3132
3349
|
}
|
|
@@ -3273,18 +3490,48 @@ function formulaEvaluators(profile = {}) {
|
|
|
3273
3490
|
return Object.hasOwn(ops, name) ? ops[name] : void 0;
|
|
3274
3491
|
};
|
|
3275
3492
|
const notTruth = (what) => fail("#VALUE!", `The ${what} must give a truth value.`);
|
|
3493
|
+
const combine = profile.combine;
|
|
3494
|
+
/** This function evaluates each part. Without `combine`, the first error stops it. A field that `omit` skips is absent. */
|
|
3495
|
+
const collect = (parts, ctx, rt, skip) => {
|
|
3496
|
+
const values = new Array(parts.length);
|
|
3497
|
+
let errors;
|
|
3498
|
+
for (let index = 0; index < parts.length; index += 1) {
|
|
3499
|
+
const result = parts[index].code(ctx, rt);
|
|
3500
|
+
if (result.ok) values[index] = result.value;
|
|
3501
|
+
else if (skip !== void 0 && skip(result.error)) values[index] = SKIPPED;
|
|
3502
|
+
else if (combine === void 0) return result;
|
|
3503
|
+
else (errors ??= []).push(result.error);
|
|
3504
|
+
}
|
|
3505
|
+
if (errors === void 0 || combine === void 0) return values;
|
|
3506
|
+
return {
|
|
3507
|
+
ok: false,
|
|
3508
|
+
error: errors.length === 1 ? errors[0] : combine(errors)
|
|
3509
|
+
};
|
|
3510
|
+
};
|
|
3276
3511
|
return {
|
|
3277
3512
|
"formula.lit": compiled(({ doc }) => {
|
|
3278
3513
|
const result = ok(doc.value);
|
|
3279
3514
|
return () => result;
|
|
3280
3515
|
}),
|
|
3281
|
-
"formula.ref": compiled(({ doc }) => {
|
|
3516
|
+
"formula.ref": compiled(({ doc, parts, fill, address }) => {
|
|
3282
3517
|
const path = doc.value;
|
|
3283
3518
|
if (!Array.isArray(path) || path.length === 0) {
|
|
3284
3519
|
const bad = fail("#VALUE!", "The value of ref is a path: a list that starts with a root, for example [\"names\", \"a\"].");
|
|
3285
3520
|
return () => bad;
|
|
3286
3521
|
}
|
|
3287
3522
|
const head = path[0] === "names" && typeof path[1] === "string" ? path[1] : void 0;
|
|
3523
|
+
const give = (found) => {
|
|
3524
|
+
if (!found.ok) return fail(found.code, found.reason);
|
|
3525
|
+
if (address === true) return ok(found.thing);
|
|
3526
|
+
const reached = valueOfThing(found.thing);
|
|
3527
|
+
if (reached instanceof Held) return {
|
|
3528
|
+
ok: false,
|
|
3529
|
+
error: reached.error
|
|
3530
|
+
};
|
|
3531
|
+
if (missing !== void 0 && missing(reached)) return fail("#N/A", "The path reaches no value.");
|
|
3532
|
+
return ok(reached);
|
|
3533
|
+
};
|
|
3534
|
+
const computed = parts.length > 0;
|
|
3288
3535
|
return (ctx, rt) => {
|
|
3289
3536
|
if (head !== void 0 && Object.hasOwn(ctx.names, head)) {
|
|
3290
3537
|
const bound = ctx.names[head];
|
|
@@ -3293,21 +3540,40 @@ function formulaEvaluators(profile = {}) {
|
|
|
3293
3540
|
error: bound.error
|
|
3294
3541
|
};
|
|
3295
3542
|
}
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
return
|
|
3543
|
+
if (!computed) return give(rt.resolve(ctx, path));
|
|
3544
|
+
const steps = valuesOf(parts, ctx, rt);
|
|
3545
|
+
return Array.isArray(steps) ? give(rt.resolve(ctx, fill(steps))) : steps;
|
|
3546
|
+
};
|
|
3547
|
+
}),
|
|
3548
|
+
"formula.step": compiled(({ doc, parts, fill }) => {
|
|
3549
|
+
if (parts.length === 0) {
|
|
3550
|
+
const same = ok(doc);
|
|
3551
|
+
return () => same;
|
|
3552
|
+
}
|
|
3553
|
+
return (ctx, rt) => {
|
|
3554
|
+
const values = valuesOf(parts, ctx, rt);
|
|
3555
|
+
return Array.isArray(values) ? ok({
|
|
3556
|
+
...doc,
|
|
3557
|
+
value: fill(values)
|
|
3558
|
+
}) : values;
|
|
3305
3559
|
};
|
|
3306
3560
|
}),
|
|
3307
3561
|
"formula.record": compiled(({ value }) => {
|
|
3308
3562
|
const fields = partsOf(value);
|
|
3309
3563
|
const keys = Object.keys(fields);
|
|
3310
3564
|
const codes = keys.map((key) => fields[key].code);
|
|
3565
|
+
if (combine !== void 0) {
|
|
3566
|
+
const parts = keys.map((key) => fields[key]);
|
|
3567
|
+
return (ctx, rt) => {
|
|
3568
|
+
const values = collect(parts, ctx, rt, omit);
|
|
3569
|
+
if (!Array.isArray(values)) return values;
|
|
3570
|
+
const out = {};
|
|
3571
|
+
keys.forEach((key, index) => {
|
|
3572
|
+
if (values[index] !== SKIPPED) setOwn(out, key, values[index]);
|
|
3573
|
+
});
|
|
3574
|
+
return ok(out);
|
|
3575
|
+
};
|
|
3576
|
+
}
|
|
3311
3577
|
return (ctx, rt) => {
|
|
3312
3578
|
const out = {};
|
|
3313
3579
|
for (let index = 0; index < keys.length; index += 1) {
|
|
@@ -3322,13 +3588,8 @@ function formulaEvaluators(profile = {}) {
|
|
|
3322
3588
|
};
|
|
3323
3589
|
}),
|
|
3324
3590
|
"formula.list": compiled(({ parts }) => (ctx, rt) => {
|
|
3325
|
-
const
|
|
3326
|
-
|
|
3327
|
-
const result = parts[index].code(ctx, rt);
|
|
3328
|
-
if (!result.ok) return result;
|
|
3329
|
-
out[index] = result.value;
|
|
3330
|
-
}
|
|
3331
|
-
return ok(out);
|
|
3591
|
+
const values = collect(parts, ctx, rt);
|
|
3592
|
+
return Array.isArray(values) ? ok(values) : values;
|
|
3332
3593
|
}),
|
|
3333
3594
|
"formula.let": compiled(({ value }) => {
|
|
3334
3595
|
const record = partsOf(value);
|
|
@@ -3443,6 +3704,15 @@ function formulaEvaluators(profile = {}) {
|
|
|
3443
3704
|
}
|
|
3444
3705
|
const done = (out) => check === void 0 ? ok(out) : check(out, name) ?? ok(out);
|
|
3445
3706
|
const failed = (error) => thrown(error, `the operation ${name}`);
|
|
3707
|
+
if (combine !== void 0) return (ctx, rt) => {
|
|
3708
|
+
const values = collect(parts, ctx, rt);
|
|
3709
|
+
if (!Array.isArray(values)) return values;
|
|
3710
|
+
try {
|
|
3711
|
+
return done(fn(...values));
|
|
3712
|
+
} catch (error) {
|
|
3713
|
+
return failed(error);
|
|
3714
|
+
}
|
|
3715
|
+
};
|
|
3446
3716
|
if (parts.length === 1) {
|
|
3447
3717
|
const [a] = parts;
|
|
3448
3718
|
return (ctx, rt) => {
|
|
@@ -3490,9 +3760,9 @@ function formulaEvaluators(profile = {}) {
|
|
|
3490
3760
|
const unknown = fail("#NAME?", `The language has no extension ${name}.`);
|
|
3491
3761
|
return () => unknown;
|
|
3492
3762
|
}
|
|
3493
|
-
return () => {
|
|
3763
|
+
return (ctx) => {
|
|
3494
3764
|
try {
|
|
3495
|
-
return handler(doc.value);
|
|
3765
|
+
return handler(doc.value, ctx);
|
|
3496
3766
|
} catch (error) {
|
|
3497
3767
|
return thrown(error, `the extension ${name}`);
|
|
3498
3768
|
}
|
|
@@ -3525,6 +3795,6 @@ function formulaMachine(profile = {}, more = {}) {
|
|
|
3525
3795
|
};
|
|
3526
3796
|
}
|
|
3527
3797
|
//#endregion
|
|
3528
|
-
export { CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_WALKERS, STD_WORLD, THING, ask, capKeys, check, checkSteps, classify, context, dataEdges, derefStep, describe, docEquals, effectEdges, entriesAsJson, evaluate, fail, failures, field, flatten, formulaEvaluators, formulaKinds, formulaMachine, fromJson, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, narrow, nearestWalker, nodeAt, ok, pathMatches, permits, placed, planner, prepare, ref, refsOf, resolve, run, splitParts, stored, tag, thrown, toJson, typeName, typePath, typed, valueOfThing, walk, worldThing };
|
|
3798
|
+
export { CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_WALKERS, STD_WORLD, THING, ask, capKeys, check, checkSteps, classify, context, dataEdges, derefStep, describe, docEquals, effectEdges, entriesAsJson, evaluate, fail, failures, field, flatten, formulaEvaluators, formulaKinds, formulaMachine, fromJson, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, narrow, nearestWalker, nodeAt, ok, partCaps, pathMatches, permits, placed, planner, prepare, ref, refsOf, resolve, run, splitParts, stored, tag, thrown, toJson, typeName, typePath, typed, valueOfThing, walk, worldThing };
|
|
3529
3799
|
|
|
3530
3800
|
//# sourceMappingURL=index.js.map
|