@cotal-ai/core 0.12.0 → 0.13.1
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,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.4 record-contract helpers (SPEC §13.4 "Record", §13.7 kinds, §13.9 writer table, §13.12
|
|
3
|
+
* binding) — the registered kind table with its pinned key grammars, the split-key CAS write
|
|
4
|
+
* discipline, and the merged read/watch with the §13.4 staleness rules.
|
|
5
|
+
*
|
|
6
|
+
* A record is stored in the per-space `cotal_records_<space>` KV as TWO keys with independent
|
|
7
|
+
* revisions, `<key>.spec` and `<key>.status` — the split IS the broker-enforced writer boundary
|
|
8
|
+
* (each writer role holds publish authority on its own key only). The single exception is the
|
|
9
|
+
* lifecycle alias HEAD, one atomic unsplit key. Writes are per-key CAS and a lost race is a
|
|
10
|
+
* LOUD `conflict` the caller re-reads and re-decides (§13.8) — deliberately unlike the ACL
|
|
11
|
+
* registry's internal retry, because record writers are fenced principals whose lost CAS is a
|
|
12
|
+
* decision point, never a last-writer-wins policy.
|
|
13
|
+
*
|
|
14
|
+
* These are the primitives the mediated writer principals (§13.9) build on; nothing here grants
|
|
15
|
+
* anything. Untrusted callers never hold raw reads on this bucket — their reads ride the
|
|
16
|
+
* mediator (§13.9 "Mediated reads"); the helpers below run inside trusted principals.
|
|
17
|
+
*/
|
|
18
|
+
import { type KV } from "@nats-io/kv";
|
|
19
|
+
import type { JetStreamManager } from "@nats-io/jetstream";
|
|
20
|
+
/** The per-space records bucket (§13.12): per-key CAS; `allow_direct=true`, but the lifecycle
|
|
21
|
+
* head and every FENCED read are leader-served `STREAM.MSG.GET` (§13.9) — helpers here are the
|
|
22
|
+
* non-fencing paths; a fence is always a revision-pinned CAS WRITE, never a read. */
|
|
23
|
+
export declare function recordsBucket(space: string): string;
|
|
24
|
+
/** Open the records bucket. Auth mode OPENs the bucket pre-created at space setup; a privileged
|
|
25
|
+
* caller passes `{ create: true }` to CREATE it (setup only). Mirrors {@link openAclRegistry}. */
|
|
26
|
+
export declare function openRecordsBucket(nc: import("@nats-io/transport-node").NatsConnection, space: string, opts?: {
|
|
27
|
+
create?: boolean;
|
|
28
|
+
}): Promise<KV>;
|
|
29
|
+
/** LEADER-SERVED read of one records-KV key: `STREAM.MSG.GET last_by_subj` on the bucket's
|
|
30
|
+
* backing stream, never `kv.get`/`DIRECT.GET`. A FENCING read — a fresh-check a mediated
|
|
31
|
+
* writer acts on before publishing authority state — needs read-your-writes against the
|
|
32
|
+
* leader; the bucket keeps `allow_direct=true` for the non-fencing paths, and a
|
|
33
|
+
* follower-served Direct Get may answer with a superseded revision, which is exactly the
|
|
34
|
+
* staleness a fence must not carry (§13.9, the same rule as {@link readLastFact}).
|
|
35
|
+
* `undefined` = the key has never been written. A DEL/PURGE marker is a DELETION, never
|
|
36
|
+
* absence — fail-closed refusal, the caller reconciles the store. */
|
|
37
|
+
export declare function readRecordLeader(jsm: JetStreamManager, space: string, key: string): Promise<{
|
|
38
|
+
value: unknown;
|
|
39
|
+
revision: number;
|
|
40
|
+
} | undefined>;
|
|
41
|
+
/** One qualifier token between the kind token and the `.spec`/`.status` suffix. */
|
|
42
|
+
export interface RecordQualifier {
|
|
43
|
+
name: string;
|
|
44
|
+
/** Token validator/normalizer — fail-loud, same validators as the subject grammar. */
|
|
45
|
+
assert: (v: string) => string;
|
|
46
|
+
}
|
|
47
|
+
/** A registered record kind: its pinned key grammar, writer roles, and mediation class —
|
|
48
|
+
* grants and merged watches are DERIVED from this entry (§13.7), so two implementations
|
|
49
|
+
* always agree on which key carries what. */
|
|
50
|
+
export interface RecordKindDef {
|
|
51
|
+
/** The wire kind token (single-label names are core-reserved; third-party kinds are
|
|
52
|
+
* reverse-DNS, tokenized `.`→`_` exactly like endpoint names). */
|
|
53
|
+
kind: string;
|
|
54
|
+
qualifiers: RecordQualifier[];
|
|
55
|
+
/** `.spec`/`.status`-split — every kind EXCEPT the lifecycle alias head (§13.7/§13.9). */
|
|
56
|
+
split: boolean;
|
|
57
|
+
/** Writer PROFILES per the §13.9 writer table (declarative names; grant generation reads
|
|
58
|
+
* them). For the unsplit head both name the one committing principal. */
|
|
59
|
+
writers: {
|
|
60
|
+
spec: string;
|
|
61
|
+
status: string;
|
|
62
|
+
};
|
|
63
|
+
mediation: "mediated" | "direct";
|
|
64
|
+
}
|
|
65
|
+
/** The lifecycle alias HEAD (§13.7/§13.9): `lifecycle.<owner>.<actor>` — ONE atomic unsplit
|
|
66
|
+
* key, the authoritative current mapping and the only `mappingRevision` source. Activation
|
|
67
|
+
* and terminal retirement serialize on its CAS; a fresh authority read of it is a
|
|
68
|
+
* leader-served `STREAM.MSG.GET` by the trusted mapping-reader, never a follower-served get. */
|
|
69
|
+
export declare const LIFECYCLE_HEAD: RecordKindDef;
|
|
70
|
+
/** The §13.1 space-global UID RESERVATION (§13.7): `uid.<lifecycleUid>` — ONE atomic unsplit
|
|
71
|
+
* key, create-only and NEVER-DELETED for the life of the space. The KEY is the reservation
|
|
72
|
+
* (the value records the reserving authority + intended alias, audit only): the minting
|
|
73
|
+
* authority wins this create BEFORE any gate or head write, a create conflict BURNS the
|
|
74
|
+
* candidate (the alias head alone cannot reject the same UID under a different alias, and
|
|
75
|
+
* the gate./cred. families key by UID alone), and a DEL/PURGE marker is corruption, never
|
|
76
|
+
* reusable absence. */
|
|
77
|
+
export declare const UID_RESERVATION: RecordKindDef;
|
|
78
|
+
/** The fixed sentinel target token for an admission with no target lifecycle (§13.7/§13.8). */
|
|
79
|
+
export declare const OBLIGATION_EP_SENTINEL = "ep";
|
|
80
|
+
/** The §13.8 TARGET-INDEXED ACCEPTANCE OBLIGATION (§13.7): one atomic unsplit key per
|
|
81
|
+
* acceptance identity, `oblig.<targetUid>.<endpoint>.<cOwner>.<cActor>.<cUid>.<id>` — the ONE
|
|
82
|
+
* durable serialization coordinate on which a durable acceptance/start contends with its
|
|
83
|
+
* authority head's movement (no cross-stream CAS exists). Target-first, so a retirement
|
|
84
|
+
* barrier enumerates `oblig.<targetUid>.>`; an admission under policy with NO target lifecycle
|
|
85
|
+
* keys the row with the fixed sentinel target token `ep` (which the §13.1 UID grammar can
|
|
86
|
+
* never produce), excluded from retirement drains and included in the endpoint's policy drain
|
|
87
|
+
* via `oblig.*.<endpoint>.>`. Create-only winner, monotonic value states
|
|
88
|
+
* (`provisional → accepted → terminal` | `provisional → rejected`), NEVER-DELETED. Writer:
|
|
89
|
+
* the admission mediator ONLY (§13.9; the canonicalizer holds no raw `oblig.` grant). */
|
|
90
|
+
export declare const OBLIGATION: RecordKindDef;
|
|
91
|
+
/** The §13.6 IMMUTABLE ADMISSION-POLICY VERSION (§13.7): `policy.<endpoint>.<digest-hex>` — one
|
|
92
|
+
* atomic unsplit key per policy version, create-only, NEVER-DELETED, never overwritten.
|
|
93
|
+
* `<digest-hex>` is the SHA-256 hex of the record's canonical value bytes, so the key is
|
|
94
|
+
* SELF-CERTIFYING: a reader re-digests the value it read and refuses a mismatch. The govern
|
|
95
|
+
* head's `enforcedPolicyKey`/`pendingPolicyKey` name keys of exactly this kind, which is what
|
|
96
|
+
* keeps both the enforced and the pending policy readable through a mutation's whole drain
|
|
97
|
+
* window (§13.6). Writer: the provisioner registration path ONLY (§13.9). */
|
|
98
|
+
export declare const POLICY_VERSION: RecordKindDef;
|
|
99
|
+
/** The §13.1 PER-STREAM RETIREMENT FRONTIERS (§13.7): `frontier.<lifecycleUid>` — ONE atomic
|
|
100
|
+
* unsplit key per retired lifecycle, create-only, NEVER-DELETED, written by the terminal
|
|
101
|
+
* retirement barrier AFTER the obligation drain, the pool cleaner, and the cleaner-credential
|
|
102
|
+
* revoke+evict, and BEFORE the gate/head terminals (§13.1 order). The value records the
|
|
103
|
+
* retirement `opId` and each bounded stream's last sequence at retirement — the cutoffs that
|
|
104
|
+
* bound the predecessor's half-open interval `(activationFrontier, retirementFrontier]`; they
|
|
105
|
+
* are never a successor's start (a successor captures its OWN activation frontier). */
|
|
106
|
+
export declare const RETIREMENT_FRONTIER: RecordKindDef;
|
|
107
|
+
/** The endpoint-wide GOVERNANCE HEAD (§13.7 "a self-published descriptor cannot strip, forge,
|
|
108
|
+
* or downgrade a governed annotation"): `govern.<endpoint>` — ONE atomic unsplit key holding
|
|
109
|
+
* the endpoint's MONOTONIC (append-only) BINDING governed-trait imposition per command, plus
|
|
110
|
+
* the single in-flight registration's PROVISIONAL slot (endpoint-service.ts): the head is the
|
|
111
|
+
* endpoint's registration linearization point — every registration CAS-takes the slot under
|
|
112
|
+
* its frozen gate, holds it through spec publication, and promotes its impositions to binding
|
|
113
|
+
* only after the publish commits. Governance is a HISTORY-bearing, endpoint-wide property, not
|
|
114
|
+
* a per-instance descriptor state: once BOUND, an imposition persists across instances AND
|
|
115
|
+
* across command removal (a tombstone), until an authorized revocation (the D18
|
|
116
|
+
* governance-consent artifact) lifts it — so a re-registration, a fresh instanceId, and a
|
|
117
|
+
* remove→re-add cannot launder a strip.
|
|
118
|
+
*
|
|
119
|
+
* NORMATIVE STATUS: `govern` is NOT yet in the frozen SPEC's §13.7 kind table, §13.9 writer
|
|
120
|
+
* matrix, or §13.12 records-bucket binding — it is implemented ahead of a pending P0
|
|
121
|
+
* reconciliation decision (the spec's governance-continuity requirement implies a durable,
|
|
122
|
+
* shared imposition record the frozen text does not name; multiple provisioners must read one
|
|
123
|
+
* head, so a process-internal store cannot satisfy it). The amendment is recorded in the
|
|
124
|
+
* control-surface STATUS; the operator decides spec changes. */
|
|
125
|
+
export declare const GOVERN_HEAD: RecordKindDef;
|
|
126
|
+
/** The §13.7 core kinds, pinned. Keys: `<kind>.<qualifiers…>` then `.spec`/`.status`. */
|
|
127
|
+
export declare const RECORD_KINDS: Record<string, RecordKindDef>;
|
|
128
|
+
/** The canonical AUTHORITY-CONTROL record kinds (§13.9): the mapping head, the UID reservation,
|
|
129
|
+
* the governance/policy heads, the acceptance obligation, and the retirement frontier. This is
|
|
130
|
+
* the SINGLE SOURCE consumed BOTH by the registry below AND by the record-reader seam
|
|
131
|
+
* ({@link ../endpoint-binding.ts}.recordReaderConfig): a caller reader durable may target NONE of
|
|
132
|
+
* these authority-only subtrees (nats-server#8274, the sealed records scanner owns `oblig.`), so
|
|
133
|
+
* adding a kind here extends registration AND the reader exclusion together — no parallel
|
|
134
|
+
* hand-kept deny-list to drift. `lifecycle` is DUAL: its atomic HEAD (`LIFECYCLE_HEAD`) is
|
|
135
|
+
* authority, while its deeper per-UID `RECORD_KINDS.lifecycle` detail is a caller-readable audit
|
|
136
|
+
* record; the seam admits the detail but head-guards the atomic key. */
|
|
137
|
+
export declare const AUTHORITY_KIND_DEFS: readonly RecordKindDef[];
|
|
138
|
+
export declare function callerReadableRecordKind(kind: string): boolean;
|
|
139
|
+
/** Register a third-party record kind. Reverse-DNS names ONLY — single-label kind names are
|
|
140
|
+
* reserved for the kinds this module pins (§13.7); a re-registration throws, no silent
|
|
141
|
+
* replacement. The kind name tokenizes `.`→`_` exactly like an endpoint name. */
|
|
142
|
+
export declare function registerRecordKind(def: Omit<RecordKindDef, "kind"> & {
|
|
143
|
+
kind: string;
|
|
144
|
+
}): RecordKindDef;
|
|
145
|
+
/** The unsplit key of an atomic kind (the lifecycle head). Throws for a split kind. */
|
|
146
|
+
export declare function recordAtomicKey(def: RecordKindDef, qualifiers: string[]): string;
|
|
147
|
+
/** The `.spec` key of a split kind. */
|
|
148
|
+
export declare function recordSpecKey(def: RecordKindDef, qualifiers: string[]): string;
|
|
149
|
+
/** The `.status` key of a split kind. */
|
|
150
|
+
export declare function recordStatusKey(def: RecordKindDef, qualifiers: string[]): string;
|
|
151
|
+
export interface ParsedRecordKey {
|
|
152
|
+
def: RecordKindDef;
|
|
153
|
+
qualifiers: string[];
|
|
154
|
+
part: "spec" | "status" | "atomic";
|
|
155
|
+
}
|
|
156
|
+
/** Parse a records-bucket key against the registry. `null` = no registered grammar matches —
|
|
157
|
+
* fail-closed, MUST NOT be handled (an unknown kind throws at the caller, no silent fallback).
|
|
158
|
+
* Split-only trust model as in the subject parser: shape and registry dispatch here; token
|
|
159
|
+
* grammars were enforced at build/mint time. */
|
|
160
|
+
export declare function parseRecordKey(key: string): ParsedRecordKey | null;
|
|
161
|
+
/** JetStream's expected-last-subject-sequence failure — the ONE broker condition behind every
|
|
162
|
+
* create-only/revision-pinned CAS loss here and in the journal (§13.4/§13.8). Keyed on the
|
|
163
|
+
* STRUCTURED `err_code` (`JetStreamApiCodes.StreamWrongLastSequence` 10071 and its
|
|
164
|
+
* `…Unknown` sibling 10164, the same pair the KV client's own create() classifies), never on
|
|
165
|
+
* message text: wording varies across server versions and a missed classification would turn
|
|
166
|
+
* a benign concurrent write into an unhandled throw inside a mediated writer. */
|
|
167
|
+
export declare function isCasLoss(e: unknown): boolean;
|
|
168
|
+
/** Create-only write of one record key, CAS-fenced against the key's ENTIRE history (a
|
|
169
|
+
* revision-0 expectation on the subject): an existing key OR a DEL/PURGE tombstone is a loud
|
|
170
|
+
* `conflict`. Deliberately NOT the KV client's own `create()`, which silently RECREATES over a
|
|
171
|
+
* tombstone — that would let whoever can delete a key re-open a one-use identity (rebind a
|
|
172
|
+
* settled checkpoint's holder, reset a decided lease, resurrect a terminal goal). Here a
|
|
173
|
+
* deletion permanently CLOSES the key (§13.8's create-only discipline; deletion is fail-closed
|
|
174
|
+
* state, never absence), and this CAS is the arbiter — a caller's marker pre-check is only a
|
|
175
|
+
* fast path, since a delete landing between check and create loses here, not there. Residual:
|
|
176
|
+
* a tombstone COMPACTED out of the bucket's history is indistinguishable from true absence at
|
|
177
|
+
* the broker; nothing in core compacts or deletes records keys, so that is operator store
|
|
178
|
+
* surgery — reconcile-the-store territory. Any other broker failure propagates untranslated.
|
|
179
|
+
* Returns the created revision. */
|
|
180
|
+
export declare function createRecordEntry(kv: KV, key: string, value: unknown): Promise<number>;
|
|
181
|
+
/** Revision-pinned CAS update of one record key. A moved revision is a loud `conflict`; any
|
|
182
|
+
* other broker failure propagates untranslated. Returns the new revision. */
|
|
183
|
+
export declare function updateRecordEntry(kv: KV, key: string, value: unknown, expectedRevision: number): Promise<number>;
|
|
184
|
+
/** Status values MUST carry `observedSpecRevision` (§13.4) — the merged-read staleness rules
|
|
185
|
+
* key on it. Enforced at the write seam so a status without it can never exist. */
|
|
186
|
+
export declare function assertStatusValue<T extends Record<string, unknown>>(value: T): T & {
|
|
187
|
+
observedSpecRevision: number;
|
|
188
|
+
};
|
|
189
|
+
export interface MergedRecord<S = unknown, T = unknown> {
|
|
190
|
+
spec: {
|
|
191
|
+
value: S;
|
|
192
|
+
revision: number;
|
|
193
|
+
};
|
|
194
|
+
status?: {
|
|
195
|
+
value: T;
|
|
196
|
+
revision: number;
|
|
197
|
+
observedSpecRevision: number;
|
|
198
|
+
};
|
|
199
|
+
/** §13.4: `observedSpecRevision < spec.revision` is a STALE-BUT-VALID level-triggered
|
|
200
|
+
* projection, not an error. `false` when status is absent or caught up. */
|
|
201
|
+
staleProjection: boolean;
|
|
202
|
+
}
|
|
203
|
+
/** Merged logical read of a split record (§13.4): both keys, both revisions, the staleness
|
|
204
|
+
* classification. `observedSpecRevision > spec.revision` (a lagging spec read, possible across
|
|
205
|
+
* replica freshness points) triggers bounded spec re-reads until caught up or the deadline —
|
|
206
|
+
* the mismatched pair is NEVER returned. Absent record → `undefined`; a status without its
|
|
207
|
+
* spec is torn state → `failed-precondition`. */
|
|
208
|
+
export declare function readRecord<S = unknown, T = unknown>(kv: KV, def: RecordKindDef, qualifiers: string[], opts?: {
|
|
209
|
+
deadlineMs?: number;
|
|
210
|
+
}): Promise<MergedRecord<S, T> | undefined>;
|
|
211
|
+
/** Read an atomic (unsplit) record — the lifecycle head. NOT a fence: an authority read of the
|
|
212
|
+
* head (mapping currency before effect) is a leader-served `STREAM.MSG.GET` by the trusted
|
|
213
|
+
* mapping-reader (§13.9); this helper is the ordinary non-fencing read, and every fence is a
|
|
214
|
+
* revision-pinned CAS write against the returned revision. */
|
|
215
|
+
export declare function readAtomicRecord<V = unknown>(kv: KV, def: RecordKindDef, qualifiers: string[]): Promise<{
|
|
216
|
+
value: V;
|
|
217
|
+
revision: number;
|
|
218
|
+
} | undefined>;
|
|
219
|
+
/** Watch a split record: the current merged snapshot first, then a re-merged view per delta.
|
|
220
|
+
*
|
|
221
|
+
* Cursor discipline (§13.4/§13.8): ONE ordered consumer supplies BOTH the snapshot (the
|
|
222
|
+
* per-key last values the watch replays first) and the deltas after it — the cursor is the
|
|
223
|
+
* consumer's own position, so nothing between "snapshot" and "watch start" can ever be
|
|
224
|
+
* skipped. (A cursor derived from independent `get` reads — `max(specRev,statusRev)+1` — is
|
|
225
|
+
* provably gap-prone: mixed-freshness/TOCTOU reads let a higher revision on one key jump the
|
|
226
|
+
* resume point past an unseen update on the other.) Replay entries accumulate silently; the
|
|
227
|
+
* first merged view is yielded when the replay completes, and every later delta re-yields the
|
|
228
|
+
* merged view. A watcher that errors, ends, or observes a status ahead of its cached spec
|
|
229
|
+
* (impossible from honest writers in an unbroken ordered watch) RESYNCS with a fresh consumer
|
|
230
|
+
* — a fresh full snapshot, duplicates tolerated, never a patch across a gap.
|
|
231
|
+
*
|
|
232
|
+
* Resyncs are budgeted on CONSECUTIVE no-progress incarnations, reset once an incarnation
|
|
233
|
+
* delivers at least one ordered post-snapshot delta (a lifetime-cumulative budget would kill a
|
|
234
|
+
* long-lived watch on accumulated benign blips; a snapshot alone must not count as progress or
|
|
235
|
+
* an immediately-ending iterator would spin forever). Ends when the spec key is deleted (the
|
|
236
|
+
* record is retired — a watch started on an already-retired record ends immediately) or when
|
|
237
|
+
* `signal` aborts. A status whose spec key NEVER existed in the consistent replay view is real
|
|
238
|
+
* torn state (`failed-precondition`) — the single-consumer view cannot false-positive this. */
|
|
239
|
+
export declare function watchRecord<S = unknown, T = unknown>(kv: KV, def: RecordKindDef, qualifiers: string[], opts?: {
|
|
240
|
+
signal?: AbortSignal;
|
|
241
|
+
maxResyncs?: number;
|
|
242
|
+
}): AsyncGenerator<MergedRecord<S, T>, void, void>;
|
|
243
|
+
//# sourceMappingURL=endpoint-records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-records.d.ts","sourceRoot":"","sources":["../src/endpoint-records.ts"],"names":[],"mappings":"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"}
|