@mark1russell7/coeval 0.4.2 → 0.5.0

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/build/index.js CHANGED
@@ -175,9 +175,17 @@ function fromJson(value) {
175
175
  });
176
176
  }
177
177
  /**
178
- * This function tells if two JSON values are equal. Equal values have the same texts, numbers and truth values,
179
- * the same items in the same order, and the same fields. The order of the fields does not matter. It does not use the stack for the
180
- * depth, thus a deep document cannot overflow it.
178
+ * This function tells if two values are equal. Plain JSON compares by its structure. Equal values have the same
179
+ * texts, numbers and truth values, the same items in the same order, and the same fields. The order of the fields
180
+ * does not matter. Each leaf compares with `Object.is`, thus `-0` is not `0`, and `NaN` is `NaN`.
181
+ *
182
+ * Only lists and plain records (`isRecord`) compare by their items and fields. Each other object compares by
183
+ * identity: a date, a map, a function and an instance of a class are equal only to themselves. Thus an early cutoff
184
+ * with this function does not keep a stale host value.
185
+ *
186
+ * The function does not use the stack for the depth, thus a deep document cannot overflow it. A cycle of lists or
187
+ * records does not make it loop. `sameValue` of `agree` uses the same rules, and it adds rules for closures and for
188
+ * a rule of the caller.
181
189
  *
182
190
  * @param a - The first value.
183
191
  * @param b - The second value.
@@ -185,15 +193,23 @@ function fromJson(value) {
185
193
  */
186
194
  function docEquals(a, b) {
187
195
  const stack = [[a, b]];
196
+ let seen;
188
197
  while (stack.length > 0) {
189
198
  const [x, y] = stack.pop();
190
199
  if (Object.is(x, y)) continue;
191
- if (typeof x !== "object" || typeof y !== "object" || x === null || y === null) return false;
192
- if (Array.isArray(x) !== Array.isArray(y)) return false;
193
- if (Array.isArray(x)) {
200
+ const list = Array.isArray(x);
201
+ if (list !== Array.isArray(y)) return false;
202
+ if (!list && (!isRecord(x) || !isRecord(y))) return false;
203
+ seen ??= /* @__PURE__ */ new Map();
204
+ const pairs = seen.get(x);
205
+ if (pairs?.has(y) === true) continue;
206
+ if (pairs === void 0) seen.set(x, /* @__PURE__ */ new Set([y]));
207
+ else pairs.add(y);
208
+ if (list) {
209
+ const xs = x;
194
210
  const ys = y;
195
- if (x.length !== ys.length) return false;
196
- for (let index = 0; index < x.length; index += 1) stack.push([x[index], ys[index]]);
211
+ if (xs.length !== ys.length) return false;
212
+ for (let index = 0; index < xs.length; index += 1) stack.push([xs[index], ys[index]]);
197
213
  continue;
198
214
  }
199
215
  const xr = x;
@@ -283,7 +299,7 @@ var Failure = class extends Error {
283
299
  */
284
300
  function isStackOverflow(error) {
285
301
  try {
286
- return error instanceof RangeError && /call stack/i.test(error.message);
302
+ return (error instanceof RangeError || error instanceof SyntaxError) && error.message.includes("call stack");
287
303
  } catch {
288
304
  return true;
289
305
  }
@@ -1040,6 +1056,10 @@ const NO_SLOTS = Object.freeze([]);
1040
1056
  function hasSlots(template) {
1041
1057
  return template.t !== "data";
1042
1058
  }
1059
+ /** This function tells if a shape holds only data: no value of the shape can hold a part. */
1060
+ function isData(shape) {
1061
+ return shape.shape === "none" || shape.shape === "text" || shape.shape === "number" || shape.shape === "one";
1062
+ }
1043
1063
  /** This function gives the reason why a value is not data of a shape, or `undefined` when it is. */
1044
1064
  function dataFault(spec, item) {
1045
1065
  if (spec.shape === "text") return typeof item === "string" ? void 0 : "The value must be a text.";
@@ -1141,9 +1161,13 @@ function splitParts(shape, value) {
1141
1161
  shape: "term",
1142
1162
  ...spec.of === void 0 ? {} : { of: spec.of }
1143
1163
  };
1144
- return {
1164
+ const items = list.map((child, index) => walk(each, child, [...path, index]));
1165
+ return isData(each) ? {
1166
+ t: "data",
1167
+ value: item
1168
+ } : {
1145
1169
  t: "list",
1146
- items: list.map((child, index) => walk(each, child, [...path, index]))
1170
+ items
1147
1171
  };
1148
1172
  }
1149
1173
  if (!isRecord(item)) throw new Bad("The value must be a record.", path);
@@ -1211,6 +1235,54 @@ function splitParts(shape, value) {
1211
1235
  };
1212
1236
  }
1213
1237
  /**
1238
+ * This function reads one document by the contracts of the world. It finds the kind of the type. A bare value gets
1239
+ * the type that its position declares. Then the function splits the value by the shape of the kind. The plan, the
1240
+ * reference interpreter and the static kit read each document with this function. Thus they see the same parts.
1241
+ *
1242
+ * @param world - The world of the kinds.
1243
+ * @param value - The document, or a bare value.
1244
+ * @param declaredType - The type that the position of a bare value declares.
1245
+ * @returns The document, its kind and its parts, or the reason why the value is not a document.
1246
+ */
1247
+ function partsOf(world, value, declaredType) {
1248
+ const envelope = isEnvelope(value) ? value : void 0;
1249
+ if (envelope === void 0 && declaredType === void 0) return {
1250
+ ok: false,
1251
+ code: "#PART?",
1252
+ reason: "The value has no envelope, and its position declares no type."
1253
+ };
1254
+ const doc = envelope ?? {
1255
+ type: declaredType,
1256
+ value
1257
+ };
1258
+ const found = lookupKind(world, doc.type);
1259
+ const kind = found.ok ? found.kind : void 0;
1260
+ const split = splitParts(kind?.parts, doc.value);
1261
+ const typePath = found.ok ? found.path : void 0;
1262
+ if (split.ok) return {
1263
+ ok: true,
1264
+ doc,
1265
+ declared: envelope === void 0,
1266
+ kind,
1267
+ typePath,
1268
+ split
1269
+ };
1270
+ const where = split.at.length === 0 ? "" : ` (at ${split.at.join(".")})`;
1271
+ const reason = `${split.reason}${where} The kind is ${typeName(doc.type)}.`;
1272
+ return {
1273
+ ok: true,
1274
+ doc,
1275
+ declared: envelope === void 0,
1276
+ kind,
1277
+ typePath,
1278
+ split: {
1279
+ ok: false,
1280
+ reason,
1281
+ at: split.at
1282
+ }
1283
+ };
1284
+ }
1285
+ /**
1214
1286
  * This function tells if the path of a part matches a pattern of a scope rule. The key `"*"` of a pattern matches
1215
1287
  * each key.
1216
1288
  *
@@ -1655,15 +1727,15 @@ function finish(c, meta, code, run) {
1655
1727
  * This function finds the evaluator of the verb `eval` without the record of the rungs, for a compilation without a
1656
1728
  * trace. It gives the same evaluator as `ask`: the own entry, then the kind, then the default of the world.
1657
1729
  */
1658
- function evaluatorOf(world, envelope, found) {
1730
+ function evaluatorOf(world, envelope, kind) {
1659
1731
  const own = envelope?.own;
1660
1732
  const ownName = own !== void 0 && Object.hasOwn(own, "eval") ? own["eval"] : void 0;
1661
1733
  if (ownName !== void 0) return {
1662
1734
  name: ownName,
1663
1735
  unknown: false
1664
1736
  };
1665
- if (!found.ok) return { unknown: true };
1666
- const verbs = found.kind.verbs;
1737
+ if (kind === void 0) return { unknown: true };
1738
+ const verbs = kind.verbs;
1667
1739
  const name = Object.hasOwn(verbs, "eval") ? verbs["eval"] : Object.hasOwn(world.defaults, "eval") ? world.defaults["eval"] : void 0;
1668
1740
  return name === void 0 ? { unknown: false } : {
1669
1741
  name,
@@ -1682,23 +1754,28 @@ const NO_META = Object.freeze({
1682
1754
  side: "derive"
1683
1755
  });
1684
1756
  function compileNode(c, value, place, declared, depth, address = false) {
1685
- const envelope = isEnvelope(value) ? value : void 0;
1686
- const doc = envelope ?? {
1687
- type: declared ?? "?",
1688
- value
1689
- };
1757
+ const world = c.machine.world;
1758
+ const read = partsOf(world, value, declared);
1759
+ if (!read.ok) return failing(c, c.traced ? {
1760
+ path: place.map(String),
1761
+ doc: {
1762
+ type: "?",
1763
+ value
1764
+ },
1765
+ declared: true,
1766
+ answer: NO_ANSWER,
1767
+ side: "derive"
1768
+ } : NO_META, place, read.code, read.reason);
1769
+ const { doc, kind, split } = read;
1770
+ const envelope = read.declared ? void 0 : doc;
1690
1771
  const meta0 = c.traced ? {
1691
1772
  path: place.map(String),
1692
1773
  doc,
1693
- declared: envelope === void 0,
1774
+ declared: read.declared,
1694
1775
  answer: NO_ANSWER,
1695
1776
  side: "derive"
1696
1777
  } : NO_META;
1697
- if (envelope === void 0 && declared === void 0) return failing(c, meta0, place, "#PART?", "The value has no envelope, and its position declares no type.");
1698
1778
  if (depth > c.maxDepth) return failing(c, meta0, place, "#DEPTH!", `The nesting is deeper than ${c.maxDepth} documents.`);
1699
- const world = c.machine.world;
1700
- const found = lookupKind(world, doc.type);
1701
- const kind = found.ok ? found.kind : void 0;
1702
1779
  let meta = meta0;
1703
1780
  let name;
1704
1781
  let unknown;
@@ -1712,7 +1789,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
1712
1789
  name = answer.evaluator;
1713
1790
  unknown = answer.error === "unknown-kind";
1714
1791
  } else {
1715
- const quick = evaluatorOf(world, envelope, found);
1792
+ const quick = evaluatorOf(world, envelope, kind);
1716
1793
  name = quick.name;
1717
1794
  unknown = quick.unknown;
1718
1795
  }
@@ -1722,11 +1799,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
1722
1799
  const runner = name !== void 0 && Object.hasOwn(runners, name) ? runners[name] : void 0;
1723
1800
  const evaluator = name !== void 0 && Object.hasOwn(c.machine.evaluators, name) ? c.machine.evaluators[name] : void 0;
1724
1801
  if (name === void 0 || runner === void 0 && evaluator === void 0) return failing(c, meta, place, "#NOEVAL", `No rung gives an evaluator for ${kindText}.`);
1725
- const split = splitParts(kind?.parts, doc.value);
1726
- if (!split.ok) {
1727
- const at = split.at.length === 0 ? "" : ` (at ${split.at.join(".")})`;
1728
- return failing(c, meta, place, "#VALUE!", `${split.reason}${at} The kind is ${kindText}.`);
1729
- }
1802
+ if (!split.ok) return failing(c, meta, place, "#VALUE!", split.reason);
1730
1803
  const parts = split.parts.map((slot) => {
1731
1804
  const item = slot.item;
1732
1805
  const own = compileNode(c, item, place.concat(slot.path), slot.of, depth + 1, slot.address === true);
@@ -1748,7 +1821,7 @@ function compileNode(c, value, place, declared, depth, address = false) {
1748
1821
  });
1749
1822
  const input = {
1750
1823
  kind: kindText,
1751
- typePath: found.ok ? found.path : [],
1824
+ typePath: read.typePath ?? [],
1752
1825
  doc,
1753
1826
  value: split.parts.length === 0 ? doc.value : split.fill(parts),
1754
1827
  data: split.data,
@@ -2184,7 +2257,8 @@ const STD_WORLD = {
2184
2257
  ],
2185
2258
  of: "number"
2186
2259
  },
2187
- summary: "A node of a tree. Its parts see it as self, and each node links to its parent."
2260
+ caps: [{ rule: "mask" }],
2261
+ summary: "A node of a tree. Each part is an attribute that evaluates on demand, one time, with the node as self."
2188
2262
  },
2189
2263
  box: {
2190
2264
  verbs: {
@@ -2200,7 +2274,8 @@ const STD_WORLD = {
2200
2274
  ],
2201
2275
  of: "number"
2202
2276
  },
2203
- summary: "A node of a tree, as panel. A formula in a box can read the parent of the box."
2277
+ caps: [{ rule: "mask" }],
2278
+ summary: "A node of a tree, as panel. A formula in a box can read its parent and its siblings."
2204
2279
  },
2205
2280
  math: { kinds: {
2206
2281
  sum: {
@@ -2317,53 +2392,167 @@ const STD_EVALUATORS = {
2317
2392
  const found = resolve(data);
2318
2393
  return found.ok ? ok(valueOfThing(found.thing)) : fail(found.code, found.reason);
2319
2394
  },
2320
- "tree.node": (input) => treeNode(input.parts, input.context, input.kind)
2395
+ "tree.node": (input) => treeNode(input)
2321
2396
  };
2397
+ /** The brand of a node of the decorated tree. Its value is the state that the kit reads. */
2398
+ const TREE_NODE = Symbol.for("coeval.tree.node");
2399
+ const BUSY = Object.freeze({ busy: true });
2400
+ /** The attributes in evaluation, in the order of their demands. An evaluation does not wait, thus one list serves. */
2401
+ const demands = [];
2402
+ function attributeText(key, type, place) {
2403
+ return `${key} of ${type} at [${place.join(", ")}]`;
2404
+ }
2405
+ /** This function gives the `#CYCLE!` of a demand that reached an attribute in evaluation, with the chain of demands. */
2406
+ function cycleAt(cells, key, text) {
2407
+ const first = demands.findIndex((demand) => demand.cells === cells && demand.key === key);
2408
+ const chain = first === -1 ? [text] : demands.slice(first).map((demand) => demand.text);
2409
+ chain.push(text);
2410
+ return fail("#CYCLE!", `The attributes form a cycle: ${chain.join(" -> ")}.`);
2411
+ }
2412
+ function stateOf(thing) {
2413
+ return typeof thing === "object" && thing !== null ? thing[TREE_NODE] : void 0;
2414
+ }
2415
+ /** This function sets an own field, also the field `__proto__` (SHAPE.PROTO). */
2416
+ function putField(target, key, value) {
2417
+ Object.defineProperty(target, key, {
2418
+ value,
2419
+ enumerable: true,
2420
+ writable: true,
2421
+ configurable: true
2422
+ });
2423
+ }
2322
2424
  /**
2323
- * This function evaluates a node of a tree. The node is a host thing. A step `parent` reaches the node that holds
2324
- * it. A step with the name of a part evaluates that part on demand, one time. Each part sees the node as self.
2425
+ * This function gives a value with the JSON of each node of a tree in it. A list or a plain record is new only when
2426
+ * it holds a node. A container that holds itself stays as it is.
2325
2427
  */
2326
- function treeNode(parts, context, type) {
2327
- const memo = /* @__PURE__ */ new Map();
2428
+ function plainOf(value, path) {
2429
+ const state = stateOf(value);
2430
+ if (state !== void 0) {
2431
+ if (path.has(value)) return fail("#CYCLE!", `The JSON of the node ${state.type} at [${state.place.join(", ")}] holds the node itself.`);
2432
+ return state.json(path);
2433
+ }
2434
+ if (typeof value !== "object" || value === null || path.has(value) || isHostThing(value)) return ok(value);
2435
+ if (!Array.isArray(value) && !isRecord(value)) return ok(value);
2436
+ path.add(value);
2437
+ try {
2438
+ if (Array.isArray(value)) {
2439
+ let list;
2440
+ for (let index = 0; index < value.length; index += 1) {
2441
+ const item = plainOf(value[index], path);
2442
+ if (!item.ok) return item;
2443
+ if (item.value !== value[index]) (list ??= [...value])[index] = item.value;
2444
+ }
2445
+ return ok(list ?? value);
2446
+ }
2447
+ const record = value;
2448
+ let out;
2449
+ for (const key of Object.keys(record)) {
2450
+ const item = plainOf(record[key], path);
2451
+ if (!item.ok) return item;
2452
+ if (item.value === record[key]) continue;
2453
+ if (out === void 0) {
2454
+ out = {};
2455
+ for (const other of Object.keys(record)) putField(out, other, record[other]);
2456
+ }
2457
+ putField(out, key, item.value);
2458
+ }
2459
+ return ok(out ?? value);
2460
+ } finally {
2461
+ path.delete(value);
2462
+ }
2463
+ }
2464
+ /**
2465
+ * This function makes a node of the decorated tree. A step `parent` gives the self of the context of the node, and a
2466
+ * step `type` gives its type. A step with the key of a part reads that attribute. A failed attribute throws `Failure`
2467
+ * with its own error, thus a reference to it gives that error.
2468
+ */
2469
+ function treeThing(parts, context, type, place, build) {
2470
+ const cells = /* @__PURE__ */ new Map();
2328
2471
  const read = (key) => {
2329
- const known = memo.get(key);
2330
- if (known !== void 0) return known;
2472
+ const cell = cells.get(key);
2473
+ if (cell !== void 0) return cell.busy ? cycleAt(cells, key, attributeText(key, type, place)) : cell.result;
2331
2474
  const part = parts.find((item) => item.key === key);
2332
2475
  if (part === void 0) return void 0;
2333
- const result = part.evaluate({
2334
- ...context,
2335
- self: me
2476
+ cells.set(key, BUSY);
2477
+ demands.push({
2478
+ cells,
2479
+ key,
2480
+ text: attributeText(key, type, place)
2481
+ });
2482
+ let result;
2483
+ try {
2484
+ result = part.evaluate({
2485
+ ...context,
2486
+ self: node
2487
+ });
2488
+ } catch (error) {
2489
+ cells.delete(key);
2490
+ throw error;
2491
+ } finally {
2492
+ demands.pop();
2493
+ }
2494
+ cells.set(key, {
2495
+ busy: false,
2496
+ result
2336
2497
  });
2337
- memo.set(key, result);
2338
2498
  return result;
2339
2499
  };
2340
- const me = {
2500
+ const state = {
2501
+ build,
2502
+ type,
2503
+ place,
2504
+ json(path) {
2505
+ path.add(node);
2506
+ try {
2507
+ const out = {};
2508
+ for (const part of parts) {
2509
+ const result = read(part.key);
2510
+ if (!result.ok) return result;
2511
+ const value = plainOf(result.value, path);
2512
+ if (!value.ok) return value;
2513
+ putField(out, part.key, value.value);
2514
+ }
2515
+ return ok(out);
2516
+ } finally {
2517
+ path.delete(node);
2518
+ }
2519
+ }
2520
+ };
2521
+ const node = {
2341
2522
  [THING]: true,
2523
+ [TREE_NODE]: state,
2342
2524
  type,
2343
2525
  label: `node ${type}`,
2344
2526
  deref(key) {
2345
2527
  if (key === "parent") return context.self;
2346
2528
  if (key === "type") return type;
2347
2529
  const result = read(String(key));
2348
- return result?.ok === true ? result.value : void 0;
2530
+ if (result === void 0) return void 0;
2531
+ if (!result.ok) throw new Failure(result.error);
2532
+ return result.value;
2349
2533
  },
2350
2534
  toJson() {
2351
- const out = {};
2352
- for (const part of parts) {
2353
- const result = read(part.key);
2354
- out[part.key] = result?.ok === true ? result.value : null;
2355
- }
2356
- return out;
2535
+ const result = state.json(/* @__PURE__ */ new Set());
2536
+ if (!result.ok) throw new Failure(result.error);
2537
+ return result.value;
2357
2538
  }
2358
2539
  };
2359
- const out = {};
2360
- for (const part of parts) {
2361
- const result = read(part.key);
2362
- if (result === void 0) continue;
2363
- if (!result.ok) return result;
2364
- out[part.key] = result.value;
2540
+ return node;
2541
+ }
2542
+ /**
2543
+ * This function evaluates a node of the decorated tree. Inside an attribute of an open tree, the node gives its host
2544
+ * thing, and no attribute evaluates. Else the node is the root of a new tree, and it gives the JSON of the tree.
2545
+ */
2546
+ function treeNode({ parts, context, kind, place }) {
2547
+ const above = stateOf(context.self);
2548
+ if (above !== void 0 && above.build.open) return ok(treeThing(parts, context, kind, place, above.build));
2549
+ const build = { open: true };
2550
+ const root = treeThing(parts, context, kind, place, build);
2551
+ try {
2552
+ return stateOf(root).json(/* @__PURE__ */ new Set());
2553
+ } finally {
2554
+ build.open = false;
2365
2555
  }
2366
- return ok(out);
2367
2556
  }
2368
2557
  function hostType(node, wanted) {
2369
2558
  return isHostThing(node) && node.type === wanted;
@@ -3020,40 +3209,32 @@ function walk(world, doc, visit, options = {}) {
3020
3209
  }];
3021
3210
  while (stack.length > 0) {
3022
3211
  const item = stack.pop();
3023
- const envelope = isEnvelope(item.value) ? item.value : void 0;
3024
- if (envelope === void 0 && item.declared === void 0) {
3212
+ const read = partsOf(world, item.value, item.declared);
3213
+ if (!read.ok) {
3025
3214
  options.problem?.({
3026
3215
  place: keysOf(item.place),
3027
3216
  at: keysOf(item.at),
3028
- code: "#PART?",
3029
- reason: "The value has no envelope, and its position declares no type."
3217
+ code: read.code,
3218
+ reason: read.reason
3030
3219
  });
3031
3220
  continue;
3032
3221
  }
3033
- const doc = envelope ?? {
3034
- type: item.declared ?? "?",
3035
- value: item.value
3036
- };
3037
- const found = lookupKind(world, doc.type);
3038
- const kind = found.ok ? found.kind : void 0;
3039
- 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);
3222
+ const { doc, kind, split } = read;
3223
+ const here = new Visit(item.place, item.at, doc, read.declared, item.depth, item.names, item.later, item.slot, item.parent, kind, read.typePath, item.address ? true : void 0, item.caps);
3040
3224
  if (visit(here) === "skip" || kind === void 0) continue;
3041
- const split = splitParts(kind.parts, doc.value);
3042
- const base = envelope === void 0 ? item.at : {
3225
+ const base = read.declared ? item.at : {
3043
3226
  up: item.at,
3044
3227
  keys: ["value"]
3045
3228
  };
3046
3229
  if (!split.ok) {
3047
- const at = split.at.length === 0 ? "" : ` (at ${split.at.join(".")})`;
3048
- const where = keysOf({
3049
- up: base,
3050
- keys: split.at
3051
- });
3052
3230
  options.problem?.({
3053
3231
  place: keysOf(item.place),
3054
- at: where,
3232
+ at: keysOf({
3233
+ up: base,
3234
+ keys: split.at
3235
+ }),
3055
3236
  code: "#VALUE!",
3056
- reason: `${split.reason}${at} The kind is ${typeName(doc.type)}.`
3237
+ reason: split.reason
3057
3238
  });
3058
3239
  continue;
3059
3240
  }
@@ -3185,7 +3366,8 @@ function capReason(v, kind) {
3185
3366
  * - `#PART?`: a value without a type.
3186
3367
  * - `#DEPTH!`: too much nesting.
3187
3368
  * - `#REF!` and `#STEP?`: a bad path.
3188
- * - `#NAME?`: a name that nothing binds.
3369
+ * - `#NAME?`: a name that nothing binds. With the hook `known` of the machine, also a name that the language does not
3370
+ * have, for example an operation.
3189
3371
  * - `#CAP!`: an effect that the capabilities of its document do not permit. A kind around the document can narrow them.
3190
3372
  *
3191
3373
  * @param machine - The world and the code of the evaluators.
@@ -3227,6 +3409,15 @@ function check(machine, doc, options = {}) {
3227
3409
  reason: `No rung gives an evaluator for ${typeName(v.doc.type)}.`,
3228
3410
  at: v.at
3229
3411
  });
3412
+ else if (machine.known !== void 0) {
3413
+ const known = machine.known(v.typePath ?? [], name);
3414
+ if (known !== true) issues.push({
3415
+ code: "#NAME?",
3416
+ place: v.place,
3417
+ reason: known,
3418
+ at: v.at
3419
+ });
3420
+ }
3230
3421
  const caps = v.caps;
3231
3422
  if (caps !== void 0 && v.kind?.effects !== void 0) {
3232
3423
  const kinds = v.kind.effects === "type" ? [v.typePath ?? []] : v.kind.effects.map((kind) => kind.split("."));
@@ -3259,7 +3450,7 @@ function check(machine, doc, options = {}) {
3259
3450
  reason: `A path starts with a root: ${ROOTS.join(", ")}.`,
3260
3451
  at: stepAt(0)
3261
3452
  });
3262
- return "skip";
3453
+ return;
3263
3454
  }
3264
3455
  if (!roots.includes(root)) issues.push({
3265
3456
  code: "#REF!",
@@ -3366,7 +3557,7 @@ function valuesOf(parts, ctx, rt) {
3366
3557
  }
3367
3558
  return values;
3368
3559
  }
3369
- function partsOf(value) {
3560
+ function partsOf$1(value) {
3370
3561
  return isRecord(value) ? value : {};
3371
3562
  }
3372
3563
  const LIT_SUMMARY = "A literal: its value is the result.";
@@ -3430,7 +3621,14 @@ function formulaKinds() {
3430
3621
  verbs: { eval: "formula.fn" },
3431
3622
  parts: {
3432
3623
  shape: "record",
3433
- fields: { body: term },
3624
+ fields: {
3625
+ params: {
3626
+ shape: "list",
3627
+ item: { shape: "text" },
3628
+ distinct: true
3629
+ },
3630
+ body: term
3631
+ },
3434
3632
  required: ["params", "body"]
3435
3633
  },
3436
3634
  scope: [{
@@ -3582,7 +3780,7 @@ function formulaEvaluators(profile = {}) {
3582
3780
  };
3583
3781
  }),
3584
3782
  "formula.record": compiled(({ value }) => {
3585
- const fields = partsOf(value);
3783
+ const fields = partsOf$1(value);
3586
3784
  const keys = Object.keys(fields);
3587
3785
  const codes = keys.map((key) => fields[key].code);
3588
3786
  if (combine !== void 0) {
@@ -3615,8 +3813,8 @@ function formulaEvaluators(profile = {}) {
3615
3813
  return Array.isArray(values) ? ok(values) : values;
3616
3814
  }),
3617
3815
  "formula.let": compiled(({ value }) => {
3618
- const record = partsOf(value);
3619
- const bindings = Object.entries(partsOf(record["bind"]));
3816
+ const record = partsOf$1(value);
3817
+ const bindings = Object.entries(partsOf$1(record["bind"]));
3620
3818
  const body = record["body"];
3621
3819
  return (ctx, rt) => {
3622
3820
  const names = { ...ctx.names };
@@ -3637,7 +3835,7 @@ function formulaEvaluators(profile = {}) {
3637
3835
  return () => bad;
3638
3836
  }
3639
3837
  const names = params;
3640
- const body = partsOf(value)["body"];
3838
+ const body = partsOf$1(value)["body"];
3641
3839
  return (ctx, rt) => {
3642
3840
  const closure = (...args) => {
3643
3841
  const scope = { ...ctx.names };
@@ -3654,7 +3852,7 @@ function formulaEvaluators(profile = {}) {
3654
3852
  };
3655
3853
  }),
3656
3854
  "formula.call": compiled(({ value }) => {
3657
- const record = partsOf(value);
3855
+ const record = partsOf$1(value);
3658
3856
  const fnPart = record["fn"];
3659
3857
  const args = Array.isArray(record["args"]) ? record["args"] : [];
3660
3858
  return (ctx, rt) => {
@@ -3675,7 +3873,7 @@ function formulaEvaluators(profile = {}) {
3675
3873
  };
3676
3874
  }),
3677
3875
  "formula.if": compiled(({ value }) => {
3678
- const record = partsOf(value);
3876
+ const record = partsOf$1(value);
3679
3877
  const test = record["test"];
3680
3878
  const then = record["then"];
3681
3879
  const other = record["else"];
@@ -3794,14 +3992,52 @@ function formulaEvaluators(profile = {}) {
3794
3992
  };
3795
3993
  }
3796
3994
  /**
3995
+ * This function makes the hook `known` of the formula kit for one profile (STATIC.KNOWN). The evaluator
3996
+ * `formula.op` knows an operation of `lazy` or of `ops`. A profile whose `ops` is a function answers through a call
3997
+ * of that function. A function that throws counts as an answer, because the run then gives `#CALC!`. The evaluator
3998
+ * `formula.ext` knows an extension of `ext` and each standard extension. The hook knows each name of the other
3999
+ * evaluators.
4000
+ *
4001
+ * @param profile - The operations and the extensions of the language.
4002
+ * @returns The hook: `true`, or the reason of the `#NAME?` that the evaluator gives in a run.
4003
+ */
4004
+ function formulaKnown(profile = {}) {
4005
+ const hasOp = (name) => {
4006
+ if (profile.lazy !== void 0 && Object.hasOwn(profile.lazy, name)) return true;
4007
+ const ops = profile.ops;
4008
+ if (ops === void 0) return false;
4009
+ if (typeof ops !== "function") return Object.hasOwn(ops, name);
4010
+ try {
4011
+ return ops(name) !== void 0;
4012
+ } catch {
4013
+ return true;
4014
+ }
4015
+ };
4016
+ const hasExt = (name) => profile.ext !== void 0 && Object.hasOwn(profile.ext, name) || Object.hasOwn(STD_EXT, name);
4017
+ return (path, evaluator) => {
4018
+ if (evaluator !== "formula.op" && evaluator !== "formula.ext") return true;
4019
+ const name = path.slice(1).join(".");
4020
+ if (evaluator === "formula.op") return hasOp(name) ? true : `The language has no operation ${name}.`;
4021
+ return hasExt(name) ? true : `The language has no extension ${name}.`;
4022
+ };
4023
+ }
4024
+ /**
3797
4025
  * This function makes a machine for a formula language. The machine has the kinds and the evaluators of the
3798
- * formula kit. It also has the kinds, the evaluators and the walkers that the language adds.
4026
+ * formula kit. It also has the kinds, the evaluators and the walkers that the language adds. Its hook `known` comes
4027
+ * from the profile (`formulaKnown`). A hook `known` of the language answers each name that the kit knows.
3799
4028
  *
3800
4029
  * @param profile - The operations and the rules of the language.
3801
4030
  * @param more - The parts of a machine that the language adds. Its kinds win over the kinds of the kit.
3802
4031
  * @returns The machine.
3803
4032
  */
3804
4033
  function formulaMachine(profile = {}, more = {}) {
4034
+ const kit = formulaKnown(profile);
4035
+ const replaced = (name) => more.evaluators !== void 0 && Object.hasOwn(more.evaluators, name) || more.runners !== void 0 && Object.hasOwn(more.runners, name);
4036
+ const theirs = more.known;
4037
+ const known = (path, evaluator) => {
4038
+ const answer = replaced(evaluator) ? true : kit(path, evaluator);
4039
+ return answer === true && theirs !== void 0 ? theirs(path, evaluator) : answer;
4040
+ };
3805
4041
  return {
3806
4042
  ...more,
3807
4043
  world: {
@@ -3814,7 +4050,8 @@ function formulaMachine(profile = {}, more = {}) {
3814
4050
  evaluators: {
3815
4051
  ...formulaEvaluators(profile),
3816
4052
  ...more.evaluators
3817
- }
4053
+ },
4054
+ known
3818
4055
  };
3819
4056
  }
3820
4057
  //#endregion
@@ -3822,7 +4059,10 @@ function formulaMachine(profile = {}, more = {}) {
3822
4059
  function own(table, name) {
3823
4060
  return table !== void 0 && Object.hasOwn(table, name) ? table[name] : void 0;
3824
4061
  }
3825
- /** This function finds the code of an evaluator name. A runner wins over an evaluator of the same name. */
4062
+ /**
4063
+ * This function finds the code of an evaluator name. A runner wins over an evaluator of the same name. A standard
4064
+ * evaluator gets the definition of the reference, unless the options give another definition (REF.TREE).
4065
+ */
3826
4066
  function choose(env, name) {
3827
4067
  const runner = own(env.machine.runners, name);
3828
4068
  if (runner !== void 0) {
@@ -3832,7 +4072,8 @@ function choose(env, name) {
3832
4072
  }
3833
4073
  const evaluator = own(env.machine.evaluators, name);
3834
4074
  if (evaluator === void 0) return void 0;
3835
- const defined = own(env.definitions.evaluators, name);
4075
+ const standard = evaluator === own(STD_EVALUATORS, name) ? own(STD_DEFINITIONS.evaluators, name) : void 0;
4076
+ const defined = own(env.definitions.evaluators, name) ?? standard;
3836
4077
  if (defined !== void 0) return { evaluator: defined };
3837
4078
  return typeof evaluator === "function" ? { evaluator } : { gap: `The reference has no definition of the compiled evaluator ${name}.` };
3838
4079
  }
@@ -3843,31 +4084,22 @@ function choose(env, name) {
3843
4084
  */
3844
4085
  function examine(env, at) {
3845
4086
  const { place, declared } = at;
3846
- const envelope = isEnvelope(at.value) ? at.value : void 0;
3847
- if (envelope === void 0 && declared === void 0) return fail("#PART?", "The value has no envelope, and its position declares no type.", { place });
4087
+ const world = env.machine.world;
4088
+ const read = partsOf(world, at.value, declared);
4089
+ if (!read.ok) return fail(read.code, read.reason, { place });
3848
4090
  if (at.depth > env.maxDepth) return fail("#DEPTH!", `The nesting is deeper than ${env.maxDepth} documents.`, { place });
3849
- const doc = envelope ?? {
3850
- type: declared,
3851
- value: at.value
3852
- };
4091
+ const { doc, kind, split } = read;
3853
4092
  const kindText = typeName(doc.type);
3854
- const world = env.machine.world;
3855
- const answer = ask(world, envelope ?? {}, "eval", declared === void 0 ? {} : { declaredType: declared });
4093
+ const answer = ask(world, read.declared ? {} : doc, "eval", declared === void 0 ? {} : { declaredType: declared });
3856
4094
  if (answer.error === "unknown-kind") return fail("#KIND?", `The world has no kind ${kindText}.`, { place });
3857
4095
  const name = answer.evaluator;
3858
4096
  const chosen = name === void 0 ? void 0 : choose(env, name);
3859
4097
  if (name === void 0 || chosen === void 0) return fail("#NOEVAL", `No rung gives an evaluator for ${kindText}.`, { place });
3860
- const found = lookupKind(world, doc.type);
3861
- const kind = found.ok ? found.kind : void 0;
3862
- const split = splitParts(kind?.parts, doc.value);
3863
- if (!split.ok) {
3864
- const where = split.at.length === 0 ? "" : ` (at ${split.at.join(".")})`;
3865
- return fail("#VALUE!", `${split.reason}${where} The kind is ${kindText}.`, { place });
3866
- }
4098
+ if (!split.ok) return fail("#VALUE!", split.reason, { place });
3867
4099
  return {
3868
4100
  doc,
3869
4101
  kindText,
3870
- typePath: found.ok ? found.path : [],
4102
+ typePath: read.typePath ?? [],
3871
4103
  kind,
3872
4104
  name,
3873
4105
  chosen,
@@ -4106,6 +4338,126 @@ function reference(machine, doc, context = makeContext(), options = {}) {
4106
4338
  return placed(thrown(error, "the reference"), []);
4107
4339
  }
4108
4340
  }
4341
+ const refNodes = /* @__PURE__ */ new WeakMap();
4342
+ /** The attributes in evaluation in the reference, in the order of their demands (TREE.CYCLE). */
4343
+ const inEvaluation = [];
4344
+ function nameOfAttribute(node, name) {
4345
+ return `${name} of ${node.kind} at [${node.place.join(", ")}]`;
4346
+ }
4347
+ function refNodeOf(thing) {
4348
+ return typeof thing === "object" && thing !== null ? refNodes.get(thing) : void 0;
4349
+ }
4350
+ /** TREE.ONCE, TREE.MEMO and TREE.CYCLE: the result of one attribute, or `undefined` when the node has no such part. */
4351
+ function attributeOf(node, self, name) {
4352
+ const done = node.values.get(name);
4353
+ if (done !== void 0) return done;
4354
+ if (node.pending.has(name)) {
4355
+ const from = inEvaluation.findIndex((entry) => entry.node === node && entry.name === name);
4356
+ return fail("#CYCLE!", `The attributes form a cycle: ${[...from < 0 ? [nameOfAttribute(node, name)] : inEvaluation.slice(from).map((entry) => nameOfAttribute(entry.node, entry.name)), nameOfAttribute(node, name)].join(" -> ")}.`);
4357
+ }
4358
+ const part = node.parts.find((item) => item.key === name);
4359
+ if (part === void 0) return void 0;
4360
+ node.pending.add(name);
4361
+ inEvaluation.push({
4362
+ node,
4363
+ name
4364
+ });
4365
+ try {
4366
+ const result = part.evaluate({
4367
+ ...node.ctx,
4368
+ self
4369
+ });
4370
+ node.values.set(name, result);
4371
+ return result;
4372
+ } finally {
4373
+ node.pending.delete(name);
4374
+ inEvaluation.pop();
4375
+ }
4376
+ }
4377
+ /** TREE.RESULT: the JSON of a node. `open` holds the nodes and the containers whose JSON is in progress. */
4378
+ function jsonOfNode(node, self, open) {
4379
+ const record = {};
4380
+ for (const part of node.parts) {
4381
+ const result = attributeOf(node, self, part.key);
4382
+ if (!result.ok) return result;
4383
+ const value = plainValue(result.value, [...open, self]);
4384
+ if (!value.ok) return value;
4385
+ setField(record, part.key, value.value);
4386
+ }
4387
+ return ok(record);
4388
+ }
4389
+ /** This function gives a copy of a value with the JSON of each node in it. */
4390
+ function plainValue(value, open) {
4391
+ const node = refNodeOf(value);
4392
+ if (node !== void 0) {
4393
+ if (open.includes(value)) return fail("#CYCLE!", `The JSON of the node ${node.kind} at [${node.place.join(", ")}] holds the node itself.`);
4394
+ return jsonOfNode(node, value, open);
4395
+ }
4396
+ if (typeof value !== "object" || value === null || isHostThing(value) || open.includes(value)) return ok(value);
4397
+ if (Array.isArray(value)) {
4398
+ const items = [];
4399
+ for (const item of value) {
4400
+ const plain = plainValue(item, [...open, value]);
4401
+ if (!plain.ok) return plain;
4402
+ items.push(plain.value);
4403
+ }
4404
+ return ok(items);
4405
+ }
4406
+ if (!isRecord(value)) return ok(value);
4407
+ const copy = {};
4408
+ for (const key of Object.keys(value)) {
4409
+ const plain = plainValue(value[key], [...open, value]);
4410
+ if (!plain.ok) return plain;
4411
+ setField(copy, key, plain.value);
4412
+ }
4413
+ return ok(copy);
4414
+ }
4415
+ /**
4416
+ * TREE.LAZY, TREE.PARENT, TREE.SIBLING and TREE.ERROR: a node of an open tree gives its thing, and the root of a new
4417
+ * tree gives its JSON. A step on the thing reads an attribute, and a failed attribute throws its own error.
4418
+ */
4419
+ const treeDefinition = ({ parts, context, kind, place }) => {
4420
+ const outer = refNodeOf(context.self);
4421
+ const nested = outer !== void 0 && outer.tree.open;
4422
+ const node = {
4423
+ tree: nested ? outer.tree : { open: true },
4424
+ kind,
4425
+ place,
4426
+ parts,
4427
+ ctx: context,
4428
+ values: /* @__PURE__ */ new Map(),
4429
+ pending: /* @__PURE__ */ new Set()
4430
+ };
4431
+ const self = {
4432
+ [THING]: true,
4433
+ type: kind,
4434
+ label: `node ${kind}`,
4435
+ deref: (key) => {
4436
+ if (key === "parent") return context.self;
4437
+ if (key === "type") return kind;
4438
+ const result = attributeOf(node, self, String(key));
4439
+ if (result === void 0 || result.ok) return result?.ok === true ? result.value : void 0;
4440
+ throw new Failure(result.error);
4441
+ },
4442
+ toJson: () => {
4443
+ const result = jsonOfNode(node, self, []);
4444
+ if (result.ok) return result.value;
4445
+ throw new Failure(result.error);
4446
+ }
4447
+ };
4448
+ refNodes.set(self, node);
4449
+ if (nested) return ok(self);
4450
+ try {
4451
+ return jsonOfNode(node, self, []);
4452
+ } finally {
4453
+ node.tree.open = false;
4454
+ }
4455
+ };
4456
+ /**
4457
+ * The definitions of the reference for the evaluators of the standard machine that need their own reading. The
4458
+ * reference uses them for the standard evaluators, also without the option `definitions`. It holds `tree.node`.
4459
+ */
4460
+ const STD_DEFINITIONS = { evaluators: { "tree.node": treeDefinition } };
4109
4461
  const CLOSURE$1 = Symbol.for("coeval.closure");
4110
4462
  /** This function sets an own field, also the field `__proto__` (SHAPE.PROTO). */
4111
4463
  function setField(target, key, value) {
@@ -4327,8 +4679,14 @@ function valuesOfStrict(parts) {
4327
4679
  /**
4328
4680
  * This function tells if two values are the same for `agree`. Lists and plain records compare item by item and field
4329
4681
  * by field, and the order of the fields does not matter. Each other leaf compares with `Object.is`, thus `-0` is not
4330
- * `0`, and `NaN` is `NaN`. Two closures of `fn` are the same when they have the same parameters. Two `Held` values
4331
- * are the same when their errors have the same code and place. Identity is not compared.
4682
+ * `0`, and `NaN` is `NaN`. The identity of a list or of a plain record is not compared.
4683
+ *
4684
+ * Two closures of `fn` are the same when they have the same parameters. Two `Held` values are the same when their
4685
+ * errors have the same code and place. Each other object is the same only as itself, unless the rule of the caller
4686
+ * tells otherwise.
4687
+ *
4688
+ * `docEquals` uses the same rules for lists, plain records and the other objects. It has no rules for closures, for
4689
+ * `Held` values and for a rule of the caller. Thus two closures are equal there only when they are the same function.
4332
4690
  *
4333
4691
  * @param a - The first value.
4334
4692
  * @param b - The second value.
@@ -4564,8 +4922,9 @@ function leafKind(kind) {
4564
4922
  /**
4565
4923
  * This function builds a random document for a world from the contracts of its kinds. It reads the shapes of the
4566
4924
  * parts, the declared types, the permitted kinds and the names that the scope rules bind. Some choices are malformed
4567
- * on purpose. Examples are an unknown kind, a value without its shape, a bare value without a type and a name that
4568
- * nothing binds. The depth and the size have limits.
4925
+ * on purpose, for example an unknown kind or an unknown name under a namespace with a fallback. Other examples are a
4926
+ * value without its shape, a bare value without a type and a name that nothing binds. The depth and the size have
4927
+ * limits.
4569
4928
  *
4570
4929
  * @param world - The world.
4571
4930
  * @param options - The seed, the types, the limits and the data of the leaves.
@@ -4578,10 +4937,16 @@ function generate(world, options) {
4578
4937
  const maxSize = options.maxSize ?? 24;
4579
4938
  const malformed = options.malformed ?? .05;
4580
4939
  const keys = options.keys ?? KEYS;
4940
+ const steps = options.steps ?? 2;
4941
+ const roots = options.roots ?? ROOTS;
4581
4942
  const stepTypes = types.filter((type) => {
4582
4943
  const found = lookupKind(world, type);
4583
4944
  return found.ok && Object.hasOwn(found.kind.verbs, "step");
4584
4945
  });
4946
+ const unknownNames = Object.keys(world.kinds).filter((key) => {
4947
+ const entry = world.kinds[key];
4948
+ return isNamespace(entry) && entry.fallback !== void 0;
4949
+ }).map((key) => [key, "nope"]);
4585
4950
  let size = 0;
4586
4951
  const kindOf = (type) => {
4587
4952
  const found = lookupKind(world, type);
@@ -4651,11 +5016,12 @@ function generate(world, options) {
4651
5016
  { names: "a" },
4652
5017
  ["nowhere", "a"]
4653
5018
  ]);
4654
- const root = pos.names.length > 0 && rng.chance(.75) ? "names" : rng.pick(ROOTS.filter((name) => name !== "names"));
5019
+ const others = roots.filter((name) => name !== "names");
5020
+ const root = roots.includes("names") && pos.names.length > 0 && (others.length === 0 || rng.chance(.75)) || others.length === 0 ? "names" : rng.pick(others);
4655
5021
  const path = [root];
4656
5022
  if (root === "names") path.push(pickName(pos.names));
4657
5023
  if (root === "world") path.push(String(rng.pick(types)[0]));
4658
- for (let index = rng.int(3); index > 0; index -= 1) if (stepTypes.length > 0 && rng.chance(.2)) {
5024
+ for (let index = rng.int(steps + 1); index > 0; index -= 1) if (stepTypes.length > 0 && rng.chance(.2)) {
4659
5025
  const type = rng.pick(stepTypes);
4660
5026
  const kind = kindOf(type);
4661
5027
  const value = refKind?.parts?.shape === "deep" && kind?.parts !== void 0 ? valueOf(kind.parts, [], {
@@ -4804,9 +5170,17 @@ function generate(world, options) {
4804
5170
  case "one": return rng.chance(malformed) ? "other" : rng.pick(shape.values);
4805
5171
  }
4806
5172
  };
4807
- /** A malformed document: an unknown kind, a bad shape, a bare value without a type, or a bad reference. */
5173
+ /**
5174
+ * A malformed document: an unknown kind, or an unknown name under a namespace with a fallback. It can also be a
5175
+ * bad shape, a bare value without a type, or a bad reference.
5176
+ */
4808
5177
  const brokenAt = (pos) => {
4809
5178
  const roll = rng.int(5);
5179
+ if (roll === 0 && unknownNames.length > 0 && rng.chance(.5)) {
5180
+ const type = rng.pick(unknownNames);
5181
+ const kind = kindOf(type);
5182
+ return envelope(type, kind?.parts === void 0 ? dataOf(type) : valueOf(kind.parts, [], pos, scopeOf(kind), type));
5183
+ }
4810
5184
  if (roll === 0) return {
4811
5185
  type: rng.pick(["nothing", ["no", "such"]]),
4812
5186
  value: 1
@@ -4844,7 +5218,10 @@ function generate(world, options) {
4844
5218
  size += 1;
4845
5219
  const leaf = pos.depth >= maxDepth || size >= maxSize;
4846
5220
  if (rng.chance(malformed)) return brokenAt(pos);
4847
- if (pos.declared !== void 0 && rng.chance(leaf ? .7 : .3)) return dataOf([pos.declared]);
5221
+ if (pos.declared !== void 0 && rng.chance(leaf ? .7 : .3)) {
5222
+ const bare = dataOf([pos.declared]);
5223
+ if (!isEnvelope(bare) || permitted(typePath(bare.type) ?? [], pos.kinds)) return bare;
5224
+ }
4848
5225
  let candidates = types.filter((type) => permitted(type, pos.kinds) && (!leaf || leafKind(kindOf(type))));
4849
5226
  if (pos.hint !== void 0 && rng.chance(.6)) {
4850
5227
  const hinted = candidates.filter((type) => pos.hint?.some((hint) => hint.length === type.length && hint.every((key, index) => key === type[index])));
@@ -4866,6 +5243,6 @@ function generate(world, options) {
4866
5243
  });
4867
5244
  }
4868
5245
  //#endregion
4869
- 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, agree, ask, capKeys, check, checkSteps, classify, context, dataEdges, derefStep, describe, docEquals, effectEdges, entriesAsJson, evaluate, fail, failures, field, flatten, formulaDefinitions, formulaEvaluators, formulaKinds, formulaMachine, fromJson, generate, 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, random, ref, reference, refsOf, resolve, run, sameValue, splitParts, stored, tag, thrown, toJson, typeName, typePath, typed, typesOf, valueOfThing, walk, worldThing };
5246
+ export { CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_WALKERS, STD_WORLD, THING, agree, ask, capKeys, check, checkSteps, classify, context, dataEdges, derefStep, describe, docEquals, effectEdges, entriesAsJson, evaluate, fail, failures, field, flatten, formulaDefinitions, formulaEvaluators, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, 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, partsOf, pathMatches, permits, placed, planner, prepare, random, ref, reference, refsOf, resolve, run, sameValue, splitParts, stored, tag, thrown, toJson, typeName, typePath, typed, typesOf, valueOfThing, walk, worldThing };
4870
5247
 
4871
5248
  //# sourceMappingURL=index.js.map