keri-ts 2.0.0 → 2.1.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/esm/keri/npm/src/acdc/chaining.js +223 -89
- package/esm/keri/npm/src/acdc/observing.js +2 -2
- package/esm/keri/npm/src/acdc/regbasing.js +20 -29
- package/esm/keri/npm/src/acdc/regengine.js +4 -6
- package/esm/keri/npm/src/acdc/registering.js +13 -10
- package/esm/keri/npm/src/acdc/registraring.js +4 -9
- package/esm/keri/npm/src/acdc/salting.js +127 -25
- package/esm/keri/npm/src/acdc/unblinding.js +2 -4
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +1 -1
- package/esm/keri/npm/src/app/credentials/root-replicating.js +123 -0
- package/esm/keri/npm/src/app/credentials/verifying.js +21 -3
- package/esm/keri/npm/src/app/delivery/forwarding.js +49 -7
- package/esm/keri/npm/src/app/exchanges/exchanging.js +11 -12
- package/esm/keri/npm/src/app/identity/configing.js +17 -43
- package/esm/keri/npm/src/app/identity/habbing.js +54 -35
- package/esm/keri/npm/src/app/identity/keeping.js +1 -1
- package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
- package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +8 -5
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
- package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +5 -9
- package/esm/keri/npm/src/app/multisig/group-members.js +14 -0
- package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +7 -2
- package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +35 -3
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +7 -10
- package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
- package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
- package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
- package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
- package/esm/keri/npm/src/app/transport/message-source.js +1 -1
- package/esm/keri/npm/src/app/transport/messengering.js +3 -4
- package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
- package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
- package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
- package/esm/keri/npm/src/cli/common/context.js +2 -2
- package/esm/keri/npm/src/cli/common/existing.js +3 -5
- package/esm/keri/npm/src/cli/credentials/ipex.js +2 -1
- package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
- package/esm/keri/npm/src/cli/endpoints/oobi.js +2 -2
- package/esm/keri/npm/src/cli/identity/challenge.js +2 -2
- package/esm/keri/npm/src/cli/identity/incept.js +2 -2
- package/esm/keri/npm/src/cli/identity/init.js +4 -3
- package/esm/keri/npm/src/cli/identity/interact.js +2 -2
- package/esm/keri/npm/src/cli/identity/rotate.js +2 -2
- package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
- package/esm/keri/npm/src/cli/messaging/multisig.js +61 -3
- package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
- package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
- package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
- package/esm/keri/npm/src/core/bytes.js +9 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
- package/esm/keri/npm/src/core/kel/eventing.js +1 -2
- package/esm/keri/npm/src/core/kel/kever.js +11 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +2 -3
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
- package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
- package/esm/keri/npm/src/core/routing.js +2 -2
- package/esm/keri/npm/src/db/basing.js +149 -203
- package/esm/keri/npm/src/db/core/dber.js +1062 -0
- package/esm/keri/npm/src/db/core/index.js +4 -2
- package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
- package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
- package/esm/keri/npm/src/db/core/memstore.js +532 -0
- package/esm/keri/npm/src/db/core/path-manager.js +109 -223
- package/esm/keri/npm/src/db/core/store-owner.js +104 -0
- package/esm/keri/npm/src/db/core/webdber.js +252 -0
- package/esm/keri/npm/src/db/escrowing.js +2 -2
- package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
- package/esm/keri/npm/src/db/keeping.js +27 -121
- package/esm/keri/npm/src/db/koming.js +1 -1
- package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
- package/esm/keri/npm/src/db/lmdb.js +6 -0
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
- package/esm/keri/npm/src/db/noting.js +11 -55
- package/esm/keri/npm/src/db/reger.js +43 -105
- package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
- package/esm/keri/npm/src/db/subing.js +1 -1
- package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
- package/esm/keri/npm/src/npm/runtime-node.js +3 -0
- package/esm/keri/npm/src/runtime/index.js +9 -10
- package/esm/keri/npm/src/runtime/node.js +14 -0
- package/esm/keri/npm/src/vdr/eventing.js +1 -1
- package/esm/keri/npm/src/vdr/tel-publication.js +3 -3
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +11 -4
- package/types/acdc/chaining.d.ts +56 -6
- package/types/acdc/chaining.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +7 -6
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/regengine.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +8 -4
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/registraring.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +53 -6
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts.map +1 -1
- package/types/app/credentials/root-replicating.d.ts +85 -0
- package/types/app/credentials/root-replicating.d.ts.map +1 -0
- package/types/app/credentials/verifying.d.ts +2 -1
- package/types/app/credentials/verifying.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +10 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +2 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/configing.d.ts +7 -5
- package/types/app/identity/configing.d.ts.map +1 -1
- package/types/app/identity/habbing.d.ts +23 -5
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +1 -1
- package/types/app/identity/lmdb-habery.d.ts +6 -0
- package/types/app/identity/lmdb-habery.d.ts.map +1 -0
- package/types/app/ipex/ipex-graph.d.ts +4 -4
- package/types/app/ipex/ipex-graph.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +11 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/ipexing.d.ts +3 -0
- package/types/app/ipex/ipexing.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +1 -1
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/group-members.d.ts +9 -0
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +2 -1
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/notifications/notifying.d.ts +1 -1
- package/types/app/notifications/notifying.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +3 -1
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +2 -0
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/runtime/agent-runtime.d.ts +7 -0
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/transport/byte-source.d.ts +13 -10
- package/types/app/transport/byte-source.d.ts.map +1 -1
- package/types/app/transport/cesr-egress.d.ts +21 -7
- package/types/app/transport/cesr-egress.d.ts.map +1 -1
- package/types/app/transport/file-bytes.d.ts +11 -0
- package/types/app/transport/file-bytes.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts +3 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/http-messenger.d.ts +15 -10
- package/types/app/transport/http-messenger.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +1 -1
- package/types/app/transport/messengering.d.ts +2 -2
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/transport/node-http-client.d.ts +10 -0
- package/types/app/transport/node-http-client.d.ts.map +1 -0
- package/types/app/transport/tcp-dialer.d.ts +21 -0
- package/types/app/transport/tcp-dialer.d.ts.map +1 -0
- package/types/cli/common/existing.d.ts.map +1 -1
- package/types/cli/credentials/ipex.d.ts.map +1 -1
- package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
- package/types/cli/identity/init.d.ts.map +1 -1
- package/types/cli/index.d.ts +1 -1
- package/types/cli/index.d.ts.map +1 -1
- package/types/cli/messaging/multisig.d.ts +10 -1
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/cli/tools/annotate.d.ts.map +1 -1
- package/types/cli/tools/benchmark.d.ts.map +1 -1
- package/types/cli/tools/db-dump.d.ts.map +1 -1
- package/types/core/bytes.d.ts +2 -0
- package/types/core/bytes.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts +41 -0
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +5 -4
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +1 -3
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/db/basing.d.ts +14 -23
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/dber.d.ts +505 -0
- package/types/db/core/dber.d.ts.map +1 -0
- package/types/db/core/index.d.ts +4 -2
- package/types/db/core/index.d.ts.map +1 -1
- package/types/db/core/lmdb-opener.d.ts +17 -0
- package/types/db/core/lmdb-opener.d.ts.map +1 -0
- package/types/db/core/lmdber.d.ts +60 -383
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/memstore.d.ts +129 -0
- package/types/db/core/memstore.d.ts.map +1 -0
- package/types/db/core/path-manager.d.ts +22 -45
- package/types/db/core/path-manager.d.ts.map +1 -1
- package/types/db/core/store-owner.d.ts +59 -0
- package/types/db/core/store-owner.d.ts.map +1 -0
- package/types/db/core/webdber.d.ts +127 -0
- package/types/db/core/webdber.d.ts.map +1 -0
- package/types/db/escrowing.d.ts +3 -3
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange/exchange-nests.d.ts.map +1 -1
- package/types/db/keeping.d.ts +9 -23
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/koming.d.ts +7 -8
- package/types/db/koming.d.ts.map +1 -1
- package/types/db/lmdb-stores.d.ts +45 -0
- package/types/db/lmdb-stores.d.ts.map +1 -0
- package/types/db/lmdb.d.ts +7 -0
- package/types/db/lmdb.d.ts.map +1 -0
- package/types/db/mailbox/mailboxing.d.ts +7 -21
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/noting.d.ts +7 -12
- package/types/db/noting.d.ts.map +1 -1
- package/types/db/reger.d.ts +7 -11
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/replay/witness-replay.d.ts +0 -2
- package/types/db/replay/witness-replay.d.ts.map +1 -1
- package/types/db/subing.d.ts +24 -25
- package/types/db/subing.d.ts.map +1 -1
- package/types/npm/db-lmdb.d.ts +4 -0
- package/types/npm/db-lmdb.d.ts.map +1 -0
- package/types/npm/runtime-node.d.ts +4 -0
- package/types/npm/runtime-node.d.ts.map +1 -0
- package/types/runtime/index.d.ts +9 -10
- package/types/runtime/index.d.ts.map +1 -1
- package/types/runtime/node.d.ts +15 -0
- package/types/runtime/node.d.ts.map +1 -0
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/acdc/relating.js +0 -59
- package/esm/keri/npm/src/db/baser-defaults.js +0 -11
- package/types/acdc/relating.d.ts +0 -21
- package/types/acdc/relating.d.ts.map +0 -1
- package/types/db/baser-defaults.d.ts +0 -5
- package/types/db/baser-defaults.d.ts.map +0 -1
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Read-only ACDC chaining over caller-owned node verdicts; authentication and application state policy stay separate.
|
|
3
|
+
*
|
|
4
|
+
* KERIpy correspondence: the graph walk and Edge evaluation of upstream PR 1757's
|
|
5
|
+
* `acdc.evaluating.EdgeEvaluator`. keri-ts keeps a functional seam: protocols
|
|
6
|
+
* (IPEX) own node authentication and frame admission, then call `walkAcdcGraph`
|
|
7
|
+
* and `evaluateChain` without this module knowing any disclosure protocol.
|
|
8
|
+
*/
|
|
2
9
|
import { ParserError, Saider } from "cesr-ts";
|
|
3
10
|
import { ValidationError } from "../core/errors.js";
|
|
11
|
+
import { delegationAncestry } from "../core/kel/delegation-ancestry.js";
|
|
4
12
|
import { Schemer } from "../core/scheming.js";
|
|
5
|
-
import { delegationRelation } from "./relating.js";
|
|
6
13
|
import { validateSchema } from "./scheming.js";
|
|
7
|
-
/**
|
|
14
|
+
/** Every Grant-side caller defaults to `open`, matching KERIpy's Grant walk default. */
|
|
15
|
+
export const DEFAULT_GRANT_WALK = "open";
|
|
16
|
+
/** Reserved Edge-group labels include a pin at every level. The top-level Edge Section additionally forbids `w`. */
|
|
8
17
|
export const acdcGroupLabels = new Set(["d", "u", "s", "o", "w"]);
|
|
9
18
|
const leafLabels = new Set([...acdcGroupLabels, "n"]);
|
|
10
|
-
const unary = new Set(["I2I", "NI2I", "DI2I", "E1E", "NOT"]);
|
|
19
|
+
const unary = new Set(["I2I", "NI2I", "DI2I", "E1E", "I1I", "DI1I", "NOT"]);
|
|
20
|
+
/** Latest-wins issuer-to-issuee group. */
|
|
11
21
|
const delegative = new Set(["I2I", "NI2I", "DI2I"]);
|
|
12
|
-
|
|
22
|
+
/** Latest-wins issuer-to-issuer group, independent of the delegative group; E1E composes with both. */
|
|
23
|
+
const issuerIdentity = new Set(["I1I", "DI1I"]);
|
|
24
|
+
/** Any explicit relation suppresses the implicit I2I/NI2I default. */
|
|
25
|
+
const suppressDefault = new Set([...delegative, "E1E", ...issuerIdentity]);
|
|
13
26
|
/** SAD maps exclude scalar/array edge representations. */
|
|
14
27
|
function record(value) {
|
|
15
28
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16
29
|
}
|
|
17
|
-
/**
|
|
18
|
-
export function acdcEdgeBlocks(value) {
|
|
19
|
-
if (!value || (Array.isArray(value) && !value.length) || (record(value) && !Object.keys(value).length))
|
|
20
|
-
return [];
|
|
21
|
-
if (record(value))
|
|
22
|
-
return [value];
|
|
23
|
-
return Array.isArray(value) && value.every(record) ? value : null;
|
|
24
|
-
}
|
|
25
|
-
/** Only canonical qualified digests identify expanded leaf targets and schema pins. */
|
|
30
|
+
/** Only canonical qualified digests identify expanded leaf targets, compact commitments and schema pins. */
|
|
26
31
|
function said(value) {
|
|
27
32
|
if (typeof value !== "string")
|
|
28
33
|
return false;
|
|
@@ -33,12 +38,116 @@ function said(value) {
|
|
|
33
38
|
return false;
|
|
34
39
|
}
|
|
35
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Classify a node's `e` field; null is malformed.
|
|
43
|
+
* Lists, falsy non-map values, non-SAID strings and a top-level `n` or `w` are
|
|
44
|
+
* malformed. A compact SAID is a valid opaque terminal that names no far nodes.
|
|
45
|
+
*/
|
|
46
|
+
export function acdcEdgeSection(sad) {
|
|
47
|
+
if (!Object.hasOwn(sad, "e"))
|
|
48
|
+
return { kind: "none" };
|
|
49
|
+
const value = sad.e;
|
|
50
|
+
if (record(value)) {
|
|
51
|
+
if (!Object.keys(value).length)
|
|
52
|
+
return { kind: "none" };
|
|
53
|
+
// The Edge Section is itself an Edge-group, never a leaf, and carries no weight.
|
|
54
|
+
if (Object.hasOwn(value, "n") || Object.hasOwn(value, "w"))
|
|
55
|
+
return null;
|
|
56
|
+
return { kind: "expanded", section: value };
|
|
57
|
+
}
|
|
58
|
+
return said(value) ? { kind: "compact", said: value } : null;
|
|
59
|
+
}
|
|
36
60
|
/** Compact Edge strings name blocks, never far ACDCs. Expanded leaves have exact labels. */
|
|
37
61
|
export function acdcEdgeTarget(value) {
|
|
38
62
|
if (!record(value) || !Object.hasOwn(value, "n"))
|
|
39
63
|
return null;
|
|
40
64
|
return Object.keys(value).every((label) => leafLabels.has(label)) && said(value.n) ? value.n : false;
|
|
41
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Walk a disclosed graph of credential views from `origin` in BFS order.
|
|
68
|
+
*
|
|
69
|
+
* Every view must verify (including its carried section SAIDs) under its own
|
|
70
|
+
* SAID key, every Edge Section must be well shaped, every disclosed node must be
|
|
71
|
+
* reachable and the reachable graph must be acyclic. Closed walks also require
|
|
72
|
+
* every expanded leaf target to be disclosed; open walks skip undisclosed ones
|
|
73
|
+
* (see `AcdcWalkPolicy`).
|
|
74
|
+
* Compact Edge Sections and compact Edge members are opaque terminals.
|
|
75
|
+
* Protocol frame admission (ilks, nests, duplicates) belongs to the caller.
|
|
76
|
+
*/
|
|
77
|
+
export function walkAcdcGraph(origin, nodes, walk) {
|
|
78
|
+
for (const [id, { body }] of nodes)
|
|
79
|
+
if (body.said !== id || !body.verify())
|
|
80
|
+
return null;
|
|
81
|
+
if (!nodes.has(origin))
|
|
82
|
+
return null;
|
|
83
|
+
const seen = new Set();
|
|
84
|
+
const order = [];
|
|
85
|
+
const dependencies = new Map();
|
|
86
|
+
const queue = [origin];
|
|
87
|
+
for (let index = 0; index < queue.length; index++) {
|
|
88
|
+
const id = queue[index];
|
|
89
|
+
if (seen.has(id))
|
|
90
|
+
continue;
|
|
91
|
+
seen.add(id);
|
|
92
|
+
order.push(id);
|
|
93
|
+
const farNodes = new Set();
|
|
94
|
+
dependencies.set(id, farNodes);
|
|
95
|
+
const section = acdcEdgeSection(nodes.get(id).body.sad);
|
|
96
|
+
if (!section)
|
|
97
|
+
return null;
|
|
98
|
+
if (section.kind !== "expanded")
|
|
99
|
+
continue;
|
|
100
|
+
const groups = [section.section];
|
|
101
|
+
for (let g = 0; g < groups.length; g++) {
|
|
102
|
+
for (const [label, member] of Object.entries(groups[g])) {
|
|
103
|
+
if (acdcGroupLabels.has(label))
|
|
104
|
+
continue;
|
|
105
|
+
if (typeof member === "string") {
|
|
106
|
+
if (!said(member))
|
|
107
|
+
return null;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const target = acdcEdgeTarget(member);
|
|
111
|
+
if (target === false)
|
|
112
|
+
return null;
|
|
113
|
+
if (target === null) {
|
|
114
|
+
if (!record(member))
|
|
115
|
+
return null;
|
|
116
|
+
groups.push(member);
|
|
117
|
+
}
|
|
118
|
+
else if (!nodes.has(target)) {
|
|
119
|
+
if (walk === "closed")
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
farNodes.add(target);
|
|
124
|
+
if (!seen.has(target))
|
|
125
|
+
queue.push(target);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (seen.size !== nodes.size)
|
|
131
|
+
return null;
|
|
132
|
+
const parents = new Map();
|
|
133
|
+
for (const [near, children] of dependencies) {
|
|
134
|
+
for (const far of children) {
|
|
135
|
+
if (!parents.has(far))
|
|
136
|
+
parents.set(far, new Set());
|
|
137
|
+
parents.get(far).add(near);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const dependencyOrder = order.filter((id) => dependencies.get(id).size === 0);
|
|
141
|
+
for (let i = 0; i < dependencyOrder.length; i++) {
|
|
142
|
+
for (const near of parents.get(dependencyOrder[i]) ?? []) {
|
|
143
|
+
const children = dependencies.get(near);
|
|
144
|
+
children.delete(dependencyOrder[i]);
|
|
145
|
+
if (!children.size)
|
|
146
|
+
dependencyOrder.push(near);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return dependencyOrder.length === nodes.size ? order : null;
|
|
150
|
+
}
|
|
42
151
|
/** Missing proof/pin dependencies retain their ordered schema causes for the existing escrow owner. */
|
|
43
152
|
function unknown(reason, retryable = false, schemas = []) {
|
|
44
153
|
return { kind: "unknown", reason, retryable, schemas };
|
|
@@ -54,11 +163,64 @@ function reduce(op, members) {
|
|
|
54
163
|
}
|
|
55
164
|
return { kind: op === "AND" ? "valid" : "invalid" };
|
|
56
165
|
}
|
|
166
|
+
/** Accepted delegation ancestry is the only evidence beyond the two ACDCs; missing KEL evidence can still arrive. */
|
|
167
|
+
function delegatedFrom(db, op, pre, ancestor) {
|
|
168
|
+
const ancestry = delegationAncestry(db, pre, ancestor);
|
|
169
|
+
if (ancestry.kind === "valid")
|
|
170
|
+
return { kind: "valid" };
|
|
171
|
+
if (ancestry.kind === "refused")
|
|
172
|
+
return { kind: "invalid" };
|
|
173
|
+
return unknown(`${op} delegation evidence: ${ancestry.reason}`, true);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Evaluate the unary relations of one leaf between its near and far ACDCs.
|
|
177
|
+
*
|
|
178
|
+
* Unrecognized tokens and the unimplemented NOT are non-retryable unknowns that
|
|
179
|
+
* are ANDed with, not substituted for, the recognized relations. Absent any
|
|
180
|
+
* explicit relation, I2I applies when the far node has an issuee, else NI2I.
|
|
181
|
+
* The delegative and issuer-identity groups are each latest-wins.
|
|
182
|
+
*/
|
|
183
|
+
function leafRelation(db, ops, near, far) {
|
|
184
|
+
const relations = [];
|
|
185
|
+
const unrecognized = ops.filter((token) => !unary.has(token));
|
|
186
|
+
if (unrecognized.length)
|
|
187
|
+
relations.push(unknown(`Unrecognized unary Edge operator ${unrecognized.join(", ")}.`));
|
|
188
|
+
if (ops.includes("NOT"))
|
|
189
|
+
relations.push(unknown("Unimplemented unary Edge operator NOT."));
|
|
190
|
+
const operators = [...ops];
|
|
191
|
+
if (!operators.some((token) => suppressDefault.has(token)))
|
|
192
|
+
operators.push(far.issuee !== null ? "I2I" : "NI2I");
|
|
193
|
+
const delegate = operators.findLast((token) => delegative.has(token));
|
|
194
|
+
const identity = operators.findLast((token) => issuerIdentity.has(token));
|
|
195
|
+
const truth = (value) => ({ kind: value ? "valid" : "invalid" });
|
|
196
|
+
if (operators.includes("E1E")) {
|
|
197
|
+
relations.push(truth(Boolean(near.issuee && far.issuee && near.issuee === far.issuee)));
|
|
198
|
+
}
|
|
199
|
+
if (delegate === "I2I")
|
|
200
|
+
relations.push(truth(Boolean(far.issuee && near.issuer === far.issuee)));
|
|
201
|
+
if (delegate === "DI2I") {
|
|
202
|
+
if (!near.issuer || !far.issuee)
|
|
203
|
+
relations.push({ kind: "invalid" });
|
|
204
|
+
else if (near.issuer !== far.issuee)
|
|
205
|
+
relations.push(delegatedFrom(db, "DI2I", near.issuer, far.issuee));
|
|
206
|
+
}
|
|
207
|
+
// Issuer identity never reads issuees.
|
|
208
|
+
if (identity) {
|
|
209
|
+
if (!near.issuer || !far.issuer)
|
|
210
|
+
relations.push({ kind: "invalid" });
|
|
211
|
+
else if (near.issuer !== far.issuer) {
|
|
212
|
+
relations.push(identity === "I1I" ? { kind: "invalid" } : delegatedFrom(db, "DI1I", near.issuer, far.issuer));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return reduce("AND", relations);
|
|
216
|
+
}
|
|
57
217
|
/**
|
|
58
218
|
* Validate every own schema, then conjoin each caller verdict with its complete edge expression.
|
|
59
219
|
* Every branch is inspected for malformed shape, even when its truth value is unused.
|
|
220
|
+
* Under an open walk an undisclosed far node is a non-retryable unknown for its leaf.
|
|
60
221
|
* Protocol callers supply issuer authentication; applications supply their state policy.
|
|
61
|
-
*
|
|
222
|
+
* The graph must come from `walkAcdcGraph` (directly or through a protocol walk).
|
|
223
|
+
* This helper reads schemas and KEL state but writes no records and publishes no cues.
|
|
62
224
|
*/
|
|
63
225
|
export function evaluateChain(graph, verdicts, db) {
|
|
64
226
|
// Own schemas are global obligations, unlike optional edge pins and node verdicts.
|
|
@@ -78,12 +240,15 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
78
240
|
if (!node || !auth)
|
|
79
241
|
return null;
|
|
80
242
|
memo.set(id, unknown(`Node ${id} is already being evaluated.`));
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
243
|
+
const section = acdcEdgeSection(node.sad);
|
|
244
|
+
if (!section)
|
|
83
245
|
return null;
|
|
84
246
|
const members = [auth];
|
|
85
|
-
|
|
86
|
-
|
|
247
|
+
if (section.kind === "compact") {
|
|
248
|
+
members.push(unknown(`Node ${id} carries compact Edge Section ${section.said}, which cannot be evaluated.`));
|
|
249
|
+
}
|
|
250
|
+
else if (section.kind === "expanded") {
|
|
251
|
+
const result = evaluateGroup(section.section, node, []);
|
|
87
252
|
if (!result)
|
|
88
253
|
return null;
|
|
89
254
|
members.push(result);
|
|
@@ -92,50 +257,41 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
92
257
|
memo.set(id, result);
|
|
93
258
|
return result;
|
|
94
259
|
};
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
return null;
|
|
99
|
-
const pins = Object.hasOwn(edge, "s") ? [...inherited, edge.s] : inherited;
|
|
100
|
-
if (target !== null)
|
|
101
|
-
return evaluateLeaf(edge, target, near, pins);
|
|
102
|
-
const op = Object.hasOwn(edge, "o") ? edge.o : "AND";
|
|
260
|
+
const evaluateGroup = (group, near, inherited) => {
|
|
261
|
+
const pins = Object.hasOwn(group, "s") ? [...inherited, group.s] : inherited;
|
|
262
|
+
const op = Object.hasOwn(group, "o") ? group.o : "AND";
|
|
103
263
|
if (typeof op !== "string")
|
|
104
264
|
return null;
|
|
105
265
|
const members = [];
|
|
106
|
-
for (const [label, member] of Object.entries(
|
|
266
|
+
for (const [label, member] of Object.entries(group)) {
|
|
107
267
|
if (acdcGroupLabels.has(label))
|
|
108
268
|
continue;
|
|
109
269
|
if (typeof member === "string") {
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
if (!record(member))
|
|
270
|
+
if (!said(member))
|
|
114
271
|
return null;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return null;
|
|
118
|
-
members.push(result);
|
|
272
|
+
members.push(unknown(`Compact Edge ${label} cannot be dereferenced.`));
|
|
273
|
+
continue;
|
|
119
274
|
}
|
|
275
|
+
const target = acdcEdgeTarget(member);
|
|
276
|
+
if (target === false || !record(member))
|
|
277
|
+
return null;
|
|
278
|
+
const result = target === null ? evaluateGroup(member, near, pins) : evaluateLeaf(member, target, near, pins);
|
|
279
|
+
if (!result)
|
|
280
|
+
return null;
|
|
281
|
+
members.push(result);
|
|
120
282
|
}
|
|
121
283
|
if (!members.length)
|
|
122
284
|
return null;
|
|
123
285
|
return op === "AND" || op === "OR" ? reduce(op, members) : unknown(`Unsupported Edge-group operator ${op}.`);
|
|
124
286
|
};
|
|
125
|
-
const evaluateLeaf = (edge, target, near,
|
|
126
|
-
const
|
|
127
|
-
if (!far)
|
|
128
|
-
return null;
|
|
287
|
+
const evaluateLeaf = (edge, target, near, inherited) => {
|
|
288
|
+
const pins = Object.hasOwn(edge, "s") ? [...inherited, edge.s] : inherited;
|
|
129
289
|
const op = edge.o;
|
|
130
290
|
const ops = op == null ? [] : typeof op === "string" ? [op] : Array.isArray(op) ? [...op] : null;
|
|
131
|
-
if (!ops)
|
|
291
|
+
if (!ops || !ops.every((token) => typeof token === "string"))
|
|
132
292
|
return null;
|
|
133
293
|
// Pin shape is morphological, so validate it before unsupported tokens or relations.
|
|
134
294
|
const resolved = [];
|
|
135
|
-
const ownSchema = far.schema;
|
|
136
|
-
const ownSchemaId = record(ownSchema) ? ownSchema.$id : ownSchema;
|
|
137
|
-
if (pins.length && typeof ownSchemaId !== "string")
|
|
138
|
-
return null;
|
|
139
295
|
for (const pin of pins) {
|
|
140
296
|
if (typeof pin === "string") {
|
|
141
297
|
if (!said(pin))
|
|
@@ -159,55 +315,33 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
159
315
|
else
|
|
160
316
|
return null;
|
|
161
317
|
}
|
|
162
|
-
|
|
163
|
-
if (
|
|
164
|
-
|
|
318
|
+
const far = graph.nodes.get(target)?.body;
|
|
319
|
+
if (!far) {
|
|
320
|
+
// A closed walk never yields a graph with an undisclosed target.
|
|
321
|
+
return graph.walk === "open" ? unknown(`Far node ${target} is not disclosed.`) : null;
|
|
165
322
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (relation.kind === "refused")
|
|
184
|
-
matched = false;
|
|
185
|
-
else if (relation.kind === "pending")
|
|
186
|
-
pending = unknown(relation.reason, true);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
own = { kind: matched ? "valid" : "invalid" };
|
|
190
|
-
if (matched) {
|
|
191
|
-
for (let pin of resolved) {
|
|
192
|
-
if (pin === ownSchemaId && record(ownSchema))
|
|
193
|
-
pin = ownSchema;
|
|
194
|
-
const result = validateSchema(far, db, pin);
|
|
195
|
-
if (result.kind === "valid")
|
|
196
|
-
continue;
|
|
197
|
-
own = result.kind === "missing"
|
|
198
|
-
? unknown(`Missing edge schema ${result.said}.`, true, [result.said])
|
|
199
|
-
: { kind: "invalid" };
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
// Pending delegation cannot replace a pin's decided refusal.
|
|
204
|
-
if (pending)
|
|
205
|
-
own = reduce("AND", [own, pending]);
|
|
323
|
+
const ownSchema = far.schema;
|
|
324
|
+
const ownSchemaId = record(ownSchema) ? ownSchema.$id : ownSchema;
|
|
325
|
+
if (pins.length && typeof ownSchemaId !== "string")
|
|
326
|
+
return null;
|
|
327
|
+
const relation = leafRelation(db, ops, near, far);
|
|
328
|
+
const own = [relation];
|
|
329
|
+
// A decided relation refusal needs no pin evidence; otherwise every pin is evaluated, not only the first failure.
|
|
330
|
+
if (relation.kind !== "invalid") {
|
|
331
|
+
for (let pin of resolved) {
|
|
332
|
+
if (pin === ownSchemaId && record(ownSchema))
|
|
333
|
+
pin = ownSchema;
|
|
334
|
+
const result = validateSchema(far, db, pin);
|
|
335
|
+
if (result.kind === "valid")
|
|
336
|
+
continue;
|
|
337
|
+
own.push(result.kind === "missing"
|
|
338
|
+
? unknown(`Missing edge schema ${result.said}.`, true, [result.said])
|
|
339
|
+
: { kind: "invalid" });
|
|
206
340
|
}
|
|
207
341
|
}
|
|
208
342
|
// Do not short-circuit a far subtree: its shape cannot be outvoted by this leaf.
|
|
209
343
|
const farVerdict = evaluateNode(target);
|
|
210
|
-
return farVerdict ? reduce("AND", [own, farVerdict]) : null;
|
|
344
|
+
return farVerdict ? reduce("AND", [reduce("AND", own), farVerdict]) : null;
|
|
211
345
|
};
|
|
212
346
|
return graph.order.length ? evaluateNode(graph.order[0]) : null;
|
|
213
347
|
}
|
|
@@ -76,7 +76,7 @@ export class RegistryObserver {
|
|
|
76
76
|
const baser = this.store.baser;
|
|
77
77
|
if (baser.readonly)
|
|
78
78
|
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
79
|
-
return baser.
|
|
79
|
+
return baser.transaction(() => {
|
|
80
80
|
this.store.putEvent(serder);
|
|
81
81
|
this.store.escrowMissingAnchor(event.regid, Number(event.sn), event.said);
|
|
82
82
|
if (opening)
|
|
@@ -106,7 +106,7 @@ export class RegistryObserver {
|
|
|
106
106
|
}
|
|
107
107
|
/** Stored inception is durable issuer identity, including while its anchor is still absent. */
|
|
108
108
|
engine(regid) {
|
|
109
|
-
if (!this.store.baser.
|
|
109
|
+
if (!this.store.baser.opened)
|
|
110
110
|
throw new DatabaseNotOpenError("Registry observer store is closed.");
|
|
111
111
|
const rip = this.store.event(regid);
|
|
112
112
|
if (!rip) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Public ACDC registry database layout and joined LMDB lifecycle. */
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { LMDBer } from "../db/core/lmdber.js";
|
|
2
|
+
import { Diger, NumberPrimitive, Saider, SerderACDC } from "cesr-ts";
|
|
3
|
+
import { StoreOwner } from "../db/core/store-owner.js";
|
|
5
4
|
import { B64OnIoSetSuber, BytesSuber, CatCesrSuber, CesrOnSuber, CesrSuber, SerderSuber } from "../db/subing.js";
|
|
6
5
|
/**
|
|
7
6
|
* Own one environment for public registry TEL bodies, accepted ordinals and heads.
|
|
@@ -9,24 +8,9 @@ import { B64OnIoSetSuber, BytesSuber, CatCesrSuber, CesrOnSuber, CesrSuber, Serd
|
|
|
9
8
|
* evidence nor migrates rows. Every current store has anchor and escrow tables.
|
|
10
9
|
* Construction stays closed; callers own reopen and joined close.
|
|
11
10
|
*/
|
|
12
|
-
export class RegBaser extends
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!this.env)
|
|
16
|
-
throw new DatabaseNotOpenError("Registry environment is closed.");
|
|
17
|
-
// Native lmdb-js exposes its C-string terminator in root metadata keys;
|
|
18
|
-
// the Deno backend also supports the unterminated representation.
|
|
19
|
-
return this.env.getBinary(b(name)) !== undefined
|
|
20
|
-
|| this.env.getBinary(b(`${name}\0`)) !== undefined;
|
|
21
|
-
}
|
|
22
|
-
constructor(options = {}) {
|
|
23
|
-
super(options, {
|
|
24
|
-
tailDirPath: "keri/acdc/reg",
|
|
25
|
-
cleanTailDirPath: "keri/clean/acdc/reg",
|
|
26
|
-
altTailDirPath: options.compat ? ".keri/acdc/reg" : ".tufa/acdc/reg",
|
|
27
|
-
altCleanTailDirPath: options.compat ? ".keri/clean/acdc/reg" : ".tufa/clean/acdc/reg",
|
|
28
|
-
tempPrefix: "keri_acdc_reg_",
|
|
29
|
-
});
|
|
11
|
+
export class RegBaser extends StoreOwner {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments);
|
|
30
14
|
/** Event-SAID -> parsed rip/bup body; body presence alone is not acceptance. */
|
|
31
15
|
Object.defineProperty(this, "evts", {
|
|
32
16
|
enumerable: true,
|
|
@@ -79,17 +63,17 @@ export class RegBaser extends LMDBer {
|
|
|
79
63
|
}
|
|
80
64
|
/** Rebind the same environment's typed tables after every joined reopen. */
|
|
81
65
|
*reopen(options = {}) {
|
|
82
|
-
const opened = yield*
|
|
66
|
+
const opened = yield* this.store.reopen(options);
|
|
83
67
|
if (!opened)
|
|
84
68
|
return false;
|
|
85
69
|
try {
|
|
86
|
-
this.evts = new SerderSuber(this, { subkey: "evts.", ctor: SerderACDC });
|
|
87
|
-
this.tels = new CesrOnSuber(this, { subkey: "tels.", ctor: Saider });
|
|
88
|
-
this.heads = new CesrSuber(this, { subkey: "heds.", ctor: Saider });
|
|
89
|
-
this.openings = new BytesSuber(this, { subkey: "openings." });
|
|
90
|
-
this.ancs = new CatCesrSuber(this, { subkey: "ancs.", ctor: [NumberPrimitive, Diger] });
|
|
91
|
-
this.maes = new B64OnIoSetSuber(this, { subkey: "maes." });
|
|
92
|
-
this.ooes = new B64OnIoSetSuber(this, { subkey: "ooes." });
|
|
70
|
+
this.evts = new SerderSuber(this.store, { subkey: "evts.", ctor: SerderACDC });
|
|
71
|
+
this.tels = new CesrOnSuber(this.store, { subkey: "tels.", ctor: Saider });
|
|
72
|
+
this.heads = new CesrSuber(this.store, { subkey: "heds.", ctor: Saider });
|
|
73
|
+
this.openings = new BytesSuber(this.store, { subkey: "openings." });
|
|
74
|
+
this.ancs = new CatCesrSuber(this.store, { subkey: "ancs.", ctor: [NumberPrimitive, Diger] });
|
|
75
|
+
this.maes = new B64OnIoSetSuber(this.store, { subkey: "maes." });
|
|
76
|
+
this.ooes = new B64OnIoSetSuber(this.store, { subkey: "ooes." });
|
|
93
77
|
return true;
|
|
94
78
|
}
|
|
95
79
|
catch (error) {
|
|
@@ -98,3 +82,10 @@ export class RegBaser extends LMDBer {
|
|
|
98
82
|
}
|
|
99
83
|
}
|
|
100
84
|
}
|
|
85
|
+
/** Placement of this store kind. */
|
|
86
|
+
Object.defineProperty(RegBaser, "Family", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: { tail: "acdc/reg" }
|
|
91
|
+
});
|
|
@@ -256,12 +256,11 @@ export class RegistryEventer {
|
|
|
256
256
|
const previous = this.acceptedEvent(event);
|
|
257
257
|
if (previous)
|
|
258
258
|
return previous;
|
|
259
|
-
|
|
260
|
-
if (!env)
|
|
259
|
+
if (!this.store.baser.opened)
|
|
261
260
|
throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
|
|
262
261
|
if (this.store.baser.readonly)
|
|
263
262
|
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
264
|
-
return
|
|
263
|
+
return this.store.baser.transaction(() => {
|
|
265
264
|
const prior = this.acceptedAt(event.regid, Number(event.sn) - 1);
|
|
266
265
|
if (prior && prior.said !== event.prior)
|
|
267
266
|
return { kind: "reject", reason: "prior" };
|
|
@@ -303,12 +302,11 @@ export class RegistryEventer {
|
|
|
303
302
|
this.regk = event.regid;
|
|
304
303
|
return previous;
|
|
305
304
|
}
|
|
306
|
-
|
|
307
|
-
if (!env)
|
|
305
|
+
if (!this.store.baser.opened)
|
|
308
306
|
throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
|
|
309
307
|
if (this.store.baser.readonly)
|
|
310
308
|
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
311
|
-
const decision =
|
|
309
|
+
const decision = this.store.baser.transaction(() => {
|
|
312
310
|
const previous = this.acceptedEvent(event);
|
|
313
311
|
if (previous)
|
|
314
312
|
return previous;
|
|
@@ -37,10 +37,13 @@ function retainedOpening(raw) {
|
|
|
37
37
|
export class RegistryRecord extends RawRecord {
|
|
38
38
|
}
|
|
39
39
|
/** Acquire one backing owner; failures/cancellation join cleanup before ownership transfers. */
|
|
40
|
-
export function* openRegistry({
|
|
41
|
-
if (
|
|
42
|
-
throw new ValidationError("
|
|
43
|
-
|
|
40
|
+
export function* openRegistry({ reopen = true, opener, ...options } = {}) {
|
|
41
|
+
if (!opener)
|
|
42
|
+
throw new ValidationError("A registry store needs a store opener.");
|
|
43
|
+
return yield* adoptRegistry(new RegBaser(opener.create(RegBaser.Family, options)), reopen);
|
|
44
|
+
}
|
|
45
|
+
/** Take ownership of a constructed registry owner, reopening it unless told otherwise. */
|
|
46
|
+
export function* adoptRegistry(baser, reopen = true) {
|
|
44
47
|
let delivered = false;
|
|
45
48
|
try {
|
|
46
49
|
if (reopen && !(yield* baser.reopen()))
|
|
@@ -81,7 +84,7 @@ export class RegistryStore {
|
|
|
81
84
|
writable: true,
|
|
82
85
|
value: null
|
|
83
86
|
});
|
|
84
|
-
Object.defineProperty(this, "
|
|
87
|
+
Object.defineProperty(this, "aliasTable", {
|
|
85
88
|
enumerable: true,
|
|
86
89
|
configurable: true,
|
|
87
90
|
writable: true,
|
|
@@ -90,13 +93,13 @@ export class RegistryStore {
|
|
|
90
93
|
}
|
|
91
94
|
/** Local alias mapper is optional; refresh it after the owner's reopen. */
|
|
92
95
|
get records() {
|
|
93
|
-
if (!this.baser.
|
|
96
|
+
if (!this.baser.opened)
|
|
94
97
|
throw new DatabaseNotOpenError("Registry backing store is closed.");
|
|
95
|
-
if (this.
|
|
98
|
+
if (this.aliasTable !== this.baser.evts.sdb) {
|
|
96
99
|
this.aliases = this.baser.hasTable("regs.")
|
|
97
|
-
? new Komer(this.baser, { subkey: "regs.", recordClass: RegistryRecord })
|
|
100
|
+
? new Komer(this.baser.store, { subkey: "regs.", recordClass: RegistryRecord })
|
|
98
101
|
: null;
|
|
99
|
-
this.
|
|
102
|
+
this.aliasTable = this.baser.evts.sdb;
|
|
100
103
|
}
|
|
101
104
|
return this.aliases;
|
|
102
105
|
}
|
|
@@ -110,7 +113,7 @@ export class RegistryStore {
|
|
|
110
113
|
if (!records) {
|
|
111
114
|
if (this.baser.readonly)
|
|
112
115
|
throw new DatabaseOperationError("Cannot create readonly registry aliases.");
|
|
113
|
-
records = this.aliases = new Komer(this.baser, { subkey: "regs.", recordClass: RegistryRecord });
|
|
116
|
+
records = this.aliases = new Komer(this.baser.store, { subkey: "regs.", recordClass: RegistryRecord });
|
|
114
117
|
}
|
|
115
118
|
return records;
|
|
116
119
|
}
|
|
@@ -13,12 +13,8 @@ export function* createRegery({ hby, baser, ...options }) {
|
|
|
13
13
|
try {
|
|
14
14
|
if (!baser) {
|
|
15
15
|
baser = yield* openRegistry({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
temp: hby.temp,
|
|
19
|
-
headDirPath: hby.headDirPath,
|
|
20
|
-
compat: hby.compat,
|
|
21
|
-
readonly: hby.readonly,
|
|
16
|
+
...hby.storeIdentity(),
|
|
17
|
+
opener: hby.opener,
|
|
22
18
|
...options,
|
|
23
19
|
});
|
|
24
20
|
}
|
|
@@ -90,12 +86,11 @@ export class Regery {
|
|
|
90
86
|
const rip = regcept(hab.pre, options);
|
|
91
87
|
if (this.regs.has(rip.said))
|
|
92
88
|
throw new ValidationError(`Registry already exists: ${rip.said}`);
|
|
93
|
-
|
|
94
|
-
if (!env)
|
|
89
|
+
if (!this.baser.opened)
|
|
95
90
|
throw new DatabaseNotOpenError("Registry backing store is closed.");
|
|
96
91
|
const records = this.store.initializeRecords();
|
|
97
92
|
const registry = new Registry(hab, this.store, name);
|
|
98
|
-
|
|
93
|
+
this.baser.transaction(() => {
|
|
99
94
|
if (records.get(name))
|
|
100
95
|
throw new ValidationError(`Registry alias already exists: ${name}`);
|
|
101
96
|
const result = registry.processEvent(rip);
|