@mark1russell7/coeval 0.22.0 → 0.23.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/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
@@ -146,6 +146,8 @@ export interface KindFacts {
146
146
  * whose attributes each declare `circular` gives a fixed point.
147
147
  * - `collect`: the value of a node without an answer of the first four rungs and without a fold. The node combines
148
148
  * the contributions of each node of its subtree (TREE.COLLECT, D122).
149
+ * - `higher`: the value of a node without an answer of the rungs before it. The term gives a document as data. The kit
150
+ * evaluates that document with the node as `self`, thus its root is a new node under the node (TREE.HIGHER, D126).
149
151
  */
150
152
  export interface AttributeDeclaration {
151
153
  readonly copy?: boolean;
@@ -153,6 +155,7 @@ export interface AttributeDeclaration {
153
155
  readonly default?: Json;
154
156
  readonly circular?: CircularDeclaration;
155
157
  readonly collect?: CollectDeclaration;
158
+ readonly higher?: Json;
156
159
  }
157
160
 
158
161
  /**
@@ -189,6 +192,9 @@ export interface CircularDeclaration {
189
192
  readonly limit?: number;
190
193
  }
191
194
 
195
+ /** The most generated documents on the way from a node to the root of its tree (TREE.HIGHER-DEPTH, D126). */
196
+ export const GENERATION_LIMIT = 64;
197
+
192
198
  /** The most rounds of a circular attribute without its own `limit` (TREE.CIRCULAR-LIMIT, D113). */
193
199
  export const CIRCULAR_LIMIT = 100;
194
200
 
@@ -260,6 +266,8 @@ export function collectOf(declared: unknown): CollectRule {
260
266
  * equation sees no names.
261
267
  * - `at`: the attributes with parameters of the node (TREE.AT, D124). Only the step `tree.at` reads them, and the
262
268
  * equation sees each parameter as a name.
269
+ * - `forwards`: the name of an attribute that gives a node. An attribute that no other rung answers comes from that
270
+ * node (TREE.FORWARD, D126).
263
271
  */
264
272
  export interface TreeContract {
265
273
  readonly equations?: Readonly<Record<string, Json>>;
@@ -267,6 +275,7 @@ export interface TreeContract {
267
275
  readonly attributes?: Readonly<Record<string, AttributeDeclaration>>;
268
276
  readonly contributes?: Readonly<Record<string, Json>>;
269
277
  readonly at?: Readonly<Record<string, AtEquation>>;
278
+ readonly forwards?: string;
270
279
  }
271
280
 
272
281
  /**
@@ -334,15 +343,27 @@ export function argsKey(value: unknown): string | undefined {
334
343
  return keyOf(value, new Set());
335
344
  }
336
345
 
337
- function keyOf(value: unknown, open: Set<object>): string | undefined {
346
+ /**
347
+ * This function gives the structural key of a document (TREE.HIGHER-PLAN, D126). The fields of a record keep their
348
+ * order, because the order of the parts decides the order of the JSON and the first error. Thus one key means one
349
+ * document, and the two documents are equal by DOC.EQUALS.
350
+ *
351
+ * @param doc - The document.
352
+ * @returns The JSON text, or `undefined` for a value that is not JSON data.
353
+ */
354
+ export function documentKey(doc: unknown): string | undefined {
355
+ return keyOf(doc, new Set(), false);
356
+ }
357
+
358
+ function keyOf(value: unknown, open: Set<object>, sorted = true): string | undefined {
338
359
  if (value === null || typeof value === "boolean" || typeof value === "string") return JSON.stringify(value);
339
360
  if (typeof value === "number") return !Number.isFinite(value) ? undefined : Object.is(value, -0) ? "-0" : JSON.stringify(value);
340
361
  if (typeof value !== "object" || open.has(value) || (!Array.isArray(value) && !isRecord(value))) return undefined;
341
362
  open.add(value);
342
363
  try {
343
364
  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));
365
+ const names = list ? [] : sorted ? Object.keys(value).sort() : Object.keys(value);
366
+ const items = list ? value.map((item) => keyOf(item, open, sorted)) : names.map((name) => keyOf(field(value as JsonRecord, name), open, sorted));
346
367
  if (items.includes(undefined)) return undefined;
347
368
  return list ? `[${items.join(",")}]` : `{${names.map((name, index) => `${JSON.stringify(name)}:${String(items[index])}`).join(",")}}`;
348
369
  } finally {