@mark1russell7/coeval 0.22.0 → 0.24.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/README.md +24 -5
- package/build/index.d.ts +442 -116
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5848 -3680
- package/build/index.js.map +1 -1
- package/package.json +4 -4
- package/src/codec-laws.ts +152 -0
- package/src/codec.ts +2 -2
- package/src/conform.ts +663 -71
- package/src/deref.ts +17 -3
- package/src/durable.ts +21 -9
- package/src/effects.ts +1 -1
- package/src/errors.ts +17 -1
- package/src/evaluate.ts +188 -24
- package/src/formula.ts +60 -17
- package/src/index.ts +15 -0
- package/src/instances.ts +16 -1
- package/src/meaning.ts +43 -10
- package/src/parts.ts +7 -4
- package/src/providers.ts +4 -1
- package/src/reference.ts +122 -2
- package/src/schedule.ts +286 -45
- package/src/static.ts +59 -16
- package/src/stdlib.ts +188 -6
- package/src/syntax.ts +637 -48
- package/src/types.ts +2 -1
- package/src/world.ts +31 -4
package/src/types.ts
CHANGED
|
@@ -87,7 +87,8 @@ export interface Domain {
|
|
|
87
87
|
/**
|
|
88
88
|
* The codec of a domain: it writes a member of the domain as JSON, and it reads the JSON again (D40). Both functions
|
|
89
89
|
* must be pure. `decode(encode(v))` must equal `v` by `sameValue` (EXT.ROUNDTRIP). The codec must give one JSON
|
|
90
|
-
* value for each member, thus the same value has the same document in each language (D12).
|
|
90
|
+
* value for each member, thus the same value has the same document in each language (D12). `codecLaws` examines
|
|
91
|
+
* these laws for the members of the domain (D130).
|
|
91
92
|
*/
|
|
92
93
|
export interface DomainCodec {
|
|
93
94
|
/**
|
package/src/world.ts
CHANGED
|
@@ -89,7 +89,13 @@ export interface ScopeRule {
|
|
|
89
89
|
export type CapsRule =
|
|
90
90
|
| { readonly rule: "same"; readonly in?: readonly (readonly Key[])[] }
|
|
91
91
|
| { readonly rule: "mask"; readonly in?: readonly (readonly Key[])[] }
|
|
92
|
-
| { readonly rule: "only"; readonly caps: readonly Cap[]; readonly in?: readonly (readonly Key[])[] }
|
|
92
|
+
| { readonly rule: "only"; readonly caps: readonly Cap[]; readonly in?: readonly (readonly Key[])[] }
|
|
93
|
+
/**
|
|
94
|
+
* The parts that the rule covers get each capability that the value of the document holds at the path `from`. The
|
|
95
|
+
* code of the kind answers these effects with its own clauses (`RunPart.handled`), thus they do not reach the host.
|
|
96
|
+
* The key `"*"` in `from` steps into each item (CAP.GRANT, D146).
|
|
97
|
+
*/
|
|
98
|
+
| { readonly rule: "grant"; readonly from: readonly Key[]; readonly in?: readonly (readonly Key[])[] };
|
|
93
99
|
|
|
94
100
|
/**
|
|
95
101
|
* A lazy rule of a kind names the parts that an evaluation can skip and still give a value. An example is the
|
|
@@ -146,6 +152,8 @@ export interface KindFacts {
|
|
|
146
152
|
* whose attributes each declare `circular` gives a fixed point.
|
|
147
153
|
* - `collect`: the value of a node without an answer of the first four rungs and without a fold. The node combines
|
|
148
154
|
* the contributions of each node of its subtree (TREE.COLLECT, D122).
|
|
155
|
+
* - `higher`: the value of a node without an answer of the rungs before it. The term gives a document as data. The kit
|
|
156
|
+
* evaluates that document with the node as `self`, thus its root is a new node under the node (TREE.HIGHER, D126).
|
|
149
157
|
*/
|
|
150
158
|
export interface AttributeDeclaration {
|
|
151
159
|
readonly copy?: boolean;
|
|
@@ -153,6 +161,7 @@ export interface AttributeDeclaration {
|
|
|
153
161
|
readonly default?: Json;
|
|
154
162
|
readonly circular?: CircularDeclaration;
|
|
155
163
|
readonly collect?: CollectDeclaration;
|
|
164
|
+
readonly higher?: Json;
|
|
156
165
|
}
|
|
157
166
|
|
|
158
167
|
/**
|
|
@@ -189,6 +198,9 @@ export interface CircularDeclaration {
|
|
|
189
198
|
readonly limit?: number;
|
|
190
199
|
}
|
|
191
200
|
|
|
201
|
+
/** The most generated documents on the way from a node to the root of its tree (TREE.HIGHER-DEPTH, D126). */
|
|
202
|
+
export const GENERATION_LIMIT = 64;
|
|
203
|
+
|
|
192
204
|
/** The most rounds of a circular attribute without its own `limit` (TREE.CIRCULAR-LIMIT, D113). */
|
|
193
205
|
export const CIRCULAR_LIMIT = 100;
|
|
194
206
|
|
|
@@ -260,6 +272,8 @@ export function collectOf(declared: unknown): CollectRule {
|
|
|
260
272
|
* equation sees no names.
|
|
261
273
|
* - `at`: the attributes with parameters of the node (TREE.AT, D124). Only the step `tree.at` reads them, and the
|
|
262
274
|
* equation sees each parameter as a name.
|
|
275
|
+
* - `forwards`: the name of an attribute that gives a node. An attribute that no other rung answers comes from that
|
|
276
|
+
* node (TREE.FORWARD, D126).
|
|
263
277
|
*/
|
|
264
278
|
export interface TreeContract {
|
|
265
279
|
readonly equations?: Readonly<Record<string, Json>>;
|
|
@@ -267,6 +281,7 @@ export interface TreeContract {
|
|
|
267
281
|
readonly attributes?: Readonly<Record<string, AttributeDeclaration>>;
|
|
268
282
|
readonly contributes?: Readonly<Record<string, Json>>;
|
|
269
283
|
readonly at?: Readonly<Record<string, AtEquation>>;
|
|
284
|
+
readonly forwards?: string;
|
|
270
285
|
}
|
|
271
286
|
|
|
272
287
|
/**
|
|
@@ -334,15 +349,27 @@ export function argsKey(value: unknown): string | undefined {
|
|
|
334
349
|
return keyOf(value, new Set());
|
|
335
350
|
}
|
|
336
351
|
|
|
337
|
-
|
|
352
|
+
/**
|
|
353
|
+
* This function gives the structural key of a document (TREE.HIGHER-PLAN, D126). The fields of a record keep their
|
|
354
|
+
* order, because the order of the parts decides the order of the JSON and the first error. Thus one key means one
|
|
355
|
+
* document, and the two documents are equal by DOC.EQUALS.
|
|
356
|
+
*
|
|
357
|
+
* @param doc - The document.
|
|
358
|
+
* @returns The JSON text, or `undefined` for a value that is not JSON data.
|
|
359
|
+
*/
|
|
360
|
+
export function documentKey(doc: unknown): string | undefined {
|
|
361
|
+
return keyOf(doc, new Set(), false);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function keyOf(value: unknown, open: Set<object>, sorted = true): string | undefined {
|
|
338
365
|
if (value === null || typeof value === "boolean" || typeof value === "string") return JSON.stringify(value);
|
|
339
366
|
if (typeof value === "number") return !Number.isFinite(value) ? undefined : Object.is(value, -0) ? "-0" : JSON.stringify(value);
|
|
340
367
|
if (typeof value !== "object" || open.has(value) || (!Array.isArray(value) && !isRecord(value))) return undefined;
|
|
341
368
|
open.add(value);
|
|
342
369
|
try {
|
|
343
370
|
const list = Array.isArray(value);
|
|
344
|
-
const names = list ? [] : Object.keys(value).sort();
|
|
345
|
-
const items = list ? value.map((item) => keyOf(item, open)) : names.map((name) => keyOf(field(value as JsonRecord, name), open));
|
|
371
|
+
const names = list ? [] : sorted ? Object.keys(value).sort() : Object.keys(value);
|
|
372
|
+
const items = list ? value.map((item) => keyOf(item, open, sorted)) : names.map((name) => keyOf(field(value as JsonRecord, name), open, sorted));
|
|
346
373
|
if (items.includes(undefined)) return undefined;
|
|
347
374
|
return list ? `[${items.join(",")}]` : `{${names.map((name, index) => `${JSON.stringify(name)}:${String(items[index])}`).join(",")}}`;
|
|
348
375
|
} finally {
|