keri-ts 2.2.3 → 2.2.5
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/_dnt.polyfills.js +14 -14
- package/esm/keri/npm/src/acdc/registering.js +19 -0
- package/esm/keri/npm/src/acdc/salting.js +4 -0
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +34 -12
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +365 -32
- package/esm/keri/npm/src/app/credentials/credential-importing.js +33 -4
- package/esm/keri/npm/src/app/credentials/root-replicator.js +27 -15
- package/esm/keri/npm/src/app/credentials/schema-resolving.js +5 -1
- package/esm/keri/npm/src/app/credentials/tel-publishing.js +16 -7
- package/esm/keri/npm/src/app/delivery/forwarding.js +188 -47
- package/esm/keri/npm/src/app/delivery/relaying.js +232 -0
- package/esm/keri/npm/src/app/delivery/respondant.js +8 -5
- package/esm/keri/npm/src/app/exchanges/exchange-messaging.js +1 -1
- package/esm/keri/npm/src/app/exchanges/exchanging.js +65 -9
- package/esm/keri/npm/src/app/identity/delegating.js +66 -9
- package/esm/keri/npm/src/app/identity/habbing.js +190 -71
- package/esm/keri/npm/src/app/identity/keeping.js +111 -39
- package/esm/keri/npm/src/app/identity/retire-identifier.js +98 -0
- package/esm/keri/npm/src/app/ipex/disclosure-replaying.js +116 -0
- package/esm/keri/npm/src/app/ipex/group-ipex.js +122 -25
- package/esm/keri/npm/src/app/ipex/group-issuance.js +109 -23
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +36 -22
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +53 -3
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +7 -2
- package/esm/keri/npm/src/app/ipex/issuance.js +131 -35
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +4 -2
- package/esm/keri/npm/src/app/ipex/presenting.js +3 -18
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +2 -1
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +16 -3
- package/esm/keri/npm/src/app/mailbox/agent-inbox.js +292 -0
- package/esm/keri/npm/src/app/mailbox/forward-handler.js +298 -52
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +26 -31
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +70 -62
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +20 -4
- package/esm/keri/npm/src/app/multisig/counseling.js +75 -27
- package/esm/keri/npm/src/app/multisig/group-members.js +41 -5
- package/esm/keri/npm/src/app/multisig/grouping.js +50 -2
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +3 -18
- package/esm/keri/npm/src/app/multisig/proposing.js +1 -16
- package/esm/keri/npm/src/app/multisig/rejoin-group.js +99 -0
- package/esm/keri/npm/src/app/multisig/replace-member.js +29 -8
- package/esm/keri/npm/src/app/protocol/parsering.js +45 -17
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +62 -27
- package/esm/keri/npm/src/app/queries/query-replies.js +0 -22
- package/esm/keri/npm/src/app/queries/relay-refresh.js +81 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +190 -40
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +46 -73
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +45 -5
- package/esm/keri/npm/src/app/runtime/doing.js +25 -0
- package/esm/keri/npm/src/app/runtime/operation-owners.js +26 -56
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +7 -4
- package/esm/keri/npm/src/app/transport/http-client.js +20 -2
- package/esm/keri/npm/src/app/transport/message-source.js +2 -1
- package/esm/keri/npm/src/app/transport/messengering.js +39 -8
- package/esm/keri/npm/src/app/witness/ingress.js +7 -0
- package/esm/keri/npm/src/app/witness/receipt-client.js +43 -16
- package/esm/keri/npm/src/app/witness/receipting.js +62 -20
- package/esm/keri/npm/src/cli/messaging/multisig.js +4 -3
- package/esm/keri/npm/src/core/errors.js +73 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +11 -2
- package/esm/keri/npm/src/core/kel/eventing.js +25 -28
- package/esm/keri/npm/src/core/kel/kever.js +15 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +8 -0
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +25 -6
- package/esm/keri/npm/src/core/mailbox/kram-time.js +34 -6
- package/esm/keri/npm/src/core/mailbox/kraming.js +58 -2
- package/esm/keri/npm/src/core/routing.js +18 -25
- package/esm/keri/npm/src/core/scheming.js +12 -5
- package/esm/keri/npm/src/core/wire-fields.js +126 -0
- package/esm/keri/npm/src/db/basing.js +4 -13
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +3 -2
- package/esm/keri/npm/src/db/core/lmdber.js +25 -6
- package/esm/keri/npm/src/db/core/memstore.js +4 -0
- package/esm/keri/npm/src/db/core/store-owner.js +4 -0
- package/esm/keri/npm/src/db/core/webdber.js +85 -27
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +13 -0
- package/esm/keri/npm/src/db/subing.js +4 -0
- package/esm/keri/npm/src/runtime/index.js +11 -5
- package/esm/keri/npm/src/time/mod.js +5 -0
- package/esm/keri/npm/src/vdr/credential-tsn-record.js +2 -7
- package/esm/keri/npm/src/vdr/eventing.js +28 -19
- package/esm/keri/npm/src/vdr/registry-tsn-record.js +3 -13
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +1 -1
- package/types/_dnt.polyfills.d.ts +9 -9
- package/types/_dnt.polyfills.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +6 -0
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +12 -2
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobiery.d.ts +144 -7
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-importing.d.ts +8 -0
- package/types/app/credentials/credential-importing.d.ts.map +1 -1
- package/types/app/credentials/root-replicator.d.ts +19 -8
- package/types/app/credentials/root-replicator.d.ts.map +1 -1
- package/types/app/credentials/schema-resolving.d.ts.map +1 -1
- package/types/app/credentials/tel-publishing.d.ts +4 -2
- package/types/app/credentials/tel-publishing.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +75 -7
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/delivery/relaying.d.ts +144 -0
- package/types/app/delivery/relaying.d.ts.map +1 -0
- package/types/app/delivery/respondant.d.ts +9 -2
- package/types/app/delivery/respondant.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +36 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +6 -0
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/habbing.d.ts +106 -19
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +54 -19
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/identity/retire-identifier.d.ts +24 -0
- package/types/app/identity/retire-identifier.d.ts.map +1 -0
- package/types/app/ipex/disclosure-replaying.d.ts +61 -0
- package/types/app/ipex/disclosure-replaying.d.ts.map +1 -0
- package/types/app/ipex/group-ipex.d.ts +60 -14
- package/types/app/ipex/group-ipex.d.ts.map +1 -1
- package/types/app/ipex/group-issuance.d.ts +48 -6
- package/types/app/ipex/group-issuance.d.ts.map +1 -1
- package/types/app/ipex/ipex-discloser.d.ts +14 -2
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts +23 -2
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +5 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +35 -11
- package/types/app/ipex/issuance.d.ts.map +1 -1
- package/types/app/ipex/pending-presentations.d.ts +4 -2
- package/types/app/ipex/pending-presentations.d.ts.map +1 -1
- package/types/app/ipex/presenting.d.ts.map +1 -1
- package/types/app/ipex/receive-issuance.d.ts +2 -1
- package/types/app/ipex/receive-issuance.d.ts.map +1 -1
- package/types/app/ipex/unblinding-workflow.d.ts +4 -1
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -1
- package/types/app/mailbox/agent-inbox.d.ts +126 -0
- package/types/app/mailbox/agent-inbox.d.ts.map +1 -0
- package/types/app/mailbox/forward-handler.d.ts +114 -14
- package/types/app/mailbox/forward-handler.d.ts.map +1 -1
- package/types/app/mailbox/kel-publisher.d.ts +12 -22
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -1
- package/types/app/mailbox/mailbox-poller.d.ts +40 -24
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +19 -5
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +34 -11
- package/types/app/multisig/counseling.d.ts.map +1 -1
- package/types/app/multisig/group-members.d.ts +17 -1
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +17 -1
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +0 -8
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposing.d.ts +4 -19
- package/types/app/multisig/proposing.d.ts.map +1 -1
- package/types/app/multisig/rejoin-group.d.ts +119 -0
- package/types/app/multisig/rejoin-group.d.ts.map +1 -0
- package/types/app/multisig/replace-member.d.ts +15 -1
- package/types/app/multisig/replace-member.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +21 -2
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +31 -6
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-replies.d.ts +4 -8
- package/types/app/queries/query-replies.d.ts.map +1 -1
- package/types/app/queries/relay-refresh.d.ts +26 -0
- package/types/app/queries/relay-refresh.d.ts.map +1 -0
- package/types/app/queries/witness-inquisitor.d.ts +57 -6
- package/types/app/queries/witness-inquisitor.d.ts.map +1 -1
- package/types/app/runtime/agent-runtime.d.ts +34 -3
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +15 -3
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/doing.d.ts +17 -0
- package/types/app/runtime/doing.d.ts.map +1 -1
- package/types/app/runtime/operation-owners.d.ts +16 -26
- package/types/app/runtime/operation-owners.d.ts.map +1 -1
- package/types/app/runtime/workflow-contract.d.ts +21 -6
- package/types/app/runtime/workflow-contract.d.ts.map +1 -1
- package/types/app/transport/http-client.d.ts +9 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +6 -3
- package/types/app/transport/message-source.d.ts.map +1 -1
- package/types/app/transport/messengering.d.ts +10 -1
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/witness/ingress.d.ts +1 -0
- package/types/app/witness/ingress.d.ts.map +1 -1
- package/types/app/witness/receipt-client.d.ts +19 -1
- package/types/app/witness/receipt-client.d.ts.map +1 -1
- package/types/app/witness/receipting.d.ts +24 -1
- package/types/app/witness/receipting.d.ts.map +1 -1
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/core/cues.d.ts +53 -1
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/errors.d.ts +32 -0
- package/types/core/errors.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -1
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever-decisions.d.ts +3 -1
- package/types/core/kel/kever-decisions.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +7 -1
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +6 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +5 -1
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/core/mailbox/kram-time.d.ts +26 -2
- package/types/core/mailbox/kram-time.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +14 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/routing.d.ts +3 -7
- package/types/core/routing.d.ts.map +1 -1
- package/types/core/scheming.d.ts.map +1 -1
- package/types/core/wire-fields.d.ts +56 -0
- package/types/core/wire-fields.d.ts.map +1 -0
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/dber.d.ts +5 -0
- package/types/db/core/dber.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +3 -2
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -1
- package/types/db/core/lmdber.d.ts +6 -0
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/memstore.d.ts +2 -0
- package/types/db/core/memstore.d.ts.map +1 -1
- package/types/db/core/store-owner.d.ts +2 -0
- package/types/db/core/store-owner.d.ts.map +1 -1
- package/types/db/core/webdber.d.ts +32 -6
- package/types/db/core/webdber.d.ts.map +1 -1
- package/types/db/exchange/exchange-records.d.ts +4 -0
- package/types/db/exchange/exchange-records.d.ts.map +1 -1
- package/types/db/mailbox/mailboxing.d.ts +10 -1
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/subing.d.ts +2 -0
- package/types/db/subing.d.ts.map +1 -1
- package/types/runtime/index.d.ts +20 -14
- package/types/runtime/index.d.ts.map +1 -1
- package/types/time/mod.d.ts +2 -0
- package/types/time/mod.d.ts.map +1 -1
- package/types/vdr/credential-tsn-record.d.ts.map +1 -1
- package/types/vdr/eventing.d.ts.map +1 -1
- package/types/vdr/registry-tsn-record.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/app/runtime/signer-conditions.js +0 -51
- package/types/app/runtime/signer-conditions.d.ts +0 -32
- package/types/app/runtime/signer-conditions.d.ts.map +0 -1
|
@@ -8,7 +8,6 @@ import { DatabaseNotOpenError } from "../../core/errors.js";
|
|
|
8
8
|
import { Kevery } from "../../core/kel/eventing.js";
|
|
9
9
|
import { Kramer } from "../../core/mailbox/kraming.js";
|
|
10
10
|
import { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../../core/mailbox/mailbox-topics.js";
|
|
11
|
-
import { Roles } from "../../core/roles.js";
|
|
12
11
|
import { Revery } from "../../core/routing.js";
|
|
13
12
|
import { openOwner } from "../../db/core/store-owner.js";
|
|
14
13
|
import { Mailboxer } from "../../db/mailbox/mailboxing.js";
|
|
@@ -20,12 +19,12 @@ import { Authenticator } from "../bootstrap/authenticating.js";
|
|
|
20
19
|
import { loadOobiHandlers, Oobiery, oobiTerminalState } from "../bootstrap/oobiery.js";
|
|
21
20
|
import { publishPendingTel } from "../credentials/tel-publishing.js";
|
|
22
21
|
import { Poster } from "../delivery/forwarding.js";
|
|
22
|
+
import { relayEndpoint, relayOnlyHttpClient } from "../delivery/relaying.js";
|
|
23
23
|
import { ReplyStreams } from "../delivery/reply-streams.js";
|
|
24
24
|
import { Respondant } from "../delivery/respondant.js";
|
|
25
25
|
import { Exchanger, RouteRefuser } from "../exchanges/exchanging.js";
|
|
26
26
|
import { loadChallengeHandlers } from "../identity/challenging.js";
|
|
27
27
|
import { Anchorer, loadDelegationHandlers } from "../identity/delegating.js";
|
|
28
|
-
import { SignerNotHeldError } from "../identity/keeping.js";
|
|
29
28
|
import { loadIpexHandlers } from "../ipex/ipexing.js";
|
|
30
29
|
import { ForwardHandler } from "../mailbox/forward-handler.js";
|
|
31
30
|
import { KEL_PUBLISHER_PACING, KelPublisher, kelPublisherDo } from "../mailbox/kel-publisher.js";
|
|
@@ -44,10 +43,9 @@ import { QueryReplies } from "../queries/query-replies.js";
|
|
|
44
43
|
import { WitnessInquisitor } from "../queries/witness-inquisitor.js";
|
|
45
44
|
import { Receiptor } from "../witness/receipting.js";
|
|
46
45
|
import { cueDo } from "./cue-runtime.js";
|
|
47
|
-
import {
|
|
46
|
+
import { doEveryOnWrite, PROTOCOL_PACING } from "./doing.js";
|
|
48
47
|
import { IpexAuxiliaries } from "./ipex-auxiliaries.js";
|
|
49
48
|
import { composeOwners, operationOwnersDo, OWNER_PACING, } from "./operation-owners.js";
|
|
50
|
-
import { SignerConditions } from "./signer-conditions.js";
|
|
51
49
|
import { signalerChangeSink } from "./workflow-contract.js";
|
|
52
50
|
import { observeUntil } from "./workflow-contract.js";
|
|
53
51
|
/**
|
|
@@ -67,12 +65,18 @@ import { observeUntil } from "./workflow-contract.js";
|
|
|
67
65
|
* @throws Dependency mismatch/acquisition errors propagate after owned resource cleanup.
|
|
68
66
|
*/
|
|
69
67
|
export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
68
|
+
// An edge reaches only its relay: every component below, and `runtime.http`, gets the guarded client.
|
|
69
|
+
if (options.relay)
|
|
70
|
+
http = relayOnlyHttpClient(http, hby, options.relay);
|
|
70
71
|
const injectedSignaler = options.signaler ?? options.notifier?.signaler;
|
|
71
72
|
if ((options.notifier && options.notifier.signator !== hby.signator)
|
|
72
73
|
|| (options.noter && options.notifier && options.noter !== options.notifier.noter)
|
|
73
74
|
|| (options.signaler && options.notifier && options.signaler !== options.notifier.signaler)) {
|
|
74
75
|
throw new RangeError("AgentRuntime notification services require its exact Signator, Noter and Signaler");
|
|
75
76
|
}
|
|
77
|
+
if (options.relaying && !options.mailboxer && !options.enableMailboxStore) {
|
|
78
|
+
throw new RangeError("Relaying requires a mailbox store for /fwd intake");
|
|
79
|
+
}
|
|
76
80
|
const mailboxer = options.mailboxer
|
|
77
81
|
?? (options.enableMailboxStore ? (yield* openRuntimeMailboxer(hby)) : null);
|
|
78
82
|
const ownsMailboxer = options.mailboxer === undefined && mailboxer !== null;
|
|
@@ -146,11 +150,11 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
146
150
|
})
|
|
147
151
|
: null;
|
|
148
152
|
const replies = new QueryReplies(cues);
|
|
149
|
-
const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies, ipex ?? undefined);
|
|
153
|
+
const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies, ipex ?? undefined, options.relaying === true);
|
|
150
154
|
const reactor = new Reactor(protocol);
|
|
151
155
|
loadChallengeHandlers(hby.db, exc);
|
|
152
156
|
loadDelegationHandlers(hby, exc, notifier);
|
|
153
|
-
loadOobiHandlers(hby, exc, notifier);
|
|
157
|
+
loadOobiHandlers(hby, exc, notifier, options.relaying === true);
|
|
154
158
|
const mux = loadMultisigHandlers(hby, exc, { notifier, registry: protocol.registry, messageKevery: protocol.kvy });
|
|
155
159
|
loadIpexHandlers(hby, exc, {
|
|
156
160
|
notifier,
|
|
@@ -158,8 +162,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
158
162
|
grantWalk: options.grantWalk,
|
|
159
163
|
});
|
|
160
164
|
// Construction adopts stored copies an earlier handler-less Exchanger left unescrowed.
|
|
165
|
+
const changes = options.operationStores?.changes ?? (signaler ? signalerChangeSink(signaler) : undefined);
|
|
161
166
|
const registryRoot = options.registryRoots !== "refuse" && acdc
|
|
162
|
-
? new RegistryRoot(hby, acdc, notifier,
|
|
167
|
+
? new RegistryRoot(hby, acdc, notifier, changes)
|
|
163
168
|
: null;
|
|
164
169
|
if (registryRoot)
|
|
165
170
|
exc.addHandler(registryRoot);
|
|
@@ -175,7 +180,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
175
180
|
}
|
|
176
181
|
});
|
|
177
182
|
const postman = yield* resource(function* (provide) {
|
|
178
|
-
const postman = new Poster(hby, mailboxer, protocol, http, clock);
|
|
183
|
+
const postman = new Poster(hby, mailboxer, protocol, http, clock, options.relay ?? null);
|
|
179
184
|
try {
|
|
180
185
|
yield* provide(postman);
|
|
181
186
|
}
|
|
@@ -185,7 +190,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
185
190
|
});
|
|
186
191
|
const respondant = new Respondant(hby, postman);
|
|
187
192
|
if (mailboxer) {
|
|
188
|
-
exc.addHandler(new ForwardHandler(mailboxDirector));
|
|
193
|
+
exc.addHandler(new ForwardHandler(mailboxDirector, reactor, options.relaying ? postman : null));
|
|
189
194
|
}
|
|
190
195
|
for (const route of exc.routes.keys()) {
|
|
191
196
|
if (route === ForwardHandler.resource) {
|
|
@@ -206,20 +211,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
206
211
|
changes: signaler ? signalerChangeSink(signaler) : undefined,
|
|
207
212
|
retry: options.kelPublishRetry,
|
|
208
213
|
});
|
|
209
|
-
const
|
|
210
|
-
const mailboxPoller = new MailboxPoller(hby, mailboxDirector, http, clock, {
|
|
211
|
-
signerConditions,
|
|
212
|
-
onPolled: (pre, mailbox) => kelPublisher.prompt(pre, mailbox),
|
|
213
|
-
onUnauthorized: (pre, mailbox) => kelPublisher.repair(pre, mailbox),
|
|
214
|
-
timeouts: options.mailboxPolling,
|
|
215
|
-
});
|
|
216
|
-
// A mailbox role accepted from a reply (a group member's approved add, an OOBI) is acted on at the next tock.
|
|
217
|
-
revery.onEndRole = (cid, role) => {
|
|
218
|
-
if (role !== Roles.mailbox)
|
|
219
|
-
return;
|
|
220
|
-
kelPublisher.prompt(cid);
|
|
221
|
-
mailboxPoller.prompt(cid);
|
|
222
|
-
};
|
|
214
|
+
const mailboxPoller = new MailboxPoller(hby, mailboxDirector, http, clock, options.relay ?? null, { polls: kelPublisher.polls, timeouts: options.mailboxPolling });
|
|
223
215
|
for (const topic of [
|
|
224
216
|
DELEGATE_MAILBOX_TOPIC,
|
|
225
217
|
CREDENTIAL_MAILBOX_TOPIC,
|
|
@@ -230,7 +222,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
230
222
|
mailboxDirector.registerTopic(topic);
|
|
231
223
|
}
|
|
232
224
|
const querying = yield* resource(function* (provide) {
|
|
233
|
-
const inquisitor = new WitnessInquisitor(hby, protocol, http, clock);
|
|
225
|
+
const inquisitor = new WitnessInquisitor(hby, protocol, http, clock, options.relay ?? null);
|
|
234
226
|
try {
|
|
235
227
|
yield* provide(inquisitor);
|
|
236
228
|
}
|
|
@@ -239,17 +231,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
239
231
|
}
|
|
240
232
|
});
|
|
241
233
|
const delegating = new Anchorer(hby, postman, querying, protocol, http, clock);
|
|
242
|
-
//
|
|
243
|
-
const
|
|
244
|
-
const counselor = new Counselor(hby, {
|
|
245
|
-
receipt: (pre, options) => groupReceiptor.receipt(pre, { ...options, allowTcp: true }),
|
|
246
|
-
get: (pre, options) => groupReceiptor.get(pre, options),
|
|
247
|
-
}, clock, signaler ? signalerChangeSink(signaler) : undefined, { anchorer: delegating, querying }, {
|
|
248
|
-
rotated: (cue) => {
|
|
249
|
-
kelPublisher.rotated.push(cue);
|
|
250
|
-
owned?.rootReplicator?.prompt(cue.pre);
|
|
251
|
-
},
|
|
252
|
-
}, options.counselorReceiptRetry, groupEventForwarding(hby, postman));
|
|
234
|
+
// Only a runtime with operations owners and a registry root has a root replicator to drain this deck.
|
|
235
|
+
const groupChanges = registryRoot && ipex ? new Deck() : undefined;
|
|
236
|
+
const counselor = new Counselor(hby, new Receiptor(hby, protocol, http, clock), clock, signaler ? signalerChangeSink(signaler) : undefined, { anchorer: delegating, querying }, kelPublisher.rotated, groupChanges, options.counselorReceiptRetry, groupEventForwarding(hby, postman));
|
|
253
237
|
const owned = acdc && ipex
|
|
254
238
|
? composeOwners({
|
|
255
239
|
hby,
|
|
@@ -264,21 +248,26 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
264
248
|
registryRoot,
|
|
265
249
|
mux,
|
|
266
250
|
counselor,
|
|
251
|
+
groupChanges,
|
|
267
252
|
retry: options.operationRetry,
|
|
268
253
|
queryResendMs: options.issuanceQueryResendMs,
|
|
269
254
|
changes: signaler ? signalerChangeSink(signaler) : undefined,
|
|
270
255
|
}, options.operationStores)
|
|
271
256
|
: null;
|
|
272
|
-
const oobiery = new Oobiery(hby, protocol, revery, http, cues);
|
|
257
|
+
const oobiery = new Oobiery(hby, protocol, revery, http, cues, options.relay ? { relay: options.relay, postman, clock } : null);
|
|
273
258
|
oobiery.registerReplyRoutes(revery.rtr);
|
|
259
|
+
if (options.relay && !relayEndpoint(hby, options.relay))
|
|
260
|
+
oobiery.resolve(options.relay.oobi);
|
|
274
261
|
const authenticator = new Authenticator(hby, http);
|
|
275
262
|
return {
|
|
276
263
|
hby,
|
|
277
264
|
mailboxer,
|
|
265
|
+
relaying: options.relaying === true,
|
|
278
266
|
noter,
|
|
279
267
|
notifier,
|
|
280
268
|
signaler,
|
|
281
269
|
cues,
|
|
270
|
+
changes: changes ?? null,
|
|
282
271
|
reactor,
|
|
283
272
|
protocol,
|
|
284
273
|
replies,
|
|
@@ -296,7 +285,6 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
296
285
|
delegating,
|
|
297
286
|
counselor,
|
|
298
287
|
kelPublisher,
|
|
299
|
-
signerConditions,
|
|
300
288
|
ownerPacing: options.ownerPacing ?? OWNER_PACING,
|
|
301
289
|
publisherPacing: options.publisherPacing ?? KEL_PUBLISHER_PACING,
|
|
302
290
|
protocolPacing: options.protocolPacing ?? PROTOCOL_PACING,
|
|
@@ -618,6 +606,11 @@ export { runtimeTurn } from "./runtime-turn.js";
|
|
|
618
606
|
* delegation and ordinary query sending. The finalizer halts children in reverse
|
|
619
607
|
* order; store ownership remains with the composition scope.
|
|
620
608
|
*
|
|
609
|
+
* Each loop is a plain spawned fixed-tock doer. A loop that signs for a local habitat reads `Hab.canSign()` on its
|
|
610
|
+
* tock and skips a habitat that cannot sign yet (a store opened without its signer); a later `Manager.hold` lets
|
|
611
|
+
* that habitat act on the next tock. A `SignerNotHeldError` that still escapes a loop is a fault: the loop ends
|
|
612
|
+
* and the failure ends this operation.
|
|
613
|
+
*
|
|
621
614
|
* @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
|
|
622
615
|
* @param options Optional default query/cue signer, remote pollMailbox switch
|
|
623
616
|
* (default true) and command-owned queryCues Deck. Wire queryCues before starting
|
|
@@ -628,24 +621,25 @@ export function* runAgentRuntime(runtime, options = {}) {
|
|
|
628
621
|
runtime.querying.configure({ hab: options.hab });
|
|
629
622
|
const pacing = runtime.protocolPacing;
|
|
630
623
|
const telReceiptor = runtime.vdr ? new Receiptor(runtime.hby, runtime.protocol, runtime.http, runtime.clock) : null;
|
|
631
|
-
// A loop that needs a signer the host released waits for it; it never ends the runtime (see `surviving`).
|
|
632
|
-
const alive = (loop, make) => spawn(() => surviving(runtime, loop, make));
|
|
633
|
-
const stopHoldWatch = runtime.hby.mgr.onHold(() => runtime.signerConditions.held());
|
|
634
624
|
const tasks = [
|
|
635
|
-
yield*
|
|
636
|
-
yield*
|
|
625
|
+
yield* spawn(() => runtime.querying.deliverDo(pacing.tockMs)),
|
|
626
|
+
yield* spawn(() => runtime.postman.deliverDo(pacing.tockMs)),
|
|
637
627
|
...(runtime.vdr && telReceiptor
|
|
638
628
|
? [
|
|
639
|
-
yield*
|
|
629
|
+
yield* spawn(() => doEveryOnWrite(runtime.clock, pacing, {
|
|
630
|
+
get writeActivity() {
|
|
631
|
+
return runtime.hby.db.writeActivity + runtime.vdr.publication.reger.writeActivity;
|
|
632
|
+
},
|
|
633
|
+
}, () => publishPendingTel(runtime.hby, runtime.vdr.publication, telReceiptor, runtime.http, runtime.clock))),
|
|
640
634
|
]
|
|
641
635
|
: []),
|
|
642
|
-
yield*
|
|
643
|
-
yield*
|
|
644
|
-
yield*
|
|
645
|
-
yield*
|
|
636
|
+
yield* spawn(() => cueDo(runtime, options, pacing)),
|
|
637
|
+
yield* spawn(() => runtime.protocol.escrowDo(runtime.clock, pacing)),
|
|
638
|
+
yield* spawn(() => runtime.oobiery.oobiDo(runtime.clock, pacing)),
|
|
639
|
+
yield* spawn(() => runtime.authenticator.authDo(runtime.clock, pacing)),
|
|
646
640
|
...(runtime.signaler
|
|
647
641
|
? [
|
|
648
|
-
yield*
|
|
642
|
+
yield* spawn(() => runtime.signaler.signalDo(runtime.clock, pacing)),
|
|
649
643
|
]
|
|
650
644
|
: []),
|
|
651
645
|
...(options.pollMailbox ?? true
|
|
@@ -655,12 +649,12 @@ export function* runAgentRuntime(runtime, options = {}) {
|
|
|
655
649
|
}),
|
|
656
650
|
]
|
|
657
651
|
: []),
|
|
658
|
-
yield*
|
|
659
|
-
yield*
|
|
660
|
-
yield*
|
|
652
|
+
yield* spawn(() => doEveryOnWrite(runtime.clock, pacing, runtime.hby.db, () => runtime.delegating.processAllOnce())),
|
|
653
|
+
yield* spawn(() => doEveryOnWrite(runtime.clock, pacing, runtime.hby.db, () => runtime.counselor.processOnce(), () => runtime.counselor.holdsForwards)),
|
|
654
|
+
yield* spawn(() => kelPublisherDo(runtime.kelPublisher, runtime.clock, runtime.publisherPacing)),
|
|
661
655
|
...(runtime.operations && runtime.ipex
|
|
662
656
|
? [
|
|
663
|
-
yield*
|
|
657
|
+
yield* spawn(() => operationOwnersDo({
|
|
664
658
|
operations: runtime.operations,
|
|
665
659
|
rootReplicator: runtime.rootReplicator,
|
|
666
660
|
ipex: runtime.ipex,
|
|
@@ -673,29 +667,8 @@ export function* runAgentRuntime(runtime, options = {}) {
|
|
|
673
667
|
return yield* suspend();
|
|
674
668
|
}
|
|
675
669
|
finally {
|
|
676
|
-
stopHoldWatch();
|
|
677
670
|
for (const task of tasks.reverse()) {
|
|
678
671
|
yield* task.halt();
|
|
679
672
|
}
|
|
680
673
|
}
|
|
681
674
|
}
|
|
682
|
-
/** How long a loop waits for a held signer before trying again, in milliseconds. */
|
|
683
|
-
const SIGNER_RETRY_MS = 1_000;
|
|
684
|
-
/**
|
|
685
|
-
* Run a background loop so that a signer the host released does not end the runtime: the loop's
|
|
686
|
-
* `SignerNotHeldError` is recorded in `runtime.signerConditions`, the loop waits for a signer to be held (or a
|
|
687
|
-
* second) and starts again. Every other failure still ends it.
|
|
688
|
-
*/
|
|
689
|
-
function* surviving(runtime, loop, make) {
|
|
690
|
-
while (true) {
|
|
691
|
-
try {
|
|
692
|
-
return yield* make();
|
|
693
|
-
}
|
|
694
|
-
catch (error) {
|
|
695
|
-
if (!(error instanceof SignerNotHeldError))
|
|
696
|
-
throw error;
|
|
697
|
-
runtime.signerConditions.report(`runtime:${loop}`, error.pub, runtime.clock.now());
|
|
698
|
-
yield* runtime.signerConditions.waitForHold(runtime.clock, SIGNER_RETRY_MS);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Roles } from "../../core/roles.js";
|
|
1
2
|
import { doEvery, PROTOCOL_PACING } from "./doing.js";
|
|
2
3
|
/**
|
|
3
4
|
* Use an explicitly selected or sole local habitat; never guess among hosted identities.
|
|
@@ -13,11 +14,28 @@ function resolveCueHab(runtime, hab) {
|
|
|
13
14
|
const first = habitats.next();
|
|
14
15
|
return first.done || !habitats.next().done ? null : first.value;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Hand an accepted mailbox end role to the KEL publisher and the mailbox poller, so both look at its controller on
|
|
19
|
+
* their next tock rather than at their next sweep. Other roles concern neither.
|
|
20
|
+
*
|
|
21
|
+
* @param runtime Borrowed composed runtime containing the publisher and poller.
|
|
22
|
+
* @param cue The committed end-role fact from `Revery`.
|
|
23
|
+
*/
|
|
24
|
+
export function promptForEndRole(runtime, cue) {
|
|
25
|
+
if (cue.role !== Roles.mailbox)
|
|
26
|
+
return;
|
|
27
|
+
runtime.kelPublisher.prompt(cue.cid);
|
|
28
|
+
runtime.mailboxPoller.prompt(cue.cid);
|
|
29
|
+
}
|
|
16
30
|
/**
|
|
17
31
|
* Route one initial cue batch to its concrete owners before removing source records.
|
|
18
32
|
*
|
|
19
|
-
* Transfer query instructions to the sender
|
|
20
|
-
*
|
|
33
|
+
* Transfer query instructions to the sender (a relaying runtime skips one identical to a request already queued),
|
|
34
|
+
* stream cues to mailbox correlation,
|
|
35
|
+
* accepted mailbox end roles to the KEL publisher and poller, and produced responder
|
|
36
|
+
* messages to Poster. No network delivery runs inline.
|
|
37
|
+
* A responder cue whose signing habitat cannot sign yet moves to the tail and is
|
|
38
|
+
* tried again on a later pass; the cues behind it still go now.
|
|
21
39
|
* Saved key-state facts transfer once to the command's optional query Deck;
|
|
22
40
|
* its noticer never competes with this worker over the runtime source Deck.
|
|
23
41
|
* Admission and source removal run synchronously within this finite batch.
|
|
@@ -33,14 +51,36 @@ export function* processCuesOnce(runtime, { hab, queryCues } = {}) {
|
|
|
33
51
|
const cue = runtime.cues.peekHead();
|
|
34
52
|
if (!cue)
|
|
35
53
|
break;
|
|
54
|
+
if (cue.kin === "kramRefused") {
|
|
55
|
+
// Pulled first: a faulty sink must not wedge the head of the Deck.
|
|
56
|
+
runtime.cues.pull();
|
|
57
|
+
runtime.changes?.push({ kind: "kramRefused", id: cue.said, refusal: cue });
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (cue.kin === "endRoleSaved") {
|
|
61
|
+
runtime.cues.pull();
|
|
62
|
+
promptForEndRole(runtime, cue);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
36
65
|
if (cue.kin === "query") {
|
|
37
|
-
|
|
66
|
+
// A relaying host serves many edges asking about the same subjects; one queued request per query suffices.
|
|
67
|
+
if (runtime.relaying)
|
|
68
|
+
runtime.querying.enqueueCueOnce(cue, interpreter);
|
|
69
|
+
else
|
|
70
|
+
runtime.querying.enqueueCue(cue, interpreter);
|
|
38
71
|
}
|
|
39
72
|
else if (cue.kin === "stream") {
|
|
40
73
|
runtime.mailboxDirector.retainQueryCue(cue);
|
|
41
74
|
}
|
|
42
|
-
else if (interpreter
|
|
43
|
-
|
|
75
|
+
else if (interpreter) {
|
|
76
|
+
const outcome = runtime.respondant.enqueueCue(interpreter, runtime.cues, hab);
|
|
77
|
+
if (outcome === "taken")
|
|
78
|
+
continue;
|
|
79
|
+
if (outcome === "unsignable") {
|
|
80
|
+
// Kept for a later pass, behind the cues that can go now; `count` bounds this pass.
|
|
81
|
+
runtime.cues.append(runtime.cues.pull());
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
44
84
|
}
|
|
45
85
|
runtime.cues.pull();
|
|
46
86
|
if (cue.kin === "keyStateSaved")
|
|
@@ -3,10 +3,13 @@ import { waitOnClock } from "./workflow-contract.js";
|
|
|
3
3
|
export const PROTOCOL_TOCK_MS = 31.25;
|
|
4
4
|
/** Tocks between full sweeps of a loop that has one: 1920 tocks of 31.25 ms is a minute. */
|
|
5
5
|
export const PROTOCOL_SWEEP_TOCKS = 1920;
|
|
6
|
+
/** Tocks between passes of a write-driven loop when the store did not change: 32 tocks of 31.25 ms is one second. */
|
|
7
|
+
export const PROTOCOL_IDLE_TOCKS = 32;
|
|
6
8
|
/** The production pacing of the protocol-facing background loops. */
|
|
7
9
|
export const PROTOCOL_PACING = Object.freeze({
|
|
8
10
|
tockMs: PROTOCOL_TOCK_MS,
|
|
9
11
|
sweepTocks: PROTOCOL_SWEEP_TOCKS,
|
|
12
|
+
idleTocks: PROTOCOL_IDLE_TOCKS,
|
|
10
13
|
});
|
|
11
14
|
/** Run `pass` forever: pass 0, wait `tockMs` on `clock`, pass 1, and so on. A thrown error ends the doer. */
|
|
12
15
|
export function* doEvery(clock, tockMs, pass) {
|
|
@@ -15,3 +18,25 @@ export function* doEvery(clock, tockMs, pass) {
|
|
|
15
18
|
yield* waitOnClock(clock, tockMs);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* A fixed-tock doer for a loop whose work lives in store rows: pass 0, then a pass only on a tock after the
|
|
23
|
+
* store's write counter moved (a pass's own writes included, so it repeats until the store is quiet),
|
|
24
|
+
* after `busy()` says work is held in memory, or every `idleTocks`-th tock for what only time releases
|
|
25
|
+
* (timeouts, retry delays). A tock with nothing new costs a counter read, which touches no store, and no table scan. Rows written by
|
|
26
|
+
* another loop are seen on the next tock; time-driven work waits at most `idleTocks` tocks.
|
|
27
|
+
*/
|
|
28
|
+
export function* doEveryOnWrite(clock, pacing, db, pass, busy = () => false) {
|
|
29
|
+
const idle = pacing.idleTocks ?? PROTOCOL_IDLE_TOCKS;
|
|
30
|
+
let seen = -1;
|
|
31
|
+
for (let tock = 0;; tock++) {
|
|
32
|
+
if (tock % idle === 0 || db.writeActivity !== seen || busy()) {
|
|
33
|
+
try {
|
|
34
|
+
yield* pass(tock);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
seen = db.writeActivity;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
yield* waitOnClock(clock, pacing.tockMs);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -14,28 +14,6 @@ export const OWNER_PACING = Object.freeze({
|
|
|
14
14
|
tockMs: OWNER_TOCK_MS,
|
|
15
15
|
sweepTocks: OWNER_SWEEP_TOCKS,
|
|
16
16
|
});
|
|
17
|
-
/**
|
|
18
|
-
* Failures of the owner loop itself. A failure of one operation (a delivery that throws, an unreadable stored
|
|
19
|
-
* Grant) ends that operation as `failed` and is never recorded here; this records only what escaped an owner
|
|
20
|
-
* pass, which the loop survives so that the other owners keep running. `faults` counts them and `last` keeps
|
|
21
|
-
* the latest. Nothing clears it: a host reads it and decides.
|
|
22
|
-
*/
|
|
23
|
-
export class OwnerHealth {
|
|
24
|
-
constructor() {
|
|
25
|
-
Object.defineProperty(this, "faults", {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
configurable: true,
|
|
28
|
-
writable: true,
|
|
29
|
-
value: 0
|
|
30
|
-
});
|
|
31
|
-
Object.defineProperty(this, "last", {
|
|
32
|
-
enumerable: true,
|
|
33
|
-
configurable: true,
|
|
34
|
-
writable: true,
|
|
35
|
-
value: null
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
17
|
/** Construct the owners over their in-memory tables; the derivation store defaults to the registry database. */
|
|
40
18
|
export function composeOwners(parts, stores = {}) {
|
|
41
19
|
const { hby, acdc, exc, protocol, reactor, postman, receiptor, ipex, clock, registryRoot, mux, counselor } = parts;
|
|
@@ -82,7 +60,6 @@ export function composeOwners(parts, stores = {}) {
|
|
|
82
60
|
retry: parts.retry,
|
|
83
61
|
changes,
|
|
84
62
|
}),
|
|
85
|
-
health: new OwnerHealth(),
|
|
86
63
|
unblinding: new UnblindingOperations({
|
|
87
64
|
hby,
|
|
88
65
|
exc,
|
|
@@ -95,7 +72,9 @@ export function composeOwners(parts, stores = {}) {
|
|
|
95
72
|
changes,
|
|
96
73
|
}),
|
|
97
74
|
};
|
|
98
|
-
const rootReplicator = registryRoot
|
|
75
|
+
const rootReplicator = registryRoot
|
|
76
|
+
? new RootReplicator({ root: registryRoot, postman, clock, changes, changed: parts.groupChanges })
|
|
77
|
+
: null;
|
|
99
78
|
return { operations, rootReplicator };
|
|
100
79
|
}
|
|
101
80
|
/**
|
|
@@ -106,47 +85,38 @@ export function composeOwners(parts, stores = {}) {
|
|
|
106
85
|
* Idle cost, per tock: four constant-time table checks, one in-memory walk of the Unblind owners for an owed
|
|
107
86
|
* reply, one drain of each DH owner's cue deck, and the replicator's emptiness checks. The replicator's
|
|
108
87
|
* rotation check (the establishment SAID of each local group, one keyed read per local identifier) runs on
|
|
109
|
-
* tock 0 and every `pacing.sweepTocks`. No owner reads a protocol store
|
|
110
|
-
* pending exchange escrow for resumable Grants
|
|
88
|
+
* tock 0 and every `pacing.sweepTocks`. No owner reads a protocol store on an ordinary tock. The issuance owner
|
|
89
|
+
* scans the pending exchange escrow on its first pass and then every `ISSUANCE_SWEEP_MS`, for resumable Grants and
|
|
90
|
+
* for group Grants whose custodian's final proof a member follows without signing; nothing else walks it per tock.
|
|
111
91
|
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
92
|
+
* Nothing is caught here. Every remote, network or validation outcome an owner meets is already a typed result
|
|
93
|
+
* below this loop: a failed delivery is retried by its operation, and an operation that cannot go on ends `failed`
|
|
94
|
+
* or `expired` alone. What escapes a pass is a real fault (a store that cannot be read or written, corrupt or
|
|
95
|
+
* missing durable state such as a `MissingDurableStateError`, a `SignerNotHeldError` past a `canSign`
|
|
96
|
+
* gate), and it ends the loop and with it `runAgentRuntime`. Halting the loop is not a fault: Effection halts a
|
|
97
|
+
* pass by returning from it, so no error is thrown. The owners run one after another, so a delivery that does not
|
|
98
|
+
* return holds the others up until it fails or its Grant deadline passes; operations already bound each delivery by
|
|
99
|
+
* that deadline.
|
|
115
100
|
*/
|
|
116
101
|
export function* operationOwnersDo(owners, pacing = OWNER_PACING) {
|
|
117
|
-
const { operations, rootReplicator, ipex, clock } = owners
|
|
118
|
-
const guarded = function* (owner, pass) {
|
|
119
|
-
try {
|
|
120
|
-
yield* pass();
|
|
121
|
-
}
|
|
122
|
-
catch (error) {
|
|
123
|
-
health.faults++;
|
|
124
|
-
health.last = {
|
|
125
|
-
owner,
|
|
126
|
-
error: error instanceof Error ? error.message : String(error),
|
|
127
|
-
at: new Date(clock.now()).toISOString(),
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
};
|
|
102
|
+
const { operations, rootReplicator, ipex, clock } = owners;
|
|
131
103
|
return yield* doEvery(clock, pacing.tockMs, function* (tock) {
|
|
132
104
|
if (operations.issuance.active())
|
|
133
|
-
yield*
|
|
105
|
+
yield* operations.issuance.processOnce();
|
|
134
106
|
if (operations.groupIpex.active())
|
|
135
|
-
yield*
|
|
107
|
+
yield* operations.groupIpex.processOnce();
|
|
136
108
|
if (operations.presentation.active())
|
|
137
|
-
yield*
|
|
109
|
+
yield* operations.presentation.processOnce();
|
|
138
110
|
if (operations.unblinding.active())
|
|
139
|
-
yield*
|
|
111
|
+
yield* operations.unblinding.processOnce();
|
|
140
112
|
if (rootReplicator) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
yield* rootReplicator.processDue();
|
|
149
|
-
});
|
|
113
|
+
for (const dh of ipex.dhkeOwners()) {
|
|
114
|
+
while (dh.replicated.length)
|
|
115
|
+
rootReplicator.replicate(dh.replicated.pull());
|
|
116
|
+
}
|
|
117
|
+
if (tock % pacing.sweepTocks === 0)
|
|
118
|
+
rootReplicator.sweep();
|
|
119
|
+
yield* rootReplicator.processDue();
|
|
150
120
|
}
|
|
151
121
|
});
|
|
152
122
|
}
|
|
@@ -24,22 +24,25 @@ export class MemoryChangeSink {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
push(change) {
|
|
27
|
-
this.changes.push({ kind: change.kind, id: change.id });
|
|
27
|
+
this.changes.push(change.kind === "kramRefused" ? change : { kind: change.kind, id: change.id });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Back a sink with the host's transient `Signaler`. Publishing needs no polling:
|
|
32
32
|
* `push` is a synchronous append that collapses repeats of one workflow into a
|
|
33
|
-
* single signal (collapse key `kind:id`).
|
|
33
|
+
* single signal (collapse key `kind:id`). A {@link KramRefusedChange} adds its refusal fields to the signal
|
|
34
|
+
* attributes, so a resent message collapses by SAID. Delivery is pull-based, though: the
|
|
34
35
|
* Signaler has no subscriber hook, so the consumer must read `signaler.list()`.
|
|
35
36
|
* A closed or failing Signaler drops the change instead of throwing: a hint must
|
|
36
37
|
* never break the workflow that published it.
|
|
37
38
|
*/
|
|
38
39
|
export function signalerChangeSink(signaler) {
|
|
39
40
|
return {
|
|
40
|
-
push: (
|
|
41
|
+
push: (change) => {
|
|
42
|
+
const { kind, id } = change;
|
|
41
43
|
try {
|
|
42
|
-
|
|
44
|
+
const attrs = change.kind === "kramRefused" ? { id, ...change.refusal } : { id };
|
|
45
|
+
signaler.push(attrs, `/workflow/${kind}`, { ckey: `${kind}:${id}` });
|
|
43
46
|
}
|
|
44
47
|
catch {
|
|
45
48
|
// Dropped on purpose; consumers re-read status and tolerate a missed hint.
|
|
@@ -4,6 +4,25 @@ import { ValidationError } from "../../core/errors.js";
|
|
|
4
4
|
import { abortable } from "../runtime/abortable.js";
|
|
5
5
|
import { collectBytes } from "./byte-source.js";
|
|
6
6
|
import { TransportError } from "./transport-error.js";
|
|
7
|
+
/**
|
|
8
|
+
* Whether {@link FetchHttpClient.open} can request `url` at all: an absolute HTTP(S) URL without embedded
|
|
9
|
+
* credentials. Anything else is refused by construction, before any I/O, so a caller holding a URL from a remote
|
|
10
|
+
* party can refuse it at intake instead of queuing work that can never succeed.
|
|
11
|
+
*
|
|
12
|
+
* @param url Candidate request URL.
|
|
13
|
+
* @returns False for an unparseable URL, a non-HTTP(S) scheme, or a URL carrying a user name or password.
|
|
14
|
+
*/
|
|
15
|
+
export function isRequestableHttpUrl(url) {
|
|
16
|
+
let endpoint;
|
|
17
|
+
try {
|
|
18
|
+
endpoint = new URL(url);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return (endpoint.protocol === "http:" || endpoint.protocol === "https:") && !endpoint.username
|
|
24
|
+
&& !endpoint.password;
|
|
25
|
+
}
|
|
7
26
|
/**
|
|
8
27
|
* Native requests and signals that a pending `fetch` still needs. WebKit links an in-flight fetch to
|
|
9
28
|
* its abort signal only weakly: once the `Request`, or an `AbortSignal.any` composite, is garbage
|
|
@@ -78,8 +97,7 @@ export class FetchHttpClient {
|
|
|
78
97
|
: new TransportError(`${message} for ${url}`, { cause });
|
|
79
98
|
try {
|
|
80
99
|
signal.throwIfAborted();
|
|
81
|
-
|
|
82
|
-
if (!["http:", "https:"].includes(endpoint.protocol) || endpoint.username || endpoint.password) {
|
|
100
|
+
if (!isRequestableHttpUrl(url)) {
|
|
83
101
|
throw new ValidationError("HTTP output requires an HTTP(S) URL without credentials");
|
|
84
102
|
}
|
|
85
103
|
// Construction errors are caller errors, before native network classification.
|
|
@@ -53,7 +53,8 @@ export function* processMessages(source, protocol, kvy, options = {}) {
|
|
|
53
53
|
signal.throwIfAborted();
|
|
54
54
|
if (result.done)
|
|
55
55
|
return;
|
|
56
|
-
|
|
56
|
+
// Only the intake choices: nothing a caller adds to its options can mark live input as retained history.
|
|
57
|
+
yield* protocol.dispatch(result.value, { local: options.local, mailboxAid: options.mailboxAid, escrows: options.escrows }, kvy);
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
finally {
|