@cotal-ai/core 0.12.0 → 0.13.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/dist/acls.d.ts +31 -7
- package/dist/acls.d.ts.map +1 -1
- package/dist/acls.js +105 -17
- package/dist/acls.js.map +1 -1
- package/dist/agent-file.js +1 -1
- package/dist/agent-file.js.map +1 -1
- package/dist/auth-provider.d.ts +8 -0
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/auth-provider.js.map +1 -1
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +6 -4
- package/dist/backup.js.map +1 -1
- package/dist/broker-floor.d.ts +34 -0
- package/dist/broker-floor.d.ts.map +1 -0
- package/dist/broker-floor.js +39 -0
- package/dist/broker-floor.js.map +1 -0
- package/dist/canonical.d.ts +24 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +159 -0
- package/dist/canonical.js.map +1 -0
- package/dist/connector.d.ts +4 -0
- package/dist/connector.d.ts.map +1 -1
- package/dist/endpoint-action.d.ts +424 -0
- package/dist/endpoint-action.d.ts.map +1 -0
- package/dist/endpoint-action.js +910 -0
- package/dist/endpoint-action.js.map +1 -0
- package/dist/endpoint-binding.d.ts +344 -0
- package/dist/endpoint-binding.d.ts.map +1 -0
- package/dist/endpoint-binding.js +753 -0
- package/dist/endpoint-binding.js.map +1 -0
- package/dist/endpoint-checkpoint.d.ts +292 -0
- package/dist/endpoint-checkpoint.d.ts.map +1 -0
- package/dist/endpoint-checkpoint.js +818 -0
- package/dist/endpoint-checkpoint.js.map +1 -0
- package/dist/endpoint-cluster.d.ts +95 -0
- package/dist/endpoint-cluster.d.ts.map +1 -0
- package/dist/endpoint-cluster.js +194 -0
- package/dist/endpoint-cluster.js.map +1 -0
- package/dist/endpoint-contract-store.d.ts +90 -0
- package/dist/endpoint-contract-store.d.ts.map +1 -0
- package/dist/endpoint-contract-store.js +348 -0
- package/dist/endpoint-contract-store.js.map +1 -0
- package/dist/endpoint-envelope.d.ts +165 -0
- package/dist/endpoint-envelope.d.ts.map +1 -0
- package/dist/endpoint-envelope.js +346 -0
- package/dist/endpoint-envelope.js.map +1 -0
- package/dist/endpoint-grants.d.ts +123 -0
- package/dist/endpoint-grants.d.ts.map +1 -0
- package/dist/endpoint-grants.js +215 -0
- package/dist/endpoint-grants.js.map +1 -0
- package/dist/endpoint-guard.d.ts +222 -0
- package/dist/endpoint-guard.d.ts.map +1 -0
- package/dist/endpoint-guard.js +468 -0
- package/dist/endpoint-guard.js.map +1 -0
- package/dist/endpoint-handle.d.ts +176 -0
- package/dist/endpoint-handle.d.ts.map +1 -0
- package/dist/endpoint-handle.js +608 -0
- package/dist/endpoint-handle.js.map +1 -0
- package/dist/endpoint-journal.d.ts +225 -0
- package/dist/endpoint-journal.d.ts.map +1 -0
- package/dist/endpoint-journal.js +431 -0
- package/dist/endpoint-journal.js.map +1 -0
- package/dist/endpoint-receipt.d.ts +225 -0
- package/dist/endpoint-receipt.d.ts.map +1 -0
- package/dist/endpoint-receipt.js +417 -0
- package/dist/endpoint-receipt.js.map +1 -0
- package/dist/endpoint-records.d.ts +243 -0
- package/dist/endpoint-records.d.ts.map +1 -0
- package/dist/endpoint-records.js +591 -0
- package/dist/endpoint-records.js.map +1 -0
- package/dist/endpoint-serve.d.ts +176 -0
- package/dist/endpoint-serve.d.ts.map +1 -0
- package/dist/endpoint-serve.js +446 -0
- package/dist/endpoint-serve.js.map +1 -0
- package/dist/endpoint-service.d.ts +518 -0
- package/dist/endpoint-service.d.ts.map +1 -0
- package/dist/endpoint-service.js +973 -0
- package/dist/endpoint-service.js.map +1 -0
- package/dist/endpoint-session.d.ts +398 -0
- package/dist/endpoint-session.d.ts.map +1 -0
- package/dist/endpoint-session.js +834 -0
- package/dist/endpoint-session.js.map +1 -0
- package/dist/endpoint-signing.d.ts +105 -0
- package/dist/endpoint-signing.d.ts.map +1 -0
- package/dist/endpoint-signing.js +190 -0
- package/dist/endpoint-signing.js.map +1 -0
- package/dist/endpoint-subjects.d.ts +222 -0
- package/dist/endpoint-subjects.d.ts.map +1 -0
- package/dist/endpoint-subjects.js +381 -0
- package/dist/endpoint-subjects.js.map +1 -0
- package/dist/endpoint-supervisor.d.ts +19 -0
- package/dist/endpoint-supervisor.d.ts.map +1 -0
- package/dist/endpoint-supervisor.js +12 -0
- package/dist/endpoint-supervisor.js.map +1 -0
- package/dist/endpoint-traits.d.ts +225 -0
- package/dist/endpoint-traits.d.ts.map +1 -0
- package/dist/endpoint-traits.js +469 -0
- package/dist/endpoint-traits.js.map +1 -0
- package/dist/endpoint-verbs.d.ts +277 -0
- package/dist/endpoint-verbs.d.ts.map +1 -0
- package/dist/endpoint-verbs.js +576 -0
- package/dist/endpoint-verbs.js.map +1 -0
- package/dist/endpoint-virtual.d.ts +308 -0
- package/dist/endpoint-virtual.d.ts.map +1 -0
- package/dist/endpoint-virtual.js +440 -0
- package/dist/endpoint-virtual.js.map +1 -0
- package/dist/endpoint-work.d.ts +304 -0
- package/dist/endpoint-work.d.ts.map +1 -0
- package/dist/endpoint-work.js +728 -0
- package/dist/endpoint-work.js.map +1 -0
- package/dist/endpoint.d.ts +66 -22
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +289 -89
- package/dist/endpoint.js.map +1 -1
- package/dist/evict.d.ts +95 -32
- package/dist/evict.d.ts.map +1 -1
- package/dist/evict.js +193 -3
- package/dist/evict.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/lease.d.ts +4 -0
- package/dist/lease.d.ts.map +1 -1
- package/dist/lease.js.map +1 -1
- package/dist/members.d.ts +4 -4
- package/dist/members.d.ts.map +1 -1
- package/dist/members.js +12 -12
- package/dist/members.js.map +1 -1
- package/dist/provision.d.ts +70 -18
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +194 -33
- package/dist/provision.js.map +1 -1
- package/dist/safe-pattern.d.ts +33 -0
- package/dist/safe-pattern.d.ts.map +1 -0
- package/dist/safe-pattern.js +486 -0
- package/dist/safe-pattern.js.map +1 -0
- package/dist/schema-profile.d.ts +93 -0
- package/dist/schema-profile.d.ts.map +1 -0
- package/dist/schema-profile.js +284 -0
- package/dist/schema-profile.js.map +1 -0
- package/dist/streams.d.ts +13 -8
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +35 -18
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +100 -40
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +136 -60
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { NatsConnection } from "@nats-io/transport-node";
|
|
2
|
+
import { type EpCaller, type EpRoute } from "./endpoint-subjects.js";
|
|
3
|
+
import { EpEnvelopeError, type EndpointReply, type EndpointEvent, type EpCorrelation } from "./endpoint-envelope.js";
|
|
4
|
+
import type { KV } from "@nats-io/kv";
|
|
5
|
+
import type { JetStreamManager } from "@nats-io/jetstream";
|
|
6
|
+
import type { CompiledContract } from "./schema-profile.js";
|
|
7
|
+
import { type FrozenInstance } from "./endpoint-service.js";
|
|
8
|
+
/** A verb's target: one input shape that builds BOTH halves of the §13.2/§13.3 targeted form —
|
|
9
|
+
* the subject's authorization-mode token block and the body target block — so they can never
|
|
10
|
+
* disagree. `self` carries no body target (the caller triple IS the target, §13.3). */
|
|
11
|
+
export type EpVerbTarget = {
|
|
12
|
+
mode: "self";
|
|
13
|
+
} | {
|
|
14
|
+
mode: "owner" | "any" | "child" | "ledger" | "handle";
|
|
15
|
+
owner: string;
|
|
16
|
+
actor: string;
|
|
17
|
+
lifecycleUid: string;
|
|
18
|
+
mappingRevision?: number;
|
|
19
|
+
};
|
|
20
|
+
/** What every verb needs to address one command: the compiled §13.7 contracts (digests derive
|
|
21
|
+
* from `closureDigest`, exactly like the serve table), the caller triple the credential pins,
|
|
22
|
+
* and an optional display name for the advisory `from.name`. */
|
|
23
|
+
export interface EpVerbOp {
|
|
24
|
+
endpoint: string;
|
|
25
|
+
command: string;
|
|
26
|
+
contract: {
|
|
27
|
+
input: CompiledContract;
|
|
28
|
+
output: CompiledContract;
|
|
29
|
+
};
|
|
30
|
+
caller: EpCaller;
|
|
31
|
+
args?: Record<string, unknown>;
|
|
32
|
+
target?: EpVerbTarget;
|
|
33
|
+
correlation?: EpCorrelation;
|
|
34
|
+
/** Opaque signed authorization-context slot (§13.3); carried as-is. */
|
|
35
|
+
auth?: string;
|
|
36
|
+
goalId?: string;
|
|
37
|
+
/** Advisory display name for `from.name`; `from.id` is DERIVED from the caller triple, so it
|
|
38
|
+
* always equals the broker-authenticated sender principal (§13.3). */
|
|
39
|
+
name?: string;
|
|
40
|
+
}
|
|
41
|
+
/** One attributed reply: the structural attribution comes from the reply SUBJECT (§13.2), never
|
|
42
|
+
* from the body. */
|
|
43
|
+
export interface EpAttributedReply {
|
|
44
|
+
reply: EndpointReply;
|
|
45
|
+
responder: {
|
|
46
|
+
endpoint: string;
|
|
47
|
+
instanceId: string;
|
|
48
|
+
epoch: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Call one command and await its reply within `deadlineMs`: on the `one` (queue-group anycast) or
|
|
53
|
+
* `inst` (stable incarnation) rail with `replyExpected: true`, subscribe the caller's own
|
|
54
|
+
* nonce-scoped reply subject BEFORE publishing, and resolve the first attributed reply — BOUND to
|
|
55
|
+
* the invoked identity (§13.2:1187-1189: "callers reject" stale-process replies), on BOTH rails:
|
|
56
|
+
* - `inst` pins the addressed `(instanceId, epoch)` incarnation up front; a stale-epoch reply is
|
|
57
|
+
* `expired` and a wrong-instance reply `internal`.
|
|
58
|
+
* - `one` cannot pin an instance up front (the queue picks the responder), so the caller MUST supply
|
|
59
|
+
* `currentEpoch(instanceId)`: after the reply lands, the answering incarnation's epoch is checked
|
|
60
|
+
* against its current registry epoch, and a superseded-but-still-connected queue member's reply is
|
|
61
|
+
* `expired`. The queue winner is NOT implicitly current — that is a check, not an assumption.
|
|
62
|
+
*
|
|
63
|
+
* Application-level failure is NOT a throw: the resolved `reply` carries `ok: false` with the
|
|
64
|
+
* responder's structured error (§13.3). This boundary throws only for its own refusals: invalid args
|
|
65
|
+
* `bad-request`; an unparseable/mis-echoed/mis-attributed reply `internal` (a raw decode error never
|
|
66
|
+
* escapes); a throwing `currentEpoch` hook `internal` and a garbled (non-integer/negative) currency
|
|
67
|
+
* value `failed-precondition` (the read's own failure, never mislabeled staleness); a stale reply `expired`;
|
|
68
|
+
* NO responder `unavailable` (SPEC 13.5:1484 — the broker's no-responders 503 lands on a reply-to that
|
|
69
|
+
* sits on THIS caller's own rail, so a manual, fully-disposed probe distinguishes it from a slow
|
|
70
|
+
* responder without leaving a lingering request); a failed reply subscription `unavailable`; the
|
|
71
|
+
* elapsed budget `deadline-exceeded`. Every subscription and timer is released in the `finally`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function epCall(nc: NatsConnection, space: string, route: {
|
|
74
|
+
mode: "one";
|
|
75
|
+
} | {
|
|
76
|
+
mode: "inst";
|
|
77
|
+
instanceId: string;
|
|
78
|
+
epoch: number;
|
|
79
|
+
}, op: EpVerbOp, opts: {
|
|
80
|
+
deadlineMs: number;
|
|
81
|
+
currentEpoch?: (instanceId: string) => Promise<number> | number;
|
|
82
|
+
}): Promise<EpAttributedReply>;
|
|
83
|
+
/**
|
|
84
|
+
* Cast one command: the same request form with `replyExpected: false` — the responder never
|
|
85
|
+
* replies, even on failure (§13.5 at-most-once), so this resolves once the request is flushed to
|
|
86
|
+
* the broker. `deadlineMs` is optional and advisory for `one`/`inst` (the envelope requires it only
|
|
87
|
+
* for calls and journal submissions, §13.3), but MANDATORY for `all`: §13.2's
|
|
88
|
+
* `checkRequestSubjectAgreement` refuses an all-rail request without a deadline regardless of
|
|
89
|
+
* `replyExpected`, and a cast has no reply on which that refusal could surface — so an all-cast
|
|
90
|
+
* without a deadline would be silently dropped by every responder. Fail loud at the caller instead.
|
|
91
|
+
*/
|
|
92
|
+
export declare function epCast(nc: NatsConnection, space: string, route: EpRoute, op: EpVerbOp, opts?: {
|
|
93
|
+
deadlineMs?: number;
|
|
94
|
+
}): Promise<void>;
|
|
95
|
+
/** One attributed event: identity and epoch come from the SUBJECT (§13.2: forge-locked tokens;
|
|
96
|
+
* a stale-epoch event is attributably stale — surfaced, never hidden). */
|
|
97
|
+
export interface EpAttributedEvent {
|
|
98
|
+
endpoint: string;
|
|
99
|
+
instanceId: string;
|
|
100
|
+
epoch: number;
|
|
101
|
+
topic: string[];
|
|
102
|
+
event: EndpointEvent;
|
|
103
|
+
}
|
|
104
|
+
export interface EpWatchHandle {
|
|
105
|
+
stop(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Watch a granted `epe` subtree LIVE (the event half of §13.5 `watch`; §13.9: the read grant is the
|
|
109
|
+
* caller's own `sub.allow` row, e.g. the per-goal progress subtree — delivery lands only on this
|
|
110
|
+
* caller's own subscription). Every event is validated at this consuming boundary: an unparseable
|
|
111
|
+
* subject or body is reported through `onError` (§13.3: fail loud, never a silent drop) and never
|
|
112
|
+
* reaches `onEvent`. This is the LIVE tap ONLY — durable catch-up / filtered replay is the §13.9
|
|
113
|
+
* mediated read (see the module note above), and record watch is `watchRecord` (§13.4).
|
|
114
|
+
*/
|
|
115
|
+
export declare function epWatchEvents(nc: NatsConnection, space: string, filter: string, handlers: {
|
|
116
|
+
onEvent: (ev: EpAttributedEvent) => void;
|
|
117
|
+
onError: (err: EpEnvelopeError) => void;
|
|
118
|
+
}): EpWatchHandle;
|
|
119
|
+
/** The scatter gathers against a request-scoped FROZEN expected set (§13.5): the live instances of
|
|
120
|
+
* the class, each `(instanceId, registrationRevision, epoch)` at send time. This is exactly
|
|
121
|
+
* {@link import("./endpoint-service.js").freezeExpectedSet}'s output — pass it through so the freeze
|
|
122
|
+
* identity (all THREE coordinates, not just instance+epoch) is what the gather classifies against. */
|
|
123
|
+
export type EpScatterSlot = FrozenInstance;
|
|
124
|
+
/** Why a frozen slot's reply is churn (§13.5): `epoch` — it replied at a DIFFERENT process epoch than
|
|
125
|
+
* frozen (a takeover restarted it); `registration` — its `svc….spec` registrationRevision advanced
|
|
126
|
+
* past the frozen value (a re-registration re-declared its surface). Both mean the reply may be from
|
|
127
|
+
* an incarnation that never saw this request, so it does NOT count toward completion. Registration
|
|
128
|
+
* churn is NOT visible on the reply rail (the reply subject carries epoch, not registrationRevision,
|
|
129
|
+
* and a re-registration does not advance the epoch), so it is observed only when a registration
|
|
130
|
+
* reconcile runs (see {@link epScatter} `reconcileRegistration`). */
|
|
131
|
+
export type EpChurnReason = "epoch" | "registration";
|
|
132
|
+
/** The §13.5 scatter outcome. `complete` means EXPECTED-SLOT COVERAGE — every frozen slot produced
|
|
133
|
+
* exactly one counted valid reply at its frozen `(epoch, registrationRevision)`, verified against the
|
|
134
|
+
* registration reconcile — NOT that the gather was anomaly-free. `missing` and `invalid` force
|
|
135
|
+
* `complete` false; a `registration`-churn drops a slot's counted reply (so that slot becomes
|
|
136
|
+
* uncovered → false). But `duplicate`, `unexpected`, and an `epoch`-churn reply do NOT by themselves
|
|
137
|
+
* force false: a slot that answered validly at its frozen epoch stays counted even if a stray
|
|
138
|
+
* different-epoch reply from another incarnation also arrived. First valid reply per frozen
|
|
139
|
+
* `(instanceId, epoch)` wins. */
|
|
140
|
+
export interface EpScatterResult {
|
|
141
|
+
complete: boolean;
|
|
142
|
+
/** instanceId → the first VALID attributed reply from that frozen slot at its frozen epoch. */
|
|
143
|
+
replies: Map<string, EpAttributedReply>;
|
|
144
|
+
/** Frozen slots with NO reply of any kind by the DEADLINE (the classification point). A slot that
|
|
145
|
+
* produced only churn/duplicate/invalid is reported there. A slot that produced ONLY a `late` reply
|
|
146
|
+
* is BOTH `missing` (no on-time reply) and `late` (observational): classification linearizes at the
|
|
147
|
+
* deadline, and the drain enriches, never moves it. */
|
|
148
|
+
missing: string[];
|
|
149
|
+
/** Replies from a DIFFERENT endpoint, or from an instance OUTSIDE the frozen set. Never count. */
|
|
150
|
+
unexpected: {
|
|
151
|
+
instanceId: string;
|
|
152
|
+
epoch: number;
|
|
153
|
+
}[];
|
|
154
|
+
/** Frozen slots whose reply came from a superseded incarnation — a DIFFERENT epoch, or (via the
|
|
155
|
+
* mandatory `reconcileRegistration`) an advanced registrationRevision. Does NOT count. */
|
|
156
|
+
churn: {
|
|
157
|
+
instanceId: string;
|
|
158
|
+
epoch: number;
|
|
159
|
+
reason: EpChurnReason;
|
|
160
|
+
}[];
|
|
161
|
+
/** Second-and-later replies from a frozen `(instanceId, epoch)` after its first classified one:
|
|
162
|
+
* REPORTED, never silently dropped (§13.5); first reply wins, whatever it was classified. */
|
|
163
|
+
duplicate: {
|
|
164
|
+
instanceId: string;
|
|
165
|
+
epoch: number;
|
|
166
|
+
}[];
|
|
167
|
+
/** Valid frozen-slot replies observed AFTER the deadline, during the optional bounded `lateDrainMs`
|
|
168
|
+
* window: too late to count, reported not dropped. Empty unless `lateDrainMs` set. */
|
|
169
|
+
late: {
|
|
170
|
+
instanceId: string;
|
|
171
|
+
epoch: number;
|
|
172
|
+
}[];
|
|
173
|
+
/** Frozen-slot replies that failed this consuming boundary (unparseable body, id mismatch, invalid
|
|
174
|
+
* success payload, mis-attributed). NON-TERMINAL: an invalid frame does NOT consume the slot's one
|
|
175
|
+
* terminal reply — the slot stays open to a later valid reply, bounded by the deadline. But any
|
|
176
|
+
* recorded invalid keeps `complete` false (§13.3 fail-loud: an observed anomaly is not clean).
|
|
177
|
+
* Not a §13.5-enumerated bucket; kept because fail-loud forbids counting an invalid reply as valid. */
|
|
178
|
+
invalid: {
|
|
179
|
+
instanceId: string;
|
|
180
|
+
epoch: number;
|
|
181
|
+
message: string;
|
|
182
|
+
}[];
|
|
183
|
+
}
|
|
184
|
+
/** The reconcile hook's per-instance verdict. An instance STILL in the registry carries its current
|
|
185
|
+
* `registrationRevision`; one the mediated §13.9 read observed as GONE is `{ registered: false }`.
|
|
186
|
+
* This is an EXPLICIT value, distinct from an absent Map entry — an absent entry stays an incomplete
|
|
187
|
+
* read (`failed-precondition`), so a buggy/partial hook can never masquerade as "everyone deregistered".
|
|
188
|
+
* A mid-scatter deregistration is NOT registration-churn (a re-registration advances the revision and
|
|
189
|
+
* invalidates the reply; a plain departure does not): a valid reply the instance already gave still
|
|
190
|
+
* counts, and if it never replied its slot falls to `missing`. */
|
|
191
|
+
export type EpRegistrationState = {
|
|
192
|
+
registered: true;
|
|
193
|
+
registrationRevision: number;
|
|
194
|
+
} | {
|
|
195
|
+
registered: false;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Scatter one command to a FROZEN expected set (§13.5): publish once on the `all` rail, gather
|
|
199
|
+
* attributed replies on the caller's nonce-scoped rail, and CLASSIFY against the freeze. An empty set
|
|
200
|
+
* refuses (`failed-precondition`, never an empty success), and the observation channel is fail-loud:
|
|
201
|
+
* a failed reply subscription is `unavailable`, never fabricated member silence.
|
|
202
|
+
*
|
|
203
|
+
* CLASSIFICATION LINEARIZES AT THE GATHER DEADLINE. The classification point T is `min(all frozen
|
|
204
|
+
* slots answered-valid, deadline)`; `missing` is fixed at T (from the `respondedAtDeadline` snapshot).
|
|
205
|
+
* The `lateDrainMs` window runs AFTER T on an ABSOLUTE clock — the rail is closed exactly `lateDrainMs`
|
|
206
|
+
* after T regardless of how long the reconcile takes, so late classification cannot leak past the
|
|
207
|
+
* requested horizon. It is OBSERVATIONAL only: it may add to `late`/`duplicate`, never move
|
|
208
|
+
* `missing`/`churn`/`complete`. With `lateDrainMs` omitted the rail closes at T (no `late`).
|
|
209
|
+
*
|
|
210
|
+
* WHOLE-OPERATION BUDGET. The op is bounded: the gather to T comes FIRST, then a post-T phase in which
|
|
211
|
+
* the reconcile and the drain run CONCURRENTLY (the drain is armed at T, before the reconcile await).
|
|
212
|
+
* So worst-case wall-clock ≈ `deadlineMs` (gather) + `max(reconcileDeadlineMs, lateDrainMs)` (post-T),
|
|
213
|
+
* NOT their sum. The reconcile is a bounded read taken SHORTLY AFTER T (not a zero-width at-T snapshot):
|
|
214
|
+
* a true instant-of-T revision would need a watch/frontier, so a re-registration strictly concurrent
|
|
215
|
+
* with the bounded read is an inherent, documented window (recorded for the §13.5 SPEC reconciliation).
|
|
216
|
+
*
|
|
217
|
+
* Two §13.5 signals are not on the reply rail, so the caller supplies them as HOOKS (keeping the verb
|
|
218
|
+
* free of storage coupling; the §13.9 read grant stays with the caller, and a caller-read revision is
|
|
219
|
+
* more trustworthy than a responder-stamped one):
|
|
220
|
+
* - `reconcileRegistration` (REQUIRED): reads EVERY frozen slot's CURRENT state after the classification
|
|
221
|
+
* point, returning a per-instance `EpRegistrationState` verdict. A slot still registered at a revision
|
|
222
|
+
* ADVANCED past its frozen one is `churn` ("registration") and uncounted (a re-registration advances
|
|
223
|
+
* registrationRevision WITHOUT advancing the epoch, so the reply rail cannot see it). A slot the read
|
|
224
|
+
* observed as GONE (`{ registered: false }`) is an explicit mid-scatter deregistration: NOT churn, and
|
|
225
|
+
* a valid reply it already gave still counts (a plain departure does not invalidate the reply the way
|
|
226
|
+
* a re-registration would). Its result is COMPLETENESS-validated: a frozen id ABSENT from the returned
|
|
227
|
+
* Map is an incomplete read (`failed-precondition`) — distinct from an explicit `{ registered: false }`
|
|
228
|
+
* verdict — a non-integer/non-positive revision is a garbled read (`failed-precondition`), and a
|
|
229
|
+
* revision BELOW the frozen one is a non-monotonic/buggy read (`failed-precondition`); otherwise a
|
|
230
|
+
* partial hook would silently preserve the old full-triple over-claim. It is BOUNDED by
|
|
231
|
+
* `reconcileDeadlineMs`: a never-settling read is `unavailable`, never a hung scatter (SPEC 13.5:
|
|
232
|
+
* deadline mandatory); an unreadable registry is `failed-precondition`. Authoritative `complete`
|
|
233
|
+
* requires it.
|
|
234
|
+
* - `reconcileDeadlineMs` (optional, default `deadlineMs`): the explicit bound on that post-T read,
|
|
235
|
+
* named so the single `deadlineMs` is not silently spent twice.
|
|
236
|
+
* - `lateDrainMs` (optional): the absolute post-T horizon for `late` classification. Omitted → none.
|
|
237
|
+
*/
|
|
238
|
+
export declare function epScatter(nc: NatsConnection, space: string, op: EpVerbOp, opts: {
|
|
239
|
+
deadlineMs: number;
|
|
240
|
+
expected: EpScatterSlot[];
|
|
241
|
+
reconcileRegistration: () => Promise<Map<string, EpRegistrationState>>;
|
|
242
|
+
reconcileDeadlineMs?: number;
|
|
243
|
+
lateDrainMs?: number;
|
|
244
|
+
}): Promise<EpScatterResult>;
|
|
245
|
+
/**
|
|
246
|
+
* Scatter one command to the LIVE class (§13.5), registry-wired end to end: freeze the expected
|
|
247
|
+
* set from the service registry, publish once on the `all` rail, and reconcile registration
|
|
248
|
+
* currency post-T — the full §13.5 sequence behind one call. `jsm` drives the LEADER-served
|
|
249
|
+
* coordinate reads (the freeze's per-slot spec/status and the reconcile), `kv` the bounded-lag
|
|
250
|
+
* instance enumeration; every freeze/reconcile refusal (`failed-precondition` on an empty or
|
|
251
|
+
* unreadable registry, `internal` on malformed mediated-writer state) and every gather
|
|
252
|
+
* classification passes through unchanged. The hooks stay public: a caller composing its own
|
|
253
|
+
* freeze (a pinned set, a test harness) uses {@link epScatter} directly.
|
|
254
|
+
*/
|
|
255
|
+
export declare function epScatterService(nc: NatsConnection, jsm: JetStreamManager, kv: KV, space: string, op: EpVerbOp, opts: {
|
|
256
|
+
deadlineMs: number;
|
|
257
|
+
reconcileDeadlineMs?: number;
|
|
258
|
+
lateDrainMs?: number;
|
|
259
|
+
}): Promise<EpScatterResult>;
|
|
260
|
+
/**
|
|
261
|
+
* Call one command with the registry-wired currency check (§13.2): on the `one` rail the queue
|
|
262
|
+
* winner's epoch is verified against a LEADER-served read of its `svc….status` through
|
|
263
|
+
* {@link serviceEpochReader}; the `inst` rail pins its incarnation up front and needs no read, so
|
|
264
|
+
* the hook is not wired there. Every {@link epCall} refusal passes through unchanged (a superseded
|
|
265
|
+
* winner is `expired`; an unregistered or never-converged responder is the read's own
|
|
266
|
+
* `failed-precondition`, never mislabeled staleness).
|
|
267
|
+
*/
|
|
268
|
+
export declare function epCallService(nc: NatsConnection, jsm: JetStreamManager, space: string, route: {
|
|
269
|
+
mode: "one";
|
|
270
|
+
} | {
|
|
271
|
+
mode: "inst";
|
|
272
|
+
instanceId: string;
|
|
273
|
+
epoch: number;
|
|
274
|
+
}, op: EpVerbOp, opts: {
|
|
275
|
+
deadlineMs: number;
|
|
276
|
+
}): Promise<EpAttributedReply>;
|
|
277
|
+
//# sourceMappingURL=endpoint-verbs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-verbs.d.ts","sourceRoot":"","sources":["../src/endpoint-verbs.ts"],"names":[],"mappings":"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"}
|