@mark1russell7/coeval 0.13.0 → 0.14.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.d.ts.map +1 -1
- package/build/index.js +45 -16
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/evaluate.ts +45 -17
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@mark1russell7/coeval",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"description": "coeval: the kernel of declarative languages. Documents in envelopes, a ladder that finds the evaluator, kind contracts, compiled plans, a static kit, a formula kit and a run side with capabilities.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./build/index.js",
|
package/src/evaluate.ts
CHANGED
|
@@ -141,8 +141,15 @@ export function partCaps(rules: readonly CapsRule[] | undefined, path: readonly
|
|
|
141
141
|
*/
|
|
142
142
|
const GRANT = /* @__PURE__ */ Symbol("coeval.grant");
|
|
143
143
|
|
|
144
|
-
/**
|
|
145
|
-
|
|
144
|
+
/**
|
|
145
|
+
* The key of the epoch of a grant (CAP.NARROW-KEPT). The epoch is the list of capabilities that the host gave the root
|
|
146
|
+
* of the evaluation of the grant. A spread of a context keeps its epoch, as it keeps its grant. An
|
|
147
|
+
* effect and a resolution read a context of another epoch as a context without a grant.
|
|
148
|
+
*/
|
|
149
|
+
const EPOCH = /* @__PURE__ */ Symbol("coeval.epoch");
|
|
150
|
+
|
|
151
|
+
/** A context with the grant of the kernel and the epoch of that grant. */
|
|
152
|
+
type Granted = Context & { readonly [GRANT]?: readonly Cap[]; readonly [EPOCH]?: readonly Cap[] | undefined };
|
|
146
153
|
|
|
147
154
|
/**
|
|
148
155
|
* This function gives the capabilities that a context and its grant both permit, the meet `intersectCaps` (CAP.MEET).
|
|
@@ -166,13 +173,25 @@ function granted(ctx: Context): Context {
|
|
|
166
173
|
return out;
|
|
167
174
|
}
|
|
168
175
|
|
|
176
|
+
/**
|
|
177
|
+
* This function gives a context of another epoch the epoch of the evaluation, without capabilities (CAP.NARROW-KEPT).
|
|
178
|
+
* Thus the context reads as a context without a grant. The kernel cannot know the document of the context in this
|
|
179
|
+
* evaluation.
|
|
180
|
+
*/
|
|
181
|
+
function ungranted(ctx: Context, epoch: readonly Cap[]): Context {
|
|
182
|
+
const out: Granted = { ...ctx, caps: NO_CAPS, [GRANT]: NO_CAPS, [EPOCH]: epoch };
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
|
|
169
186
|
/**
|
|
170
187
|
* This function gives the context in which the runtime resolves a path of compiled code (CAP.CAPS-GRANT, CAP.MEET).
|
|
171
188
|
* 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
|
|
172
189
|
* `caps` and a walker of a step document get the capabilities of the document from a widened context.
|
|
173
190
|
* A context that the code narrowed keeps its own list. A context whose list does not change stays the same object.
|
|
191
|
+
* A context of another epoch has no capabilities (CAP.NARROW-KEPT).
|
|
174
192
|
*/
|
|
175
|
-
function readable(ctx: Context): Context {
|
|
193
|
+
function readable(ctx: Context, epoch: readonly Cap[]): Context {
|
|
194
|
+
if ((ctx as Granted)[EPOCH] !== epoch) return ctx.caps.length === 0 ? ctx : ungranted(ctx, epoch);
|
|
176
195
|
const caps = grantedCaps(ctx);
|
|
177
196
|
if (caps === ctx.caps || (caps.length === 0 && ctx.caps.length === 0)) return ctx;
|
|
178
197
|
const out: Granted = { ...ctx, caps, [GRANT]: caps };
|
|
@@ -181,12 +200,14 @@ function readable(ctx: Context): Context {
|
|
|
181
200
|
|
|
182
201
|
/**
|
|
183
202
|
* This function gives the context of a part of a function evaluator. It is the context that the evaluator gives,
|
|
184
|
-
* narrowed by the context of the document (CAP.NARROW), with the grant of its capabilities.
|
|
203
|
+
* narrowed by the context of the document (CAP.NARROW), with the grant of its capabilities. The grant has the epoch
|
|
204
|
+
* of the document, because the document permits each of its capabilities (CAP.NARROW-KEPT).
|
|
185
205
|
*/
|
|
186
206
|
function handed(parent: Context, next: Context): Context {
|
|
187
207
|
const ctx = narrow(parent, next);
|
|
188
|
-
|
|
189
|
-
|
|
208
|
+
const epoch = (parent as Granted)[EPOCH];
|
|
209
|
+
if ((ctx as Granted)[GRANT] === ctx.caps && (ctx as Granted)[EPOCH] === epoch) return ctx;
|
|
210
|
+
const out: Granted = { ...ctx, [GRANT]: ctx.caps, [EPOCH]: epoch };
|
|
190
211
|
return out;
|
|
191
212
|
}
|
|
192
213
|
|
|
@@ -896,6 +917,11 @@ class Session implements Runtime {
|
|
|
896
917
|
|
|
897
918
|
constructor(
|
|
898
919
|
readonly machine: Machine,
|
|
920
|
+
/**
|
|
921
|
+
* The epoch of the evaluation: the list of capabilities that the host gave the root (CAP.NARROW-KEPT). A context
|
|
922
|
+
* keeps its grant only in an evaluation of the same epoch.
|
|
923
|
+
*/
|
|
924
|
+
readonly epoch: readonly Cap[],
|
|
899
925
|
readonly running: boolean,
|
|
900
926
|
readonly traced: boolean,
|
|
901
927
|
readonly perform: Perform | undefined,
|
|
@@ -924,7 +950,7 @@ class Session implements Runtime {
|
|
|
924
950
|
* `caps` and a walker of a step document get the capabilities of the document.
|
|
925
951
|
*/
|
|
926
952
|
resolve(ctx: Context, path: readonly unknown[], options?: ResolveOptions): Resolution {
|
|
927
|
-
return this.read(readable(ctx), path, undefined, options);
|
|
953
|
+
return this.read(readable(ctx, this.epoch), path, undefined, options);
|
|
928
954
|
}
|
|
929
955
|
|
|
930
956
|
/**
|
|
@@ -933,7 +959,7 @@ class Session implements Runtime {
|
|
|
933
959
|
* that the grant permits (CAP.CAPS-GRANT, CAP.MEET).
|
|
934
960
|
*/
|
|
935
961
|
resolvePath(given: Context, compiled: CompiledPath): Resolution {
|
|
936
|
-
const ctx = readable(given);
|
|
962
|
+
const ctx = readable(given, this.epoch);
|
|
937
963
|
if (this.reading === undefined && !this.traced && compiled.nav === this.machine) return compiled.resolve(ctx);
|
|
938
964
|
return this.read(ctx, compiled.path, compiled, undefined);
|
|
939
965
|
}
|
|
@@ -995,10 +1021,11 @@ class Session implements Runtime {
|
|
|
995
1021
|
/**
|
|
996
1022
|
* This function checks the capability of an effect, and records the effect with its address (RUN.ADDRESS). The
|
|
997
1023
|
* context keeps only the capabilities of its grant, thus compiled code cannot widen the context of its own effect
|
|
998
|
-
* (CAP.NARROW-CODE).
|
|
1024
|
+
* (CAP.NARROW-CODE). A context of another epoch has no capabilities, thus code cannot keep a context for a later
|
|
1025
|
+
* evaluation with fewer capabilities (CAP.NARROW-KEPT).
|
|
999
1026
|
*/
|
|
1000
1027
|
private record(given: Context, kind: Cap, payload: unknown, place: readonly Key[]): Result | Recorded {
|
|
1001
|
-
const ctx = granted(given);
|
|
1028
|
+
const ctx = (given as Granted)[EPOCH] === this.epoch ? granted(given) : ungranted(given, this.epoch);
|
|
1002
1029
|
const keys = typeof kind === "string" ? kind.split(".") : kind;
|
|
1003
1030
|
const text = keys.join(".");
|
|
1004
1031
|
if (!this.permitted(ctx, keys)) return fail("#CAP!", `The context has no capability for the effect ${text}.`, { place });
|
|
@@ -1921,15 +1948,16 @@ function interpretRun(fn: RunFn, input: CompileInput, fill: <P>(handles: readonl
|
|
|
1921
1948
|
/**
|
|
1922
1949
|
* This function gives the context at the root of an evaluation. It is the context of the host, with the world of
|
|
1923
1950
|
* the machine when the context has none. The host gives the capabilities, thus the root has the grant of each one
|
|
1924
|
-
* (CAP.NARROW-CODE).
|
|
1951
|
+
* (CAP.NARROW-CODE). The list of the host is also the epoch of the grant (CAP.NARROW-KEPT). An evaluation and
|
|
1952
|
+
* `verifyReads` share it.
|
|
1925
1953
|
*
|
|
1926
1954
|
* @param machine - The machine.
|
|
1927
1955
|
* @param ctx - The context of the host.
|
|
1928
1956
|
* @returns The context at the root.
|
|
1929
1957
|
*/
|
|
1930
1958
|
export function rootContext(machine: Machine, ctx: Context): Context {
|
|
1931
|
-
if (ctx.world !== null && (ctx as Granted)[GRANT] === ctx.caps) return ctx;
|
|
1932
|
-
const root: Granted = { ...ctx, world: ctx.world === null ? worldThing(machine.world) : ctx.world, [GRANT]: ctx.caps };
|
|
1959
|
+
if (ctx.world !== null && (ctx as Granted)[GRANT] === ctx.caps && (ctx as Granted)[EPOCH] === ctx.caps) return ctx;
|
|
1960
|
+
const root: Granted = { ...ctx, world: ctx.world === null ? worldThing(machine.world) : ctx.world, [GRANT]: ctx.caps, [EPOCH]: ctx.caps };
|
|
1933
1961
|
return root;
|
|
1934
1962
|
}
|
|
1935
1963
|
|
|
@@ -2000,14 +2028,14 @@ class CompiledPlan implements Plan {
|
|
|
2000
2028
|
evaluate(context: Context = makeContext(), evalOptions?: EvalOptions): Result {
|
|
2001
2029
|
const machine = this.machine;
|
|
2002
2030
|
const ctx = rootContext(machine, context);
|
|
2003
|
-
const s = new Session(machine, false, this.traced, evalOptions?.perform, undefined, evalOptions?.effects, readingOf(evalOptions?.reads, ctx));
|
|
2031
|
+
const s = new Session(machine, ctx.caps, false, this.traced, evalOptions?.perform, undefined, evalOptions?.effects, readingOf(evalOptions?.reads, ctx));
|
|
2004
2032
|
return this.code(ctx, s);
|
|
2005
2033
|
}
|
|
2006
2034
|
|
|
2007
2035
|
run(context: Context = makeContext(), runOptions: PlanRunOptions = {}): Promise<Result> {
|
|
2008
2036
|
const machine = this.machine;
|
|
2009
2037
|
const ctx = rootContext(machine, context);
|
|
2010
|
-
const s = new Session(machine, true, this.traced, runOptions.perform, runOptions.signal, undefined, readingOf(runOptions.reads, ctx));
|
|
2038
|
+
const s = new Session(machine, ctx.caps, true, this.traced, runOptions.perform, runOptions.signal, undefined, readingOf(runOptions.reads, ctx));
|
|
2011
2039
|
return driveWaiting(this.runCode()(ctx, s), runOptions.signal);
|
|
2012
2040
|
}
|
|
2013
2041
|
}
|
|
@@ -2075,7 +2103,7 @@ export function evaluate(machine: Machine, doc: unknown, context: Context = make
|
|
|
2075
2103
|
...(given.verb === undefined ? {} : { verb: given.verb }),
|
|
2076
2104
|
});
|
|
2077
2105
|
const ctx = rootContext(machine, context);
|
|
2078
|
-
const s = new Session(machine, false, true, given.perform, undefined, undefined, readingOf(given.reads, ctx));
|
|
2106
|
+
const s = new Session(machine, ctx.caps, false, true, given.perform, undefined, undefined, readingOf(given.reads, ctx));
|
|
2079
2107
|
const result = (plan as CompiledPlan).code(ctx, s);
|
|
2080
2108
|
return record(s, result);
|
|
2081
2109
|
}
|
|
@@ -2098,7 +2126,7 @@ export async function run(machine: Machine, doc: unknown, context: Context = mak
|
|
|
2098
2126
|
...(options.verb === undefined ? {} : { verb: options.verb }),
|
|
2099
2127
|
});
|
|
2100
2128
|
const ctx = rootContext(machine, context);
|
|
2101
|
-
const s = new Session(machine, true, true, options.perform, options.signal, undefined, readingOf(options.reads, ctx));
|
|
2129
|
+
const s = new Session(machine, ctx.caps, true, true, options.perform, options.signal, undefined, readingOf(options.reads, ctx));
|
|
2102
2130
|
const result = await driveWaiting((plan as CompiledPlan).runCode()(ctx, s), options.signal);
|
|
2103
2131
|
return record(s, result);
|
|
2104
2132
|
}
|