@mark1russell7/coeval 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +15 -9
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/deref.ts +18 -9
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.2.
|
|
4
|
+
"version": "0.2.1",
|
|
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/deref.ts
CHANGED
|
@@ -112,6 +112,8 @@ export type Walker = (input: WalkInput) => WalkResult;
|
|
|
112
112
|
* - `plain`: `true` when the values are data. Then a step does not ask the kind of an envelope, and a reference
|
|
113
113
|
* that a step reaches stays a value (no collapse).
|
|
114
114
|
* - `roots`: the roots that a path can start at. The default is each root.
|
|
115
|
+
* - `adopt`: the thing of each value that a path reaches. A host gives its own values a host thing with this
|
|
116
|
+
* function, for example a value whose fields read through signals. A host thing is not followed as a reference.
|
|
115
117
|
*/
|
|
116
118
|
export interface Navigator {
|
|
117
119
|
readonly world: World;
|
|
@@ -119,6 +121,7 @@ export interface Navigator {
|
|
|
119
121
|
readonly walkers?: Readonly<Record<string, Walker>>;
|
|
120
122
|
readonly plain?: boolean;
|
|
121
123
|
readonly roots?: readonly Root[];
|
|
124
|
+
readonly adopt?: (value: unknown) => Thing;
|
|
122
125
|
}
|
|
123
126
|
|
|
124
127
|
/** The way that one hop of a path was answered. */
|
|
@@ -265,6 +268,7 @@ function resolveQuick(nav: Navigator, ctx: Context, path: readonly unknown[]): R
|
|
|
265
268
|
const root = path[0];
|
|
266
269
|
if (root !== "names" && root !== "self" && root !== "event") return undefined;
|
|
267
270
|
if (nav.roots !== undefined && !(nav.roots as readonly string[]).includes(root)) return undefined;
|
|
271
|
+
if (nav.adopt !== undefined) return undefined;
|
|
268
272
|
let here: unknown = ctx[root];
|
|
269
273
|
const plain = nav.plain === true;
|
|
270
274
|
for (let index = 1; index < path.length; index += 1) {
|
|
@@ -316,6 +320,7 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
316
320
|
const done = hops ?? NO_HOPS;
|
|
317
321
|
const failed = (code: ResolveCode, reason: string): Resolution => ({ ok: false, code, reason, hops: done });
|
|
318
322
|
let collapses = 0;
|
|
323
|
+
const adopt = nav.adopt ?? ((value: unknown): Thing => value);
|
|
319
324
|
|
|
320
325
|
const collapse = (thing: Thing): Resolution => {
|
|
321
326
|
let here = thing;
|
|
@@ -325,7 +330,7 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
325
330
|
if (collapses > MAX_COLLAPSE) return failed("#CYCLE!", "The references form a cycle.");
|
|
326
331
|
const inner = walk(here.value);
|
|
327
332
|
if (!inner.ok) return inner;
|
|
328
|
-
here = inner.thing;
|
|
333
|
+
here = adopt(inner.thing);
|
|
329
334
|
hops?.push({ step: "collapse", thing: here, by: "collapse" });
|
|
330
335
|
}
|
|
331
336
|
return { ok: true, thing: here, hops: done };
|
|
@@ -339,7 +344,7 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
339
344
|
if (nav.roots !== undefined && !(nav.roots as readonly string[]).includes(root)) {
|
|
340
345
|
return failed("#REF!", `The root ${root} is not open here. The open roots are ${nav.roots.join(", ")}.`);
|
|
341
346
|
}
|
|
342
|
-
let here: Thing = ctx[root as Root];
|
|
347
|
+
let here: Thing = adopt(ctx[root as Root]);
|
|
343
348
|
hops?.push({ step: root, thing: here, by: "root" });
|
|
344
349
|
const first = collapse(here);
|
|
345
350
|
if (!first.ok) return first;
|
|
@@ -350,8 +355,9 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
350
355
|
const keys = steps.slice(index) as readonly Key[];
|
|
351
356
|
const reached = here.resolve(keys);
|
|
352
357
|
if (reached === undefined) return failed("#N/A", `The path ${keys.join(".")} reaches nothing.`);
|
|
353
|
-
|
|
354
|
-
|
|
358
|
+
const thing = adopt(reached.thing);
|
|
359
|
+
hops?.push({ step: keys as readonly Json[], thing, by: "own" });
|
|
360
|
+
return collapse(thing);
|
|
355
361
|
}
|
|
356
362
|
if (isKey(step)) {
|
|
357
363
|
const reached = derefStep(nav, here, step);
|
|
@@ -359,8 +365,8 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
359
365
|
if (root === "names" && index === 1) return failed("#NAME?", `The context has no name ${String(step)}.`);
|
|
360
366
|
return failed("#N/A", `The step ${String(step)} reaches nothing.`);
|
|
361
367
|
}
|
|
362
|
-
|
|
363
|
-
here
|
|
368
|
+
here = adopt(reached.thing);
|
|
369
|
+
hops?.push({ step, thing: here, by: reached.by });
|
|
364
370
|
} else {
|
|
365
371
|
const envelope = isEnvelope(step) ? step : undefined;
|
|
366
372
|
const found = envelope === undefined ? undefined : lookupKind(nav.world, envelope.type);
|
|
@@ -373,11 +379,14 @@ export function resolve(nav: Navigator, ctx: Context, path: readonly unknown[],
|
|
|
373
379
|
data: envelope.value,
|
|
374
380
|
here,
|
|
375
381
|
context: ctx,
|
|
376
|
-
deref: (thing, key) =>
|
|
382
|
+
deref: (thing, key) => {
|
|
383
|
+
const reached = derefStep(nav, thing, key);
|
|
384
|
+
return reached === undefined ? undefined : adopt(reached.thing);
|
|
385
|
+
},
|
|
377
386
|
});
|
|
378
387
|
if (!result.ok) return failed("#N/A", result.reason);
|
|
379
|
-
|
|
380
|
-
here
|
|
388
|
+
here = adopt(result.thing);
|
|
389
|
+
hops?.push({ step: envelope as Json, thing: here, by: "step" });
|
|
381
390
|
}
|
|
382
391
|
const next = collapse(here);
|
|
383
392
|
if (!next.ok) return next;
|