@mark1russell7/coeval 0.13.0 → 0.15.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
@@ -2905,6 +2905,12 @@ function partCaps(rules, path, caps) {
2905
2905
  */
2906
2906
  const GRANT = /* @__PURE__ */ Symbol("coeval.grant");
2907
2907
  /**
2908
+ * The key of the epoch of a grant (CAP.NARROW-KEPT). The epoch is the list of capabilities that the host gave the root
2909
+ * of the evaluation of the grant. A spread of a context keeps its epoch, as it keeps its grant. An
2910
+ * effect and a resolution read a context of another epoch as a context without a grant.
2911
+ */
2912
+ const EPOCH = /* @__PURE__ */ Symbol("coeval.epoch");
2913
+ /**
2908
2914
  * This function gives the capabilities that a context and its grant both permit, the meet `intersectCaps` (CAP.MEET).
2909
2915
  * A context whose grant is its own list gives that list after one comparison. A context without a grant gives none.
2910
2916
  */
@@ -2928,12 +2934,27 @@ function granted(ctx) {
2928
2934
  };
2929
2935
  }
2930
2936
  /**
2937
+ * This function gives a context of another epoch the epoch of the evaluation, without capabilities (CAP.NARROW-KEPT).
2938
+ * Thus the context reads as a context without a grant. The kernel cannot know the document of the context in this
2939
+ * evaluation.
2940
+ */
2941
+ function ungranted(ctx, epoch) {
2942
+ return {
2943
+ ...ctx,
2944
+ caps: NO_CAPS$2,
2945
+ [GRANT]: NO_CAPS$2,
2946
+ [EPOCH]: epoch
2947
+ };
2948
+ }
2949
+ /**
2931
2950
  * This function gives the context in which the runtime resolves a path of compiled code (CAP.CAPS-GRANT, CAP.MEET).
2932
2951
  * The context has the meet of its list and its grant, and a context without a grant has none. Thus a read of the root
2933
2952
  * `caps` and a walker of a step document get the capabilities of the document from a widened context.
2934
2953
  * A context that the code narrowed keeps its own list. A context whose list does not change stays the same object.
2954
+ * A context of another epoch has no capabilities (CAP.NARROW-KEPT).
2935
2955
  */
2936
- function readable(ctx) {
2956
+ function readable(ctx, epoch) {
2957
+ if (ctx[EPOCH] !== epoch) return ctx.caps.length === 0 ? ctx : ungranted(ctx, epoch);
2937
2958
  const caps = grantedCaps(ctx);
2938
2959
  if (caps === ctx.caps || caps.length === 0 && ctx.caps.length === 0) return ctx;
2939
2960
  return {
@@ -2944,14 +2965,17 @@ function readable(ctx) {
2944
2965
  }
2945
2966
  /**
2946
2967
  * This function gives the context of a part of a function evaluator. It is the context that the evaluator gives,
2947
- * narrowed by the context of the document (CAP.NARROW), with the grant of its capabilities.
2968
+ * narrowed by the context of the document (CAP.NARROW), with the grant of its capabilities. The grant has the epoch
2969
+ * of the document, because the document permits each of its capabilities (CAP.NARROW-KEPT).
2948
2970
  */
2949
2971
  function handed(parent, next) {
2950
2972
  const ctx = narrow(parent, next);
2951
- if (ctx[GRANT] === ctx.caps) return ctx;
2973
+ const epoch = parent[EPOCH];
2974
+ if (ctx[GRANT] === ctx.caps && ctx[EPOCH] === epoch) return ctx;
2952
2975
  return {
2953
2976
  ...ctx,
2954
- [GRANT]: ctx.caps
2977
+ [GRANT]: ctx.caps,
2978
+ [EPOCH]: epoch
2955
2979
  };
2956
2980
  }
2957
2981
  /** The text that names a resolution in the error of an exception of the host. */
@@ -3058,6 +3082,28 @@ const NO_ANSWER = {
3058
3082
  /** The options of a resolution without a record of hops, and with one. One object of each serves each call. */
3059
3083
  const WITHOUT_HOPS = /* @__PURE__ */ Object.freeze({ hops: false });
3060
3084
  const WITH_HOPS = /* @__PURE__ */ Object.freeze({ hops: true });
3085
+ /**
3086
+ * This function gives the path of a kept read (READS.CLOSURE). The evaluation did not ask for the read. Thus the read
3087
+ * does not step into a host thing, and the path ends at the first host thing. The host gives a new thing for a new state.
3088
+ * A reference in the data reads the context of its reader, thus the function then gives `undefined`.
3089
+ *
3090
+ * @param nav - The world and the code of the evaluators.
3091
+ * @param root - The context at the root of the evaluation.
3092
+ * @param path - The root and the keys of the static read.
3093
+ * @returns The path of the kept read, or `undefined` for a reference on the way.
3094
+ */
3095
+ function keptPath(nav, root, path) {
3096
+ const adopt = nav.adopt ?? ((value) => value);
3097
+ let here = adopt(root[path[0]]);
3098
+ for (let index = 1;; index += 1) {
3099
+ if (isHostThing(here)) return index === path.length ? path : path.slice(0, index);
3100
+ if (nav.plain !== true && isRef(here)) return void 0;
3101
+ if (index >= path.length) return path;
3102
+ const reached = derefStep(nav, here, path[index]);
3103
+ if (reached === void 0) return path;
3104
+ here = adopt(reached.thing);
3105
+ }
3106
+ }
3061
3107
  /** This function makes the record of the reads of an evaluation, when the host gives a list. */
3062
3108
  function readingOf(list, root) {
3063
3109
  return list === void 0 ? void 0 : {
@@ -3070,6 +3116,7 @@ function readingOf(list, root) {
3070
3116
  /** This class holds the state of one evaluation or run: the machine, the effects, the clock and the trace. */
3071
3117
  var Session = class {
3072
3118
  machine;
3119
+ epoch;
3073
3120
  running;
3074
3121
  traced;
3075
3122
  perform;
@@ -3086,8 +3133,9 @@ var Session = class {
3086
3133
  * root scope is made at the first effect or `all`, thus an evaluation without effects makes no scope.
3087
3134
  */
3088
3135
  scope;
3089
- constructor(machine, running, traced, perform, signal, effects, reading = void 0) {
3136
+ constructor(machine, epoch, running, traced, perform, signal, effects, reading = void 0) {
3090
3137
  this.machine = machine;
3138
+ this.epoch = epoch;
3091
3139
  this.running = running;
3092
3140
  this.traced = traced;
3093
3141
  this.perform = perform;
@@ -3110,7 +3158,7 @@ var Session = class {
3110
3158
  * `caps` and a walker of a step document get the capabilities of the document.
3111
3159
  */
3112
3160
  resolve(ctx, path, options) {
3113
- return this.read(readable(ctx), path, void 0, options);
3161
+ return this.read(readable(ctx, this.epoch), path, void 0, options);
3114
3162
  }
3115
3163
  /**
3116
3164
  * This function resolves a compiled path (PLAN.PATH). Without a list of reads and without a trace, the compiled
@@ -3118,7 +3166,7 @@ var Session = class {
3118
3166
  * that the grant permits (CAP.CAPS-GRANT, CAP.MEET).
3119
3167
  */
3120
3168
  resolvePath(given, compiled) {
3121
- const ctx = readable(given);
3169
+ const ctx = readable(given, this.epoch);
3122
3170
  if (this.reading === void 0 && !this.traced && compiled.nav === this.machine) return compiled.resolve(ctx);
3123
3171
  return this.read(ctx, compiled.path, compiled, void 0);
3124
3172
  }
@@ -3162,13 +3210,45 @@ var Session = class {
3162
3210
  if (compiled !== void 0 && !hops && compiled.nav === this.machine) return compiled.resolve(ctx);
3163
3211
  return resolve(this.machine, ctx, path, hops ? WITH_HOPS : WITHOUT_HOPS);
3164
3212
  }
3165
- keepsContext() {
3213
+ keepsContext(ctx, reads) {
3166
3214
  const reading = this.reading;
3167
3215
  if (reading === void 0 || reading.kept) return;
3216
+ const known = ctx === void 0 ? void 0 : reads?.();
3217
+ if (ctx !== void 0 && known !== void 0 && known.every((read) => this.keepRead(reading, ctx, read))) return;
3168
3218
  reading.kept = true;
3169
3219
  this.keep(reading, reading.self ? ROOTS.filter((root) => root !== "self") : ROOTS);
3170
3220
  }
3171
3221
  /**
3222
+ * This function adds the kept read of one static read of a closure (READS.CLOSURE). The read resolves from the
3223
+ * context at the root, one time in an evaluation. A name that a kind binds in the kept context gives no read,
3224
+ * because the reads of its binding are already in the list.
3225
+ *
3226
+ * @returns `false` when the path meets a reference in the data. Then the closure keeps each whole root.
3227
+ */
3228
+ keepRead(reading, ctx, read) {
3229
+ const root = read.root;
3230
+ const exact = [root, ...read.keys];
3231
+ if (!isFree(reading.root, ctx, exact)) {
3232
+ if (root === "self" && !reading.self) this.keep(reading, ["self"]);
3233
+ return true;
3234
+ }
3235
+ if (root === "self" && reading.self) return true;
3236
+ const path = keptPath(this.machine, reading.root, read.exact ? exact : [root]);
3237
+ if (path === void 0) return false;
3238
+ const paths = reading.paths ??= /* @__PURE__ */ new Set();
3239
+ const text = JSON.stringify(path);
3240
+ if (paths.has(text) || paths.has(JSON.stringify([root]))) return true;
3241
+ paths.add(text);
3242
+ if (path.length === 1 && root === "self") reading.self = true;
3243
+ reading.list.push({
3244
+ path,
3245
+ reached: readAgain(this.machine, reading.root, path, false).reached,
3246
+ free: true,
3247
+ kept: true
3248
+ });
3249
+ return true;
3250
+ }
3251
+ /**
3172
3252
  * This function adds a read of each whole root to the list, from the context at the root (READS.KEPT). An exception
3173
3253
  * of the host gives the error value of the read, because the evaluation did not ask for the read.
3174
3254
  */
@@ -3190,10 +3270,11 @@ var Session = class {
3190
3270
  /**
3191
3271
  * This function checks the capability of an effect, and records the effect with its address (RUN.ADDRESS). The
3192
3272
  * context keeps only the capabilities of its grant, thus compiled code cannot widen the context of its own effect
3193
- * (CAP.NARROW-CODE).
3273
+ * (CAP.NARROW-CODE). A context of another epoch has no capabilities, thus code cannot keep a context for a later
3274
+ * evaluation with fewer capabilities (CAP.NARROW-KEPT).
3194
3275
  */
3195
3276
  record(given, kind, payload, place) {
3196
- const ctx = granted(given);
3277
+ const ctx = given[EPOCH] === this.epoch ? granted(given) : ungranted(given, this.epoch);
3197
3278
  const keys = typeof kind === "string" ? kind.split(".") : kind;
3198
3279
  const text = keys.join(".");
3199
3280
  if (!this.permitted(ctx, keys)) return fail("#CAP!", `The context has no capability for the effect ${text}.`, { place });
@@ -4027,18 +4108,20 @@ function interpretRun(fn, input, fill) {
4027
4108
  /**
4028
4109
  * This function gives the context at the root of an evaluation. It is the context of the host, with the world of
4029
4110
  * the machine when the context has none. The host gives the capabilities, thus the root has the grant of each one
4030
- * (CAP.NARROW-CODE). An evaluation and `verifyReads` share it.
4111
+ * (CAP.NARROW-CODE). The list of the host is also the epoch of the grant (CAP.NARROW-KEPT). An evaluation and
4112
+ * `verifyReads` share it.
4031
4113
  *
4032
4114
  * @param machine - The machine.
4033
4115
  * @param ctx - The context of the host.
4034
4116
  * @returns The context at the root.
4035
4117
  */
4036
4118
  function rootContext(machine, ctx) {
4037
- if (ctx.world !== null && ctx[GRANT] === ctx.caps) return ctx;
4119
+ if (ctx.world !== null && ctx[GRANT] === ctx.caps && ctx[EPOCH] === ctx.caps) return ctx;
4038
4120
  return {
4039
4121
  ...ctx,
4040
4122
  world: ctx.world === null ? worldThing(machine.world) : ctx.world,
4041
- [GRANT]: ctx.caps
4123
+ [GRANT]: ctx.caps,
4124
+ [EPOCH]: ctx.caps
4042
4125
  };
4043
4126
  }
4044
4127
  /**
@@ -4109,13 +4192,13 @@ var CompiledPlan = class {
4109
4192
  evaluate(context = makeContext(), evalOptions) {
4110
4193
  const machine = this.machine;
4111
4194
  const ctx = rootContext(machine, context);
4112
- const s = new Session(machine, false, this.traced, evalOptions?.perform, void 0, evalOptions?.effects, readingOf(evalOptions?.reads, ctx));
4195
+ const s = new Session(machine, ctx.caps, false, this.traced, evalOptions?.perform, void 0, evalOptions?.effects, readingOf(evalOptions?.reads, ctx));
4113
4196
  return this.code(ctx, s);
4114
4197
  }
4115
4198
  run(context = makeContext(), runOptions = {}) {
4116
4199
  const machine = this.machine;
4117
4200
  const ctx = rootContext(machine, context);
4118
- const s = new Session(machine, true, this.traced, runOptions.perform, runOptions.signal, void 0, readingOf(runOptions.reads, ctx));
4201
+ const s = new Session(machine, ctx.caps, true, this.traced, runOptions.perform, runOptions.signal, void 0, readingOf(runOptions.reads, ctx));
4119
4202
  return driveWaiting(this.runCode()(ctx, s), runOptions.signal);
4120
4203
  }
4121
4204
  };
@@ -4184,7 +4267,7 @@ function evaluate(machine, doc, context = makeContext(), options) {
4184
4267
  ...given.verb === void 0 ? {} : { verb: given.verb }
4185
4268
  });
4186
4269
  const ctx = rootContext(machine, context);
4187
- const s = new Session(machine, false, true, given.perform, void 0, void 0, readingOf(given.reads, ctx));
4270
+ const s = new Session(machine, ctx.caps, false, true, given.perform, void 0, void 0, readingOf(given.reads, ctx));
4188
4271
  return record(s, plan.code(ctx, s));
4189
4272
  }
4190
4273
  /**
@@ -4205,7 +4288,7 @@ async function run(machine, doc, context = makeContext(), options = {}) {
4205
4288
  ...options.verb === void 0 ? {} : { verb: options.verb }
4206
4289
  });
4207
4290
  const ctx = rootContext(machine, context);
4208
- const s = new Session(machine, true, true, options.perform, options.signal, void 0, readingOf(options.reads, ctx));
4291
+ const s = new Session(machine, ctx.caps, true, true, options.perform, options.signal, void 0, readingOf(options.reads, ctx));
4209
4292
  return record(s, await driveWaiting(plan.runCode()(ctx, s), options.signal));
4210
4293
  }
4211
4294
  /**
@@ -7510,7 +7593,7 @@ function formulaCode(profile) {
7510
7593
  }, rt);
7511
7594
  };
7512
7595
  }),
7513
- "formula.fn": compiled(({ value, data }) => {
7596
+ "formula.fn": compiled(({ value, data, doc, machine }) => {
7514
7597
  const params = isRecord(data) ? data["params"] : void 0;
7515
7598
  if (!Array.isArray(params) || !params.every((param) => typeof param === "string") || new Set(params).size !== params.length) {
7516
7599
  const bad = fail("#VALUE!", "The params of fn are a list of different texts.");
@@ -7518,8 +7601,19 @@ function formulaCode(profile) {
7518
7601
  }
7519
7602
  const names = params;
7520
7603
  const body = partsOf$1(value)["body"];
7604
+ let known = null;
7605
+ const reads = () => {
7606
+ if (known !== null) return known;
7607
+ try {
7608
+ const facts = factsOf(machine, doc);
7609
+ known = facts.pure ? facts.reads : void 0;
7610
+ } catch {
7611
+ known = void 0;
7612
+ }
7613
+ return known;
7614
+ };
7521
7615
  return (ctx, rt) => {
7522
- rt.keepsContext?.();
7616
+ rt.keepsContext?.(ctx, reads);
7523
7617
  const closure = (...args) => {
7524
7618
  const scope = { ...ctx.names };
7525
7619
  names.forEach((name, index) => setOwn$1(scope, name, args[index]));
@@ -8733,6 +8827,42 @@ function resolveFully(machine, ctx, path, options) {
8733
8827
  * mock, the effect gives its payload (RUN.EVAL).
8734
8828
  */
8735
8829
  function cause(env, ctx, kind, payload, place) {
8830
+ const effect = recordEffect(env, ctx, kind, payload, place);
8831
+ if ("ok" in effect) return effect;
8832
+ effect.outcome = answer(env.perform, effect, place);
8833
+ return effect.outcome;
8834
+ }
8835
+ /**
8836
+ * This function causes the effect of an evaluator. In a run, the host does each effect, thus only a runner can cause
8837
+ * one. The effect then gives `#CALC!` before the test of its capability (RUN.NEEDS-RUNNER).
8838
+ */
8839
+ function causeFromEvaluator(env, ctx, kind, payload, place) {
8840
+ const text = typeof kind === "string" ? kind : kind.join(".");
8841
+ if (env.running) return fail("#CALC!", `The effect ${text} needs a runner: in a run, the host does each effect.`, { place });
8842
+ return cause(env, ctx, kind, payload, place);
8843
+ }
8844
+ /**
8845
+ * This function causes the effect of a runner. In an evaluation, the mock answers it at once. In a run, the host does
8846
+ * it, and a promise from the host makes the steps wait (RUN.SEQ). An effect whose wait a stop ends keeps no outcome
8847
+ * (RUN.OUTCOME).
8848
+ */
8849
+ function* causeAndWait(env, ctx, kind, payload, place) {
8850
+ if (!env.running) return cause(env, ctx, kind, payload, place);
8851
+ const effect = recordEffect(env, ctx, kind, payload, place);
8852
+ if ("ok" in effect) return effect;
8853
+ const perform = env.perform;
8854
+ if (perform === void 0) return effect.outcome = ok(payload);
8855
+ let given;
8856
+ try {
8857
+ given = perform(effect);
8858
+ } catch (error) {
8859
+ return effect.outcome = hostError(effect, place, error);
8860
+ }
8861
+ if (!(given instanceof Promise)) return effect.outcome = ok(given);
8862
+ return effect.outcome = yield given.then((value) => ok(value), (error) => hostError(effect, place, error));
8863
+ }
8864
+ /** This function checks the capability of an effect, and records the effect with its address (RUN.CAP, RUN.ADDRESS). */
8865
+ function recordEffect(env, ctx, kind, payload, place) {
8736
8866
  const keys = typeof kind === "string" ? kind.split(".") : kind;
8737
8867
  const text = keys.join(".");
8738
8868
  const machine = env.machine;
@@ -8752,8 +8882,18 @@ function cause(env, ctx, kind, payload, place) {
8752
8882
  address: `${env.scope.prefix}${at}#${count}`
8753
8883
  };
8754
8884
  env.effects.push(effect);
8755
- effect.outcome = answer(env.perform, effect, place);
8756
- return effect.outcome;
8885
+ return effect;
8886
+ }
8887
+ /** This function gives the outcome of an effect that the host failed. A `Failure` gives its own error value (RUN.CAUSE). */
8888
+ function hostError(effect, place, error) {
8889
+ if (error instanceof Failure) return placed({
8890
+ ok: false,
8891
+ error: error.error
8892
+ }, place);
8893
+ return fail("#CALC!", `The host failed the effect ${effect.kind}: ${describe(error)}`, {
8894
+ place,
8895
+ cause: error
8896
+ });
8757
8897
  }
8758
8898
  /**
8759
8899
  * This function gives the answer of the mock to an effect. A throw gives `#CALC!` with the cause, and a `Failure`
@@ -8765,14 +8905,7 @@ function answer(perform, effect, place) {
8765
8905
  try {
8766
8906
  given = perform(effect);
8767
8907
  } catch (error) {
8768
- if (error instanceof Failure) return placed({
8769
- ok: false,
8770
- error: error.error
8771
- }, place);
8772
- return fail("#CALC!", `The host failed the effect ${effect.kind}: ${describe(error)}`, {
8773
- place,
8774
- cause: error
8775
- });
8908
+ return hostError(effect, place, error);
8776
8909
  }
8777
8910
  if (!(given instanceof Promise)) return ok(given);
8778
8911
  given.catch(() => void 0);
@@ -8843,7 +8976,7 @@ function evalInput(env, seen, at) {
8843
8976
  machine: env.machine,
8844
8977
  ...at.address ? { address: true } : {},
8845
8978
  resolve: (path, options) => resolveFully(env.machine, at.ctx, path, options),
8846
- effect: (kind, payload) => cause(env, at.ctx, kind, payload, at.place),
8979
+ effect: (kind, payload) => causeFromEvaluator(env, at.ctx, kind, payload, at.place),
8847
8980
  fill
8848
8981
  };
8849
8982
  }
@@ -8870,67 +9003,116 @@ function runInput(env, seen, at) {
8870
9003
  place: at.place,
8871
9004
  machine: env.machine,
8872
9005
  resolve: (path, options) => resolveFully(env.machine, at.ctx, path, options),
8873
- effect: function* (kind, payload) {
8874
- return cause(env, at.ctx, kind, payload, at.place);
8875
- },
9006
+ effect: (kind, payload) => causeAndWait(env, at.ctx, kind, payload, at.place),
8876
9007
  all: (list, options) => together(env, list, options),
8877
9008
  fill
8878
9009
  };
8879
9010
  }
8880
9011
  /**
8881
9012
  * This function evaluates parts for `all` (RUN.ALL). The parts start in their order, up to the limit, and each part
8882
- * goes on until it ends or waits. In an evaluation, a part that waits does not end, thus it keeps its place in the
8883
- * limit. With `failFast`, the first failure stops the parts that wait, and the later parts do not start
8884
- * (RUN.FAIL-FAST). When no part failed and a part waits, the steps wait, and the drive gives `#CALC!`.
9013
+ * goes on until it ends or waits. A part that waits keeps its place in the limit. With `failFast`, the first failure
9014
+ * stops the parts that wait, and the later parts do not start (RUN.FAIL-FAST).
9015
+ *
9016
+ * When a part waits, the steps wait for the next part that settles. The journal of the host can choose that part
9017
+ * (RUN.REPLAY), and it gets each part that settled (RUN.RECORD). In an evaluation, the drive stops at the first wait
9018
+ * and gives `#CALC!`. In a run, the host settles the wait, and the part goes on in its own scope.
8885
9019
  *
8886
9020
  * Each part has its own scope of addresses. Its prefix names the use of `all` in the scope around it, and the part
8887
9021
  * (RUN.ADDRESS).
8888
9022
  */
8889
9023
  function* together(env, list, options = {}) {
8890
9024
  const limit = Math.max(1, options.concurrency ?? list.length);
9025
+ const failFast = options.failFast === true;
8891
9026
  const results = list.map(() => void 0);
9027
+ const scopes = [];
8892
9028
  const waiting = [];
8893
9029
  const outer = env.scope;
8894
9030
  const address = `${outer.prefix}all${outer.alls}`;
8895
9031
  outer.alls += 1;
8896
9032
  let failed = false;
8897
- for (let index = 0; index < list.length && !failed && waiting.length < limit; index += 1) {
8898
- let result;
8899
- env.scope = {
8900
- prefix: `${address}.${index}/`,
8901
- counts: /* @__PURE__ */ new Map(),
8902
- alls: 0
8903
- };
9033
+ let started = 0;
9034
+ const end = (index, result) => {
9035
+ results[index] = result;
9036
+ if (failFast && !result.ok) failed = true;
9037
+ };
9038
+ /** This function gives a part its input in its own scope, and keeps it in the list when it waits again. */
9039
+ const goOn = (index, steps, input) => {
9040
+ const around = env.scope;
9041
+ env.scope = scopes[index];
9042
+ let step;
8904
9043
  try {
8905
- const steps = list[index].evaluate();
8906
- const step = steps.next();
8907
- if (step.done === true) result = step.value;
8908
- else waiting.push({
8909
- steps,
8910
- promise: step.value
8911
- });
9044
+ step = input.threw ? steps.throw(input.error) : steps.next(input.value);
8912
9045
  } catch (error) {
8913
- result = thrown(error, "a part");
9046
+ end(index, thrown(error, "a part"));
9047
+ return;
8914
9048
  } finally {
8915
- env.scope = outer;
9049
+ env.scope = around;
8916
9050
  }
8917
- results[index] = result;
8918
- if (result !== void 0 && options.failFast === true && !result.ok) failed = true;
8919
- }
8920
- if (failed) {
8921
- const stopped = fail("#ABORT", "The part stopped: a part before it failed, and the parts run with failFast.");
8922
- for (const item of waiting) try {
8923
- item.steps.return(stopped);
8924
- } catch {}
8925
- return results.map((result) => result ?? stopped);
9051
+ if (step.done === true) {
9052
+ end(index, step.value);
9053
+ return;
9054
+ }
9055
+ const waiter = {
9056
+ index,
9057
+ steps,
9058
+ next: Promise.resolve()
9059
+ };
9060
+ waiter.next = step.value.then((value) => ({
9061
+ waiter,
9062
+ value,
9063
+ threw: false
9064
+ }), (error) => ({
9065
+ waiter,
9066
+ error,
9067
+ threw: true
9068
+ }));
9069
+ waiting.push(waiter);
9070
+ };
9071
+ /** This function starts the next parts in their order, while the limit permits it and no part failed. */
9072
+ const startMore = () => {
9073
+ while (!failed && waiting.length < limit && started < list.length) {
9074
+ const index = started;
9075
+ started += 1;
9076
+ scopes[index] = {
9077
+ prefix: `${address}.${index}/`,
9078
+ counts: /* @__PURE__ */ new Map(),
9079
+ alls: 0
9080
+ };
9081
+ const around = env.scope;
9082
+ env.scope = scopes[index];
9083
+ let steps;
9084
+ try {
9085
+ steps = list[index].evaluate();
9086
+ } catch (error) {
9087
+ end(index, thrown(error, "a part"));
9088
+ continue;
9089
+ } finally {
9090
+ env.scope = around;
9091
+ }
9092
+ goOn(index, steps, { threw: false });
9093
+ }
9094
+ };
9095
+ startMore();
9096
+ while (waiting.length > 0 && !failed) {
9097
+ const chosen = env.journal?.next?.(address, waiting.map((waiter) => waiter.index));
9098
+ const pick = chosen === void 0 ? void 0 : waiting.find((waiter) => waiter.index === chosen);
9099
+ const resumed = yield pick === void 0 ? Promise.race(waiting.map((waiter) => waiter.next)) : pick.next;
9100
+ env.journal?.settled?.(address, resumed.waiter.index);
9101
+ waiting.splice(waiting.indexOf(resumed.waiter), 1);
9102
+ goOn(resumed.waiter.index, resumed.waiter.steps, resumed);
9103
+ startMore();
8926
9104
  }
8927
- if (waiting.length > 0) yield Promise.race(waiting.map((item) => item.promise));
8928
- return results;
9105
+ if (!failed) return results;
9106
+ const stopped = fail("#ABORT", "The part stopped: a part before it failed, and the parts run with failFast.");
9107
+ for (const waiter of waiting) try {
9108
+ waiter.steps.return(stopped);
9109
+ } catch {}
9110
+ return results.map((result) => result ?? stopped);
8929
9111
  }
8930
9112
  /**
8931
9113
  * This function evaluates a document by the rules, without a compilation. It is the reference of the plans: a plan,
8932
- * a traced plan and the second tier of a language must give its results. It covers evaluations, not runs: an effect
8933
- * gives the answer of the mock or its payload, and a part that waits gives `#CALC!`.
9114
+ * a traced plan and the second tier of a language must give its results. In an evaluation, an effect gives the answer
9115
+ * of the mock or its payload, and a part that waits gives `#CALC!`. `referenceRun` reads the rules of a run.
8934
9116
  *
8935
9117
  * The verb of the options goes up the ladder at each document, as in `prepare`. Each verb has the same rules: the
8936
9118
  * ladder, the contract of the kind and the sealed parts (VERB.AGREE).
@@ -8942,12 +9124,43 @@ function* together(env, list, options = {}) {
8942
9124
  * @returns The result.
8943
9125
  */
8944
9126
  function reference(machine, doc, context = makeContext(), options = {}) {
8945
- const env = {
9127
+ const env = envOf(machine, options, false);
9128
+ try {
9129
+ return within(env, () => evaluateAt(env, rootAt(machine, doc, context, options)));
9130
+ } catch (error) {
9131
+ return placed(thrown(error, "the reference"), []);
9132
+ }
9133
+ }
9134
+ /**
9135
+ * This function starts a run of a document by the rules, without a compilation (REF.RUN). The host does each effect of a runner,
9136
+ * and a step waits when the host waits (RUN.SEQ). `all` settles the waits in the order of the host, or in the order
9137
+ * of the journal of a replay (RUN.REPLAY). An effect of an evaluator gives `#CALC!` (RUN.NEEDS-RUNNER). A signal that
9138
+ * aborts stops the run with `#ABORT` (RUN.ABORT).
9139
+ *
9140
+ * The part of the run before the first wait happens at once, in the call (RUN.EAGER). `agreeRun` compares the run of
9141
+ * a plan with this run.
9142
+ *
9143
+ * @param machine - The world, the evaluators and the runners.
9144
+ * @param doc - The document.
9145
+ * @param context - The names and the capabilities at the root.
9146
+ * @param options - The options of `reference`, the host and a signal.
9147
+ * @returns The result, when the run ends.
9148
+ */
9149
+ function referenceRun(machine, doc, context = makeContext(), options = {}) {
9150
+ const env = envOf(machine, options, true);
9151
+ return driveRun(env, stepsAt(env, rootAt(machine, doc, context, options)), options.signal).catch((error) => placed(thrown(error, "the reference"), []));
9152
+ }
9153
+ /** This function makes the state of the reference for one evaluation or one run. */
9154
+ function envOf(machine, options, running) {
9155
+ const perform = options.perform;
9156
+ return {
8946
9157
  machine,
8947
9158
  definitions: options.definitions ?? {},
8948
9159
  effects: options.effects ?? [],
8949
9160
  maxDepth: machine.maxDepth ?? 1e3,
8950
- perform: options.perform,
9161
+ perform,
9162
+ journal: perform === void 0 ? void 0 : perform[JOURNAL],
9163
+ running,
8951
9164
  verb: options.verb ?? "eval",
8952
9165
  scope: {
8953
9166
  prefix: "",
@@ -8955,26 +9168,66 @@ function reference(machine, doc, context = makeContext(), options = {}) {
8955
9168
  alls: 0
8956
9169
  }
8957
9170
  };
9171
+ }
9172
+ /** This function gives the root position of a document. A context without a world gets the world of the machine. */
9173
+ function rootAt(machine, doc, context, options) {
8958
9174
  const ctx = context.world === null ? {
8959
9175
  ...context,
8960
9176
  world: worldThing(machine.world)
8961
9177
  } : context;
9178
+ return {
9179
+ value: doc,
9180
+ place: [],
9181
+ declared: options.declaredType,
9182
+ depth: 0,
9183
+ address: false,
9184
+ ctx
9185
+ };
9186
+ }
9187
+ /**
9188
+ * This function does one synchronous step of an evaluation or a run. A node of a tree reads the definitions of the
9189
+ * evaluation for its equations (TREE.LADDER). Thus the state of the evaluation is the innermost one in the step.
9190
+ */
9191
+ function within(env, step) {
8962
9192
  activeEnvs.push(env);
8963
9193
  try {
8964
- return evaluateAt(env, {
8965
- value: doc,
8966
- place: [],
8967
- declared: options.declaredType,
8968
- depth: 0,
8969
- address: false,
8970
- ctx
8971
- });
8972
- } catch (error) {
8973
- return placed(thrown(error, "the reference"), []);
9194
+ return step();
8974
9195
  } finally {
8975
9196
  activeEnvs.pop();
8976
9197
  }
8977
9198
  }
9199
+ /** The mark of a signal that aborted. */
9200
+ const STOPPED$1 = /* @__PURE__ */ Symbol("stopped");
9201
+ /**
9202
+ * This function drives the steps of a run. Each step waits for its promise. A rejection goes into the steps as an
9203
+ * exception. A signal that aborts stops the steps with `#ABORT`, also before the first step (RUN.ABORT).
9204
+ */
9205
+ async function driveRun(env, steps, signal) {
9206
+ const stop = () => {
9207
+ const aborted = fail("#ABORT", `The host stopped the run: ${describe(signal?.reason ?? "no reason")}`, { cause: signal?.reason });
9208
+ try {
9209
+ within(env, () => steps.return(aborted));
9210
+ } catch {}
9211
+ return aborted;
9212
+ };
9213
+ if (signal?.aborted === true) return stop();
9214
+ const stopping = signal === void 0 ? void 0 : new Promise((resolve) => {
9215
+ signal.addEventListener("abort", () => resolve(STOPPED$1), { once: true });
9216
+ });
9217
+ let step = within(env, () => steps.next());
9218
+ while (step.done !== true) {
9219
+ let input;
9220
+ try {
9221
+ input = await (stopping === void 0 ? step.value : Promise.race([step.value, stopping]));
9222
+ } catch (error) {
9223
+ step = within(env, () => steps.throw(error));
9224
+ continue;
9225
+ }
9226
+ if (input === STOPPED$1) return stop();
9227
+ step = within(env, () => steps.next(input));
9228
+ }
9229
+ return step.value;
9230
+ }
8978
9231
  /** The evaluations of the reference that run at this time, the innermost last. */
8979
9232
  const activeEnvs = [];
8980
9233
  const refNodes = /* @__PURE__ */ new WeakMap();
@@ -9408,6 +9661,101 @@ function valuesOfStrict(parts) {
9408
9661
  return { values };
9409
9662
  }
9410
9663
  //#endregion
9664
+ //#region src/replay.ts
9665
+ /**
9666
+ * This function makes a recorder (RUN.RECORD). The recorder gives each effect to the function `perform` of the host.
9667
+ * Its log keeps each effect with its address, its kind, its payload and the outcome that the kernel gives it. The log
9668
+ * also keeps the order in which the waits of each `all` settle.
9669
+ *
9670
+ * @param perform - The function of the host. Without it, each effect gives its payload, as in a run without a host.
9671
+ * @returns The function `perform` for the run, and the log.
9672
+ */
9673
+ function recorder(perform) {
9674
+ const seen = [];
9675
+ const settles = [];
9676
+ const journal = { settled: (all, item) => {
9677
+ settles.push({
9678
+ all,
9679
+ item
9680
+ });
9681
+ } };
9682
+ const host = (effect) => {
9683
+ const entry = {
9684
+ effect,
9685
+ waited: false
9686
+ };
9687
+ seen.push(entry);
9688
+ const answer = perform === void 0 ? effect.payload : perform(effect);
9689
+ if (answer instanceof Promise) entry.waited = true;
9690
+ return answer;
9691
+ };
9692
+ return {
9693
+ perform: Object.assign(host, { [JOURNAL]: journal }),
9694
+ log: () => ({
9695
+ effects: seen.map(({ effect, waited }) => ({
9696
+ address: effect.address ?? "",
9697
+ kind: effect.kind,
9698
+ payload: effect.payload,
9699
+ waited,
9700
+ ...effect.outcome === void 0 ? {} : { outcome: effect.outcome }
9701
+ })),
9702
+ settles: [...settles]
9703
+ })
9704
+ };
9705
+ }
9706
+ /**
9707
+ * This function makes a replayer: a function `perform` that answers each effect from a log, by its address (RUN.REPLAY). A
9708
+ * recorded error comes again with its code, its reason, its place and its cause. The waits of each `all` settle in the
9709
+ * recorded order. An effect that the log does not have at its address gives `#REPLAY!` (RUN.REPLAY-MISMATCH).
9710
+ *
9711
+ * A replayer keeps its place in the order of the waits, thus each run needs a new replayer.
9712
+ *
9713
+ * @param log - The log of a recorder.
9714
+ * @param options - `wait: false` for an evaluation.
9715
+ * @returns The function `perform` for the replay.
9716
+ */
9717
+ function replayer(log, options = {}) {
9718
+ const wait = options.wait !== false;
9719
+ const entries = /* @__PURE__ */ new Map();
9720
+ for (const entry of log.effects) entries.set(entry.address, entry);
9721
+ const order = /* @__PURE__ */ new Map();
9722
+ for (const settle of log.settles) {
9723
+ const items = order.get(settle.all);
9724
+ if (items === void 0) order.set(settle.all, [settle.item]);
9725
+ else items.push(settle.item);
9726
+ }
9727
+ const journal = { next: (all, waiting) => {
9728
+ const items = order.get(all);
9729
+ const item = items?.[0];
9730
+ if (items === void 0 || item === void 0 || !waiting.includes(item)) return void 0;
9731
+ items.shift();
9732
+ return item;
9733
+ } };
9734
+ const perform = (effect) => {
9735
+ const entry = effect.address === void 0 ? void 0 : entries.get(effect.address);
9736
+ const wrong = mismatch(effect, entry);
9737
+ if (wrong !== void 0 || entry === void 0) throw wrong;
9738
+ const outcome = entry.outcome;
9739
+ const failure = outcome === void 0 ? replayError(effect, `The log has no outcome for the effect ${effect.kind} at ${effect.address ?? ""}: the recorded run stopped before the answer.`) : outcome.ok ? void 0 : new Failure(outcome.error);
9740
+ const value = outcome?.ok === true ? outcome.value : void 0;
9741
+ if (wait && entry.waited) return failure === void 0 ? Promise.resolve(value) : Promise.reject(failure);
9742
+ if (failure !== void 0) throw failure;
9743
+ return value;
9744
+ };
9745
+ return Object.assign(perform, { [JOURNAL]: journal });
9746
+ }
9747
+ /** This function gives the error of an effect that the log does not have at its address, or `undefined`. */
9748
+ function mismatch(effect, entry) {
9749
+ const at = effect.address ?? "";
9750
+ if (entry === void 0) return replayError(effect, `The log has no effect at the address ${at}, and the run asks for the effect ${effect.kind}.`);
9751
+ if (entry.kind !== effect.kind) return replayError(effect, `The log has the effect ${entry.kind} at the address ${at}, and the run asks for the effect ${effect.kind}.`);
9752
+ if (!docEquals(entry.payload, effect.payload)) return replayError(effect, `The effect ${effect.kind} at the address ${at} has another payload than the log.`);
9753
+ }
9754
+ /** This function gives the exception that carries `#REPLAY!` to the kernel, with the place of the effect. */
9755
+ function replayError(effect, reason) {
9756
+ return new Failure(fail("#REPLAY!", reason, { place: effect.place }).error);
9757
+ }
9758
+ //#endregion
9411
9759
  //#region src/agree.ts
9412
9760
  /** The tiers that `agree` compares when its options name none. */
9413
9761
  const DEFAULT_TIERS = /* @__PURE__ */ Object.freeze([
@@ -9595,6 +9943,113 @@ function agree(machine, doc, context = makeContext(), options = {}) {
9595
9943
  effects
9596
9944
  };
9597
9945
  }
9946
+ /**
9947
+ * This function wraps the function `perform` of a run. The wrapper keeps each effect and each wait of `all` that
9948
+ * settles. It gives each effect to the inner function, and each call of its journal to the inner journal.
9949
+ */
9950
+ function watched(perform) {
9951
+ const effects = [];
9952
+ const settles = [];
9953
+ const inner = perform[JOURNAL];
9954
+ const settled = (all, item) => {
9955
+ settles.push({
9956
+ all,
9957
+ item
9958
+ });
9959
+ inner?.settled?.(all, item);
9960
+ };
9961
+ const journal = inner?.next === void 0 ? { settled } : {
9962
+ settled,
9963
+ next: (all, waiting) => inner.next?.(all, waiting)
9964
+ };
9965
+ const host = (effect) => {
9966
+ effects.push(effect);
9967
+ return perform(effect);
9968
+ };
9969
+ return {
9970
+ perform: Object.assign(host, { [JOURNAL]: journal }),
9971
+ effects,
9972
+ settles
9973
+ };
9974
+ }
9975
+ function settleText(settle) {
9976
+ return settle === void 0 ? "no item" : `the item ${settle.item} of ${settle.all}`;
9977
+ }
9978
+ /** This function gives the first difference of two orders of the waits of `all`, or `undefined` when they agree. */
9979
+ function settlesDiffer(a, b) {
9980
+ for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
9981
+ const x = a[index];
9982
+ const y = b[index];
9983
+ if (x?.all !== y?.all || x?.item !== y?.item) return `The wait ${index} settles ${settleText(x)} in the plan, and ${settleText(y)} in the tier.`;
9984
+ }
9985
+ }
9986
+ /**
9987
+ * This function compares the run of a document in a plan with its run in other tiers (RUN.AGREES). First the plan
9988
+ * starts the run with a recorder around the host. Then each tier replays the log of that run. These tiers are the
9989
+ * reference run, the traced run, a second run of the plan and the plan with the other choice of folds.
9990
+ *
9991
+ * The rules of `agree` compare the results and the effects, with their addresses and outcomes. A tier must also
9992
+ * settle the waits of each `all` in the order of the plan, thus a replay keeps the order of the waits.
9993
+ *
9994
+ * @param machine - The world, the evaluators and the runners.
9995
+ * @param doc - The document.
9996
+ * @param context - The names and the capabilities at the root.
9997
+ * @param options - The tiers, the definitions for the reference, the rules of the comparison and the host.
9998
+ * @returns The result of the plan, or the first tier that disagrees and the reason.
9999
+ */
10000
+ async function agreeRun(machine, doc, context = makeContext(), options = {}) {
10001
+ const declared = {
10002
+ ...options.declaredType === void 0 ? {} : { declaredType: options.declaredType },
10003
+ ...options.verb === void 0 ? {} : { verb: options.verb }
10004
+ };
10005
+ const observe = options.observe;
10006
+ observe?.();
10007
+ const folds = observe === void 0;
10008
+ const plan = prepare(machine, doc, {
10009
+ ...declared,
10010
+ fold: folds
10011
+ });
10012
+ const recording = recorder(options.perform);
10013
+ const first = watched(recording.perform);
10014
+ const result = await plan.run(context, { perform: first.perform });
10015
+ const saw = observe?.();
10016
+ const log = recording.log();
10017
+ for (const tier of options.tiers ?? DEFAULT_TIERS) {
10018
+ const replay = watched(replayer(log));
10019
+ const host = { perform: replay.perform };
10020
+ let other;
10021
+ if (tier === "reference") other = await referenceRun(machine, doc, context, {
10022
+ ...declared,
10023
+ ...host,
10024
+ ...options.definitions === void 0 ? {} : { definitions: options.definitions }
10025
+ });
10026
+ else if (tier === "traced") other = (await run(machine, doc, context, {
10027
+ ...declared,
10028
+ ...host
10029
+ })).result;
10030
+ else if (tier === "folds") other = await prepare(machine, doc, {
10031
+ ...declared,
10032
+ fold: !folds
10033
+ }).run(context, host);
10034
+ else other = await plan.run(context, host);
10035
+ const compareCalls = observe !== void 0 && tier !== "folds";
10036
+ const calls = observe?.();
10037
+ if (overflowed(result) || overflowed(other)) continue;
10038
+ const why = resultDiffers(result, other, options) ?? effectsDiffer(first.effects, replay.effects, options) ?? settlesDiffer(first.settles, replay.settles) ?? (compareCalls && !sameValue(saw, calls, options.equal) ? "The host saw other calls in the tier." : void 0);
10039
+ if (why !== void 0) return {
10040
+ ok: false,
10041
+ tier,
10042
+ plan: result,
10043
+ other,
10044
+ reason: why
10045
+ };
10046
+ }
10047
+ return {
10048
+ ok: true,
10049
+ result,
10050
+ effects: first.effects
10051
+ };
10052
+ }
9598
10053
  //#endregion
9599
10054
  //#region src/generate.ts
9600
10055
  /**
@@ -11810,101 +12265,6 @@ function schedule(machine, options = {}) {
11810
12265
  };
11811
12266
  }
11812
12267
  //#endregion
11813
- //#region src/replay.ts
11814
- /**
11815
- * This function makes a recorder (RUN.RECORD). The recorder gives each effect to the function `perform` of the host.
11816
- * Its log keeps each effect with its address, its kind, its payload and the outcome that the kernel gives it. The log
11817
- * also keeps the order in which the waits of each `all` settle.
11818
- *
11819
- * @param perform - The function of the host. Without it, each effect gives its payload, as in a run without a host.
11820
- * @returns The function `perform` for the run, and the log.
11821
- */
11822
- function recorder(perform) {
11823
- const seen = [];
11824
- const settles = [];
11825
- const journal = { settled: (all, item) => {
11826
- settles.push({
11827
- all,
11828
- item
11829
- });
11830
- } };
11831
- const host = (effect) => {
11832
- const entry = {
11833
- effect,
11834
- waited: false
11835
- };
11836
- seen.push(entry);
11837
- const answer = perform === void 0 ? effect.payload : perform(effect);
11838
- if (answer instanceof Promise) entry.waited = true;
11839
- return answer;
11840
- };
11841
- return {
11842
- perform: Object.assign(host, { [JOURNAL]: journal }),
11843
- log: () => ({
11844
- effects: seen.map(({ effect, waited }) => ({
11845
- address: effect.address ?? "",
11846
- kind: effect.kind,
11847
- payload: effect.payload,
11848
- waited,
11849
- ...effect.outcome === void 0 ? {} : { outcome: effect.outcome }
11850
- })),
11851
- settles: [...settles]
11852
- })
11853
- };
11854
- }
11855
- /**
11856
- * This function makes a replayer: a function `perform` that answers each effect from a log, by its address (RUN.REPLAY). A
11857
- * recorded error comes again with its code, its reason, its place and its cause. The waits of each `all` settle in the
11858
- * recorded order. An effect that the log does not have at its address gives `#REPLAY!` (RUN.REPLAY-MISMATCH).
11859
- *
11860
- * A replayer keeps its place in the order of the waits, thus each run needs a new replayer.
11861
- *
11862
- * @param log - The log of a recorder.
11863
- * @param options - `wait: false` for an evaluation.
11864
- * @returns The function `perform` for the replay.
11865
- */
11866
- function replayer(log, options = {}) {
11867
- const wait = options.wait !== false;
11868
- const entries = /* @__PURE__ */ new Map();
11869
- for (const entry of log.effects) entries.set(entry.address, entry);
11870
- const order = /* @__PURE__ */ new Map();
11871
- for (const settle of log.settles) {
11872
- const items = order.get(settle.all);
11873
- if (items === void 0) order.set(settle.all, [settle.item]);
11874
- else items.push(settle.item);
11875
- }
11876
- const journal = { next: (all, waiting) => {
11877
- const items = order.get(all);
11878
- const item = items?.[0];
11879
- if (items === void 0 || item === void 0 || !waiting.includes(item)) return void 0;
11880
- items.shift();
11881
- return item;
11882
- } };
11883
- const perform = (effect) => {
11884
- const entry = effect.address === void 0 ? void 0 : entries.get(effect.address);
11885
- const wrong = mismatch(effect, entry);
11886
- if (wrong !== void 0 || entry === void 0) throw wrong;
11887
- const outcome = entry.outcome;
11888
- const failure = outcome === void 0 ? replayError(effect, `The log has no outcome for the effect ${effect.kind} at ${effect.address ?? ""}: the recorded run stopped before the answer.`) : outcome.ok ? void 0 : new Failure(outcome.error);
11889
- const value = outcome?.ok === true ? outcome.value : void 0;
11890
- if (wait && entry.waited) return failure === void 0 ? Promise.resolve(value) : Promise.reject(failure);
11891
- if (failure !== void 0) throw failure;
11892
- return value;
11893
- };
11894
- return Object.assign(perform, { [JOURNAL]: journal });
11895
- }
11896
- /** This function gives the error of an effect that the log does not have at its address, or `undefined`. */
11897
- function mismatch(effect, entry) {
11898
- const at = effect.address ?? "";
11899
- if (entry === void 0) return replayError(effect, `The log has no effect at the address ${at}, and the run asks for the effect ${effect.kind}.`);
11900
- if (entry.kind !== effect.kind) return replayError(effect, `The log has the effect ${entry.kind} at the address ${at}, and the run asks for the effect ${effect.kind}.`);
11901
- if (!docEquals(entry.payload, effect.payload)) return replayError(effect, `The effect ${effect.kind} at the address ${at} has another payload than the log.`);
11902
- }
11903
- /** This function gives the exception that carries `#REPLAY!` to the kernel, with the place of the effect. */
11904
- function replayError(effect, reason) {
11905
- return new Failure(fail("#REPLAY!", reason, { place: effect.place }).error);
11906
- }
11907
- //#endregion
11908
12268
  //#region src/providers.ts
11909
12269
  /** The deepest schema that `typeFromSchema` reads. A deeper schema reads as `unknown`. */
11910
12270
  const MAX_SCHEMA_DEPTH = 256;
@@ -12215,6 +12575,6 @@ function typeFromSamples(values, options = {}) {
12215
12575
  return samplesAt(values, options.closed === true, 0);
12216
12576
  }
12217
12577
  //#endregion
12218
- export { ATTRIBUTE_RUNGS, CAPS_TYPE, CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, JOURNAL, MergeError, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_DOMAINS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_SYNTAX, STD_WALKERS, STD_WORLD, THING, agree, ask, attributeTrace, capKeys, check, checkLatent, checkSteps, checkWorld, classify, components, conforms, context, cycles, dataEdges, decodeDomain, decodeValue, derefStep, describe, docEquals, durable, edgesOf, effectEdges, effectsOf, effectsOfVerb, encodeValue, entriesAsJson, equationType, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partsOf, pathMatches, permits, placed, planner, prepare, print, random, recorder, ref, reference, refsOf, replayer, resolve, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stored, syntaxFormat, tag, thrown, toJson, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
12578
+ export { ATTRIBUTE_RUNGS, CAPS_TYPE, CONSTRUCTS, ENVELOPE_KEYS, Failure, Held, JOURNAL, MergeError, PARTS, PART_INFO, ROOTS, RUNGS, STD_CAPS, STD_DEFINITIONS, STD_DOMAINS, STD_EVALUATORS, STD_EXT, STD_MACHINE, STD_RUNNERS, STD_SYNTAX, STD_WALKERS, STD_WORLD, THING, agree, agreeRun, ask, attributeTrace, capKeys, check, checkLatent, checkSteps, checkWorld, classify, components, conforms, context, cycles, dataEdges, decodeDomain, decodeValue, derefStep, describe, docEquals, durable, edgesOf, effectEdges, effectsOf, effectsOfVerb, encodeValue, entriesAsJson, equationType, evaluate, extendDomain, factsOf, fail, failures, field, fits, flatten, formulaDefinitions, formulaEvaluators, formulaFacts, formulaKinds, formulaKnown, formulaMachine, fromJson, generate, heights, intersectCaps, isAlias, isAllowedOrder, isClosure, isEnvelope, isHostThing, isKey, isKind, isNamespace, isRecord, isRef, isStackOverflow, isTypeRef, join, jsTruthy, kindDocument, kindNamed, kindOf, layers, looksLikeKind, lookupKind, makeContext, mapRefs, member, mergeMachines, mergeWorlds, narrow, nearestWalker, necessary, nodeAt, nodeLayers, ok, parse, partCaps, partsOf, pathMatches, permits, placed, planner, prepare, print, random, recorder, ref, reference, referenceRun, refsOf, replayer, resolve, restrictMachine, restrictWorld, run, sameResult, sameValue, schedule, splitParts, stored, syntaxFormat, tag, thrown, toJson, typeCheck, typeFromSamples, typeFromSchema, typeIssues, typeName, typePath, typeText, typed, typesOf, valueOfThing, verifyReads, walk, worldThing };
12219
12579
 
12220
12580
  //# sourceMappingURL=index.js.map