@cotal-ai/core 0.66.1 → 0.67.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.
Files changed (67) hide show
  1. package/dist/auth-provider.d.ts +16 -9
  2. package/dist/auth-provider.d.ts.map +1 -1
  3. package/dist/backup-config.d.ts +1 -1
  4. package/dist/backup-config.d.ts.map +1 -1
  5. package/dist/backup-config.js +6 -2
  6. package/dist/backup-config.js.map +1 -1
  7. package/dist/connector.d.ts +24 -0
  8. package/dist/connector.d.ts.map +1 -1
  9. package/dist/connector.js.map +1 -1
  10. package/dist/endpoint-action.d.ts.map +1 -1
  11. package/dist/endpoint-action.js +9 -10
  12. package/dist/endpoint-action.js.map +1 -1
  13. package/dist/endpoint-envelope.d.ts.map +1 -1
  14. package/dist/endpoint-envelope.js +1 -3
  15. package/dist/endpoint-envelope.js.map +1 -1
  16. package/dist/endpoint-grants.d.ts +1 -1
  17. package/dist/endpoint-grants.d.ts.map +1 -1
  18. package/dist/endpoint-grants.js +1 -0
  19. package/dist/endpoint-grants.js.map +1 -1
  20. package/dist/endpoint-invoke.d.ts +6 -0
  21. package/dist/endpoint-invoke.d.ts.map +1 -1
  22. package/dist/endpoint-invoke.js +6 -0
  23. package/dist/endpoint-invoke.js.map +1 -1
  24. package/dist/endpoint-reconcile.js +2 -2
  25. package/dist/endpoint-reconcile.js.map +1 -1
  26. package/dist/endpoint-serve-kv.d.ts.map +1 -1
  27. package/dist/endpoint-serve-kv.js +29 -44
  28. package/dist/endpoint-serve-kv.js.map +1 -1
  29. package/dist/endpoint-service.d.ts +3 -10
  30. package/dist/endpoint-service.d.ts.map +1 -1
  31. package/dist/endpoint-service.js +3 -3
  32. package/dist/endpoint-service.js.map +1 -1
  33. package/dist/endpoint.d.ts +8 -8
  34. package/dist/endpoint.d.ts.map +1 -1
  35. package/dist/endpoint.js +19 -20
  36. package/dist/endpoint.js.map +1 -1
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +1 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/lifecycle-saga.d.ts.map +1 -1
  42. package/dist/lifecycle-saga.js +24 -24
  43. package/dist/lifecycle-saga.js.map +1 -1
  44. package/dist/lifecycle-state.d.ts +44 -36
  45. package/dist/lifecycle-state.d.ts.map +1 -1
  46. package/dist/lifecycle-state.js.map +1 -1
  47. package/dist/provision.d.ts +14 -1
  48. package/dist/provision.d.ts.map +1 -1
  49. package/dist/provision.js +27 -4
  50. package/dist/provision.js.map +1 -1
  51. package/dist/remote-manager-authority.d.ts +13 -1
  52. package/dist/remote-manager-authority.d.ts.map +1 -1
  53. package/dist/remote-manager-authority.js +24 -17
  54. package/dist/remote-manager-authority.js.map +1 -1
  55. package/dist/spaces.d.ts +5 -1
  56. package/dist/spaces.d.ts.map +1 -1
  57. package/dist/spaces.js +50 -15
  58. package/dist/spaces.js.map +1 -1
  59. package/dist/subjects.d.ts +9 -0
  60. package/dist/subjects.d.ts.map +1 -1
  61. package/dist/subjects.js +14 -0
  62. package/dist/subjects.js.map +1 -1
  63. package/dist/transfer.d.ts +110 -0
  64. package/dist/transfer.d.ts.map +1 -0
  65. package/dist/transfer.js +325 -0
  66. package/dist/transfer.js.map +1 -0
  67. package/package.json +1 -1
@@ -0,0 +1,110 @@
1
+ import { type NatsConnection } from "@nats-io/nats-core";
2
+ import { type JetStreamManager } from "@nats-io/jetstream";
3
+ /** The stock client's default chunk, and the most a chunk carries. */
4
+ export declare const TRANSFER_CHUNK_MAX: number;
5
+ /** Transcript bytes acknowledged through a chunk. */
6
+ export declare const OFFSET_HEADER = "Cotal-Offset";
7
+ /** Chunks acknowledged through a chunk. */
8
+ export declare const CHUNK_HEADER = "Cotal-Chunk";
9
+ /** `$O.<bucket>.C.<hex>`: one stable chunk subject per transcript, so every attempt at the same bytes
10
+ * extends the same chain. */
11
+ export declare function transferChunkSubject(bucket: string, hex: string): string;
12
+ /** `$O.<bucket>.M.<name>`, the name encoded as the stock client encodes it. */
13
+ export declare function transferMetaSubject(bucket: string, hex: string): string;
14
+ /**
15
+ * Create the instance's transfer bucket, or verify one that exists, and return its name. Same
16
+ * discipline as `ensureArtifactStore`: a store that exists under the name with other bounds is
17
+ * refused rather than adopted. `max_age` must be 0, because a per-message age can drop the start of
18
+ * a chain and keep its end (design section 4.5); direct get must be on, because the hit check and the
19
+ * resume read use it.
20
+ */
21
+ export declare function ensureTransferStore(nc: NatsConnection, space: string, instanceId: string): Promise<string>;
22
+ /**
23
+ * The operator's transfer instrument (design section 6): publish the one object's chunk and meta
24
+ * subjects in one instance's bucket, and read the last message of each with a direct get. It names
25
+ * no other object, no stream API beyond those two reads, and no consumer, so a copied instrument can
26
+ * extend or commit only the transcript the CLI hashed before minting it.
27
+ */
28
+ export declare function transferWriterGrants(space: string, instanceId: string, hex: string, connId: string): {
29
+ publish: string[];
30
+ subscribe: string[];
31
+ };
32
+ /**
33
+ * A manager instance's transfer reader (design section 6): create and read its own bucket's stream,
34
+ * stream it through the stock `get`'s push consumer, and remove a transfer with the stock delete
35
+ * marker and a filtered purge. Every row names the instance's own stream, so it reads no other
36
+ * instance's transfers. The push consumer delivers to this connection's own inbox, and a caller-chosen
37
+ * `deliver_subject` could only export the bucket this reader is already entitled to.
38
+ */
39
+ export declare function transferReaderGrants(space: string, instanceId: string, connId: string): {
40
+ publish: string[];
41
+ subscribe: string[];
42
+ };
43
+ /** How far a chain got: the last chunk's headers and stream sequence, or all zero for no chain. */
44
+ export interface ChainHead {
45
+ offset: number;
46
+ chunks: number;
47
+ seq: number;
48
+ }
49
+ /** Which read a caller's grant allows: the writer holds last-by-subject direct gets on its two
50
+ * subjects, the target's reader holds `STREAM.MSG.GET` on its own stream (design section 6). */
51
+ export type TransferRead = "direct" | "stream";
52
+ /** Read the last chunk on the transcript's chunk subject: the writer's resume point. */
53
+ export declare function readChainHead(jsm: JetStreamManager, bucket: string, hex: string): Promise<ChainHead>;
54
+ /** The meta subject's last message: its sequence (0 for none) and whether it is a live record. */
55
+ export interface MetaHead {
56
+ seq: number;
57
+ live: boolean;
58
+ /** The record's chunk subject token (a stock delete marker keeps it) and the live record's chunk count. */
59
+ nuid?: string;
60
+ chunks?: number;
61
+ digest?: string;
62
+ }
63
+ export declare function readMetaHead(jsm: JetStreamManager, bucket: string, hex: string, read: TransferRead): Promise<MetaHead>;
64
+ /** How one write pass ended. Every outcome but `live` is followed by `transcript-receive`, whose answer
65
+ * ends the write (design 4.3); `live` is another writer's commit, which the target fetches. */
66
+ export type WriteOutcome = {
67
+ state: "committed" | "refused" | "removed" | "live";
68
+ sent: number;
69
+ chunks: number;
70
+ };
71
+ /**
72
+ * One pass of the writer (design 4.2-4.4): skip to the target on a live record, continue the chain from
73
+ * its head, and commit. A refused chunk expectation rereads the head and continues when a chunk is
74
+ * left; an empty subject means the target removed the transfer, which only the target can resolve.
75
+ * `sent` and `chunks` count what this pass published.
76
+ */
77
+ export declare function writeTransfer(nc: NatsConnection, bucket: string, bytes: Uint8Array): Promise<WriteOutcome>;
78
+ /**
79
+ * Remove a transfer whole (design 4.5): the stock delete for a live record (its marker, then one
80
+ * filtered purge of the record's chunk subject), otherwise the purge alone of each chunk subject that
81
+ * holds a message: the chain's, and the one a delete marker names, whose chunks remain when a stop fell
82
+ * between the marker and its purge (a stock put names a random one). A transfer with neither is already
83
+ * removed and nothing is written, because a stock delete of a deleted record publishes another marker.
84
+ */
85
+ export declare function removeTransfer(nc: NatsConnection, bucket: string, hex: string): Promise<void>;
86
+ /** One transfer the sweep found: its digest and when its last message was written. */
87
+ export interface TransferEntry {
88
+ hex: string;
89
+ lastWrite: Date;
90
+ }
91
+ /** Every transfer in the bucket, listed from the stream's subjects and the last message of each. */
92
+ export declare function listTransfers(nc: NatsConnection, bucket: string): Promise<TransferEntry[]>;
93
+ /** What fetching a committed object found. */
94
+ export type FetchOutcome = {
95
+ state: "absent";
96
+ } | {
97
+ state: "fetched";
98
+ bytes: Uint8Array;
99
+ } | {
100
+ state: "invalid";
101
+ reason: string;
102
+ };
103
+ /**
104
+ * Read a committed object with the stock `get` and check it against the requested digest. The chunk
105
+ * count is checked first, because the stock `get` of a record whose chunks were swept waits for them
106
+ * and never returns (design 4.5). The record is the writer's claim: the stock `get` recomputes the
107
+ * digest over what it streams, and the record's own digest must name the bytes the operator asked for.
108
+ */
109
+ export declare function fetchTransfer(nc: NatsConnection, bucket: string, hex: string): Promise<FetchOutcome>;
110
+ //# sourceMappingURL=transfer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,325 @@
1
+ /**
2
+ * The resume transfer store: a carried transcript's path from the operator's host to one manager
3
+ * instance (docs/design/resume-transfer.md sections 3 and 4).
4
+ *
5
+ * Objects are written in the stock Object Store layout so the stock `get` reads and verifies them,
6
+ * but never with the stock `put`: that draws a random chunk subject per call and purges what it wrote
7
+ * on any error, so an interrupted upload could only restart from byte zero. Here the chunk subject is
8
+ * derived from the digest and every chunk publish is pinned to the previous one's stream sequence, so
9
+ * the broker's chain is the checkpoint and any writer of the same bytes continues it.
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ import { headers } from "@nats-io/nats-core";
13
+ import { jetstream, jetstreamManager } from "@nats-io/jetstream";
14
+ import { Objm } from "@nats-io/obj";
15
+ import { objectStoreStream, transferBucket } from "./subjects.js";
16
+ import { fromObjectStoreDigest } from "./artifact.js";
17
+ import { isCasLoss } from "./endpoint-records.js";
18
+ /** The stock client's default chunk, and the most a chunk carries. */
19
+ export const TRANSFER_CHUNK_MAX = 128 * 1024;
20
+ /** Room left under `max_payload` for the publish's headers. */
21
+ const HEADER_ROOM = 4 * 1024;
22
+ /** Transcript bytes acknowledged through a chunk. */
23
+ export const OFFSET_HEADER = "Cotal-Offset";
24
+ /** Chunks acknowledged through a chunk. */
25
+ export const CHUNK_HEADER = "Cotal-Chunk";
26
+ const EXPECTED_LAST_SUBJECT_SEQ = "Nats-Expected-Last-Subject-Sequence";
27
+ const HEX64 = /^[0-9a-f]{64}$/;
28
+ /** A record's chunk subject token: this protocol's hex digest or the stock client's nuid, never a wildcard. */
29
+ const STOCK_NUID = /^[0-9A-Za-z]{1,64}$/;
30
+ function assertHex(hex) {
31
+ if (!HEX64.test(hex))
32
+ throw new Error(`transfer: ${JSON.stringify(hex)} is not a 64-character lowercase hex digest`);
33
+ }
34
+ /** Base64url with its padding kept, the stock client's encoding for meta subjects and digests. */
35
+ function paddedBase64Url(bytes) {
36
+ return bytes.toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
37
+ }
38
+ /** `$O.<bucket>.C.<hex>`: one stable chunk subject per transcript, so every attempt at the same bytes
39
+ * extends the same chain. */
40
+ export function transferChunkSubject(bucket, hex) {
41
+ assertHex(hex);
42
+ return `$O.${bucket}.C.${hex}`;
43
+ }
44
+ /** `$O.<bucket>.M.<name>`, the name encoded as the stock client encodes it. */
45
+ export function transferMetaSubject(bucket, hex) {
46
+ assertHex(hex);
47
+ return `$O.${bucket}.M.${paddedBase64Url(Buffer.from(`sha256:${hex}`))}`;
48
+ }
49
+ /**
50
+ * Create the instance's transfer bucket, or verify one that exists, and return its name. Same
51
+ * discipline as `ensureArtifactStore`: a store that exists under the name with other bounds is
52
+ * refused rather than adopted. `max_age` must be 0, because a per-message age can drop the start of
53
+ * a chain and keep its end (design section 4.5); direct get must be on, because the hit check and the
54
+ * resume read use it.
55
+ */
56
+ export async function ensureTransferStore(nc, space, instanceId) {
57
+ const bucket = transferBucket(space, instanceId);
58
+ const stream = objectStoreStream(bucket);
59
+ const jsm = await jetstreamManager(nc);
60
+ await new Objm(jetstream(nc)).create(bucket, { max_bytes: -1 });
61
+ const { config } = await jsm.streams.info(stream);
62
+ const drift = [];
63
+ const want = [`$O.${bucket}.C.>`, `$O.${bucket}.M.>`];
64
+ if (JSON.stringify(config.subjects ?? []) !== JSON.stringify(want))
65
+ drift.push(`subjects are ${JSON.stringify(config.subjects ?? [])}, expected ${JSON.stringify(want)}`);
66
+ if (config.mirror)
67
+ drift.push("it is a MIRROR of another stream");
68
+ if (config.sources?.length)
69
+ drift.push(`it SOURCES ${config.sources.length} other stream(s)`);
70
+ if (String(config.discard) !== "new")
71
+ drift.push(`discard is ${config.discard}, expected new`);
72
+ if (String(config.storage) !== "file")
73
+ drift.push(`storage is ${config.storage}, expected file`);
74
+ if (String(config.retention) !== "limits")
75
+ drift.push(`retention is ${config.retention}, expected limits`);
76
+ if (config.allow_rollup_hdrs !== true)
77
+ drift.push("allow_rollup_hdrs is false, expected true (the commit is a subject rollup)");
78
+ if (config.allow_direct !== true)
79
+ drift.push("allow_direct is false, expected true (the hit and resume reads are direct gets)");
80
+ if (config.max_age !== 0)
81
+ drift.push(`max_age is ${config.max_age}, expected 0 (an age can drop the start of a chain and keep its end)`);
82
+ if (config.sealed === true)
83
+ drift.push("the stream is SEALED (writes permanently refused)");
84
+ for (const [field, value] of [["max_bytes", config.max_bytes], ["max_msgs", config.max_msgs],
85
+ ["max_msgs_per_subject", config.max_msgs_per_subject], ["max_msg_size", config.max_msg_size]])
86
+ if (value !== -1)
87
+ drift.push(`${field} is ${value}, expected -1`);
88
+ if (drift.length)
89
+ throw new Error(`transfer store ${stream} has drifted: ${drift.join("; ")} - refusing to adopt it (delete it, or reconcile it deliberately)`);
90
+ return bucket;
91
+ }
92
+ /**
93
+ * The operator's transfer instrument (design section 6): publish the one object's chunk and meta
94
+ * subjects in one instance's bucket, and read the last message of each with a direct get. It names
95
+ * no other object, no stream API beyond those two reads, and no consumer, so a copied instrument can
96
+ * extend or commit only the transcript the CLI hashed before minting it.
97
+ */
98
+ export function transferWriterGrants(space, instanceId, hex, connId) {
99
+ const bucket = transferBucket(space, instanceId);
100
+ const subjects = [transferChunkSubject(bucket, hex), transferMetaSubject(bucket, hex)];
101
+ const direct = `$JS.API.DIRECT.GET.${objectStoreStream(bucket)}`;
102
+ return { publish: [...subjects, ...subjects.map((s) => `${direct}.${s}`)], subscribe: [`_INBOX_${connId}.>`] };
103
+ }
104
+ /**
105
+ * A manager instance's transfer reader (design section 6): create and read its own bucket's stream,
106
+ * stream it through the stock `get`'s push consumer, and remove a transfer with the stock delete
107
+ * marker and a filtered purge. Every row names the instance's own stream, so it reads no other
108
+ * instance's transfers. The push consumer delivers to this connection's own inbox, and a caller-chosen
109
+ * `deliver_subject` could only export the bucket this reader is already entitled to.
110
+ */
111
+ export function transferReaderGrants(space, instanceId, connId) {
112
+ const bucket = transferBucket(space, instanceId);
113
+ const stream = objectStoreStream(bucket);
114
+ return {
115
+ publish: [
116
+ // The stock Object Store client opens its manager with the account API check.
117
+ "$JS.API.INFO",
118
+ `$JS.API.STREAM.CREATE.${stream}`,
119
+ `$JS.API.STREAM.INFO.${stream}`,
120
+ `$JS.API.STREAM.MSG.GET.${stream}`,
121
+ `$JS.API.STREAM.PURGE.${stream}`,
122
+ `$JS.API.CONSUMER.CREATE.${stream}`,
123
+ `$JS.API.CONSUMER.CREATE.${stream}.>`,
124
+ `$O.${bucket}.M.>`,
125
+ // Flow control replies of the stock get's push consumer, which the broker names by stream.
126
+ `$JS.FC.${stream}.>`,
127
+ ],
128
+ subscribe: [`_INBOX_${connId}.>`],
129
+ };
130
+ }
131
+ function lastOnSubject(jsm, stream, subject, read) {
132
+ return read === "direct"
133
+ ? jsm.direct.getMessage(stream, { last_by_subj: subject })
134
+ : jsm.streams.getMessage(stream, { last_by_subj: subject });
135
+ }
136
+ /** Read the last chunk on the transcript's chunk subject: the writer's resume point. */
137
+ export async function readChainHead(jsm, bucket, hex) {
138
+ const m = await lastOnSubject(jsm, objectStoreStream(bucket), transferChunkSubject(bucket, hex), "direct");
139
+ if (m === null)
140
+ return { offset: 0, chunks: 0, seq: 0 };
141
+ const offset = Number(m.header.get(OFFSET_HEADER));
142
+ const chunks = Number(m.header.get(CHUNK_HEADER));
143
+ if (!Number.isSafeInteger(offset) || offset <= 0 || !Number.isSafeInteger(chunks) || chunks <= 0)
144
+ throw new Error(`transfer chunk ${m.subject}#${m.seq} carries no valid ${OFFSET_HEADER}/${CHUNK_HEADER} headers`);
145
+ return { offset, chunks, seq: m.seq };
146
+ }
147
+ export async function readMetaHead(jsm, bucket, hex, read) {
148
+ const m = await lastOnSubject(jsm, objectStoreStream(bucket), transferMetaSubject(bucket, hex), read);
149
+ if (m === null)
150
+ return { seq: 0, live: false };
151
+ const info = JSON.parse(m.string());
152
+ if (info.deleted === true)
153
+ return { seq: m.seq, live: false, nuid: info.nuid };
154
+ return { seq: m.seq, live: true, nuid: info.nuid, chunks: info.chunks, digest: info.digest };
155
+ }
156
+ /** The connection's chunk size: the stock default, lowered to fit `max_payload`. */
157
+ function chunkSize(nc) {
158
+ const maxPayload = nc.info?.max_payload;
159
+ if (!maxPayload)
160
+ throw new Error("transfer: the connection reports no max_payload");
161
+ const size = Math.min(TRANSFER_CHUNK_MAX, maxPayload - HEADER_ROOM);
162
+ if (size <= 0)
163
+ throw new Error(`transfer: max_payload ${maxPayload} leaves no room for a chunk`);
164
+ return size;
165
+ }
166
+ /**
167
+ * One pass of the writer (design 4.2-4.4): skip to the target on a live record, continue the chain from
168
+ * its head, and commit. A refused chunk expectation rereads the head and continues when a chunk is
169
+ * left; an empty subject means the target removed the transfer, which only the target can resolve.
170
+ * `sent` and `chunks` count what this pass published.
171
+ */
172
+ export async function writeTransfer(nc, bucket, bytes) {
173
+ const digest = createHash("sha256").update(bytes).digest();
174
+ const hex = digest.toString("hex");
175
+ // The writer's instrument holds its two direct gets and nothing else on the JetStream API.
176
+ const jsm = await jetstreamManager(nc, { checkAPI: false });
177
+ const js = jetstream(nc);
178
+ const meta = await readMetaHead(jsm, bucket, hex, "direct");
179
+ if (meta.live)
180
+ return { state: "live", sent: 0, chunks: 0 };
181
+ const subject = transferChunkSubject(bucket, hex);
182
+ const max = chunkSize(nc);
183
+ let head = await readChainHead(jsm, bucket, hex);
184
+ let sent = 0;
185
+ let published = 0;
186
+ while (head.offset < bytes.length) {
187
+ const end = Math.min(head.offset + max, bytes.length);
188
+ const h = headers();
189
+ h.set(OFFSET_HEADER, String(end));
190
+ h.set(CHUNK_HEADER, String(head.chunks + 1));
191
+ h.set(EXPECTED_LAST_SUBJECT_SEQ, String(head.seq));
192
+ try {
193
+ const ack = await js.publish(subject, bytes.subarray(head.offset, end), { headers: h });
194
+ sent += end - head.offset;
195
+ published++;
196
+ head = { offset: end, chunks: head.chunks + 1, seq: ack.seq };
197
+ }
198
+ catch (e) {
199
+ if (!isCasLoss(e))
200
+ throw e;
201
+ head = await readChainHead(jsm, bucket, hex);
202
+ if (head.seq === 0)
203
+ return { state: "removed", sent, chunks: published };
204
+ }
205
+ }
206
+ const record = {
207
+ name: `sha256:${hex}`,
208
+ bucket,
209
+ nuid: hex,
210
+ size: bytes.length,
211
+ chunks: head.chunks,
212
+ mtime: new Date().toISOString(),
213
+ deleted: false,
214
+ options: { max_chunk_size: max },
215
+ digest: `SHA-256=${paddedBase64Url(digest)}`,
216
+ };
217
+ const h = headers();
218
+ h.set("Nats-Rollup", "sub");
219
+ h.set(EXPECTED_LAST_SUBJECT_SEQ, String(meta.seq));
220
+ try {
221
+ await js.publish(transferMetaSubject(bucket, hex), JSON.stringify(record), { headers: h });
222
+ }
223
+ catch (e) {
224
+ if (!isCasLoss(e))
225
+ throw e;
226
+ return { state: "refused", sent, chunks: published };
227
+ }
228
+ return { state: "committed", sent, chunks: published };
229
+ }
230
+ /** Messages held on one subject, read with `STREAM.INFO` and `subjects_filter`. */
231
+ async function subjectCount(jsm, stream, subject) {
232
+ const info = await jsm.streams.info(stream, { subjects_filter: subject });
233
+ return info.state.subjects?.[subject] ?? 0;
234
+ }
235
+ /**
236
+ * Remove a transfer whole (design 4.5): the stock delete for a live record (its marker, then one
237
+ * filtered purge of the record's chunk subject), otherwise the purge alone of each chunk subject that
238
+ * holds a message: the chain's, and the one a delete marker names, whose chunks remain when a stop fell
239
+ * between the marker and its purge (a stock put names a random one). A transfer with neither is already
240
+ * removed and nothing is written, because a stock delete of a deleted record publishes another marker.
241
+ */
242
+ export async function removeTransfer(nc, bucket, hex) {
243
+ const jsm = await jetstreamManager(nc);
244
+ const meta = await readMetaHead(jsm, bucket, hex, "stream");
245
+ if (meta.live) {
246
+ await (await new Objm(jetstream(nc)).open(bucket)).delete(`sha256:${hex}`);
247
+ return;
248
+ }
249
+ const stream = objectStoreStream(bucket);
250
+ const marked = meta.nuid !== undefined && STOCK_NUID.test(meta.nuid) ? [`$O.${bucket}.C.${meta.nuid}`] : [];
251
+ for (const subject of new Set([transferChunkSubject(bucket, hex), ...marked]))
252
+ if ((await subjectCount(jsm, stream, subject)) > 0)
253
+ await jsm.streams.purge(stream, { filter: subject });
254
+ }
255
+ /** Every transfer in the bucket, listed from the stream's subjects and the last message of each. */
256
+ export async function listTransfers(nc, bucket) {
257
+ const jsm = await jetstreamManager(nc);
258
+ const stream = objectStoreStream(bucket);
259
+ const chunkPrefix = `$O.${bucket}.C.`;
260
+ const metaPrefix = `$O.${bucket}.M.`;
261
+ const info = await jsm.streams.info(stream, { subjects_filter: `$O.${bucket}.>` });
262
+ const last = new Map();
263
+ for (const subject of Object.keys(info.state.subjects ?? {})) {
264
+ let hex;
265
+ if (subject.startsWith(chunkPrefix))
266
+ hex = subject.slice(chunkPrefix.length);
267
+ else if (subject.startsWith(metaPrefix)) {
268
+ const name = Buffer.from(subject.slice(metaPrefix.length), "base64url").toString();
269
+ if (!name.startsWith("sha256:"))
270
+ continue;
271
+ hex = name.slice("sha256:".length);
272
+ }
273
+ else
274
+ continue;
275
+ if (!HEX64.test(hex))
276
+ continue;
277
+ const m = await lastOnSubject(jsm, stream, subject, "stream");
278
+ if (m === null)
279
+ continue;
280
+ const at = m.time;
281
+ const seen = last.get(hex);
282
+ if (!seen || at > seen)
283
+ last.set(hex, at);
284
+ }
285
+ return [...last].map(([hex, lastWrite]) => ({ hex, lastWrite }));
286
+ }
287
+ /**
288
+ * Read a committed object with the stock `get` and check it against the requested digest. The chunk
289
+ * count is checked first, because the stock `get` of a record whose chunks were swept waits for them
290
+ * and never returns (design 4.5). The record is the writer's claim: the stock `get` recomputes the
291
+ * digest over what it streams, and the record's own digest must name the bytes the operator asked for.
292
+ */
293
+ export async function fetchTransfer(nc, bucket, hex) {
294
+ const jsm = await jetstreamManager(nc);
295
+ const meta = await readMetaHead(jsm, bucket, hex, "stream");
296
+ if (!meta.live)
297
+ return { state: "absent" };
298
+ if (meta.nuid === undefined || !HEX64.test(meta.nuid) || meta.chunks === undefined)
299
+ return { state: "invalid", reason: "the record names no chunk subject or chunk count" };
300
+ const held = await subjectCount(jsm, objectStoreStream(bucket), `$O.${bucket}.C.${meta.nuid}`);
301
+ if (held !== meta.chunks)
302
+ return { state: "invalid", reason: `the record names ${meta.chunks} chunks and ${held} are held` };
303
+ let recorded;
304
+ try {
305
+ recorded = fromObjectStoreDigest(meta.digest ?? "");
306
+ }
307
+ catch (e) {
308
+ return { state: "invalid", reason: e.message };
309
+ }
310
+ if (recorded !== `sha256:${hex}`)
311
+ return { state: "invalid", reason: `the record's digest is ${recorded}` };
312
+ const os = await new Objm(jetstream(nc)).open(bucket);
313
+ try {
314
+ const bytes = await os.getBlob(`sha256:${hex}`);
315
+ if (bytes === null)
316
+ return { state: "absent" };
317
+ if (createHash("sha256").update(bytes).digest("hex") !== hex)
318
+ return { state: "invalid", reason: "the bytes read do not hash to the name" };
319
+ return { state: "fetched", bytes };
320
+ }
321
+ catch (e) {
322
+ return { state: "invalid", reason: e.message };
323
+ }
324
+ }
325
+ //# sourceMappingURL=transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.js","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAuB,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAyC,MAAM,oBAAoB,CAAC;AACxG,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,sEAAsE;AACtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC7C,+DAA+D;AAC/D,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC;AAC7B,qDAAqD;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAC;AAC5C,2CAA2C;AAC3C,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;AAC1C,MAAM,yBAAyB,GAAG,qCAAqC,CAAC;AACxE,MAAM,KAAK,GAAG,gBAAgB,CAAC;AAC/B,+GAA+G;AAC/G,MAAM,UAAU,GAAG,qBAAqB,CAAC;AAEzC,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;AACvH,CAAC;AAED,kGAAkG;AAClG,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC1E,CAAC;AAED;8BAC8B;AAC9B,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,GAAW;IAC9D,SAAS,CAAC,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,MAAM,MAAM,GAAG,EAAE,CAAC;AACjC,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,GAAW;IAC7D,SAAS,CAAC,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,MAAM,MAAM,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAkB,EAAE,KAAa,EAAE,UAAkB;IAC7F,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,MAAM,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC;IACtD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxG,IAAI,MAAM,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAC9F,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAC/F,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;IACjG,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,SAAS,mBAAmB,CAAC,CAAC;IAC3G,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAChI,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;IAChI,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,OAAO,sEAAsE,CAAC,CAAC;IACzI,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAC5F,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC;QAC9D,CAAC,sBAAsB,EAAE,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,YAAY,CAAC,CAAU;QAClI,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,OAAO,KAAK,eAAe,CAAC,CAAC;IACpE,IAAI,KAAK,CAAC,MAAM;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;IAChJ,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa,EAAE,UAAkB,EAAE,GAAW,EAAE,MAAc;IACjG,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,sBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;IACjE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,UAAU,MAAM,IAAI,CAAC,EAAE,CAAC;AACjH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa,EAAE,UAAkB,EAAE,MAAc;IACpF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO;QACL,OAAO,EAAE;YACP,8EAA8E;YAC9E,cAAc;YACd,yBAAyB,MAAM,EAAE;YACjC,uBAAuB,MAAM,EAAE;YAC/B,0BAA0B,MAAM,EAAE;YAClC,wBAAwB,MAAM,EAAE;YAChC,2BAA2B,MAAM,EAAE;YACnC,2BAA2B,MAAM,IAAI;YACrC,MAAM,MAAM,MAAM;YAClB,2FAA2F;YAC3F,UAAU,MAAM,IAAI;SACrB;QACD,SAAS,EAAE,CAAC,UAAU,MAAM,IAAI,CAAC;KAClC,CAAC;AACJ,CAAC;AAaD,SAAS,aAAa,CAAC,GAAqB,EAAE,MAAc,EAAE,OAAe,EAAE,IAAkB;IAC/F,OAAO,IAAI,KAAK,QAAQ;QACtB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;QAC1D,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAqB,EAAE,MAAc,EAAE,GAAW;IACpF,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3G,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;QAC9F,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,qBAAqB,aAAa,IAAI,YAAY,UAAU,CAAC,CAAC;IACpH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;AACxC,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAqB,EAAE,MAAc,EAAE,GAAW,EAAE,IAAkB;IACvG,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;IACtG,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAA2E,CAAC;IAC9G,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/E,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC/F,CAAC;AAED,oFAAoF;AACpF,SAAS,SAAS,CAAC,EAAkB;IACnC,MAAM,UAAU,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC;IACxC,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,UAAU,GAAG,WAAW,CAAC,CAAC;IACpE,IAAI,IAAI,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,UAAU,6BAA6B,CAAC,CAAC;IACjG,OAAO,IAAI,CAAC;AACd,CAAC;AAOD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAkB,EAAE,MAAc,EAAE,KAAiB;IACvF,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,2FAA2F;IAC3F,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IACzB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC1B,IAAI,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YACxF,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,SAAS,EAAE,CAAC;YACZ,IAAI,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,CAAC;YAC3B,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7C,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC;gBAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC3E,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,UAAU,GAAG,EAAE;QACrB,MAAM;QACN,IAAI,EAAE,GAAG;QACT,IAAI,EAAE,KAAK,CAAC,MAAM;QAClB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC/B,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE;QAChC,MAAM,EAAE,WAAW,eAAe,CAAC,MAAM,CAAC,EAAE;KAC7C,CAAC;IACF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC,CAAC,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACzD,CAAC;AAED,mFAAmF;AACnF,KAAK,UAAU,YAAY,CAAC,GAAqB,EAAE,MAAc,EAAE,OAAe;IAChF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EAAkB,EAAE,MAAc,EAAE,GAAW;IAClF,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAC3E,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5G,KAAK,MAAM,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC,oBAAoB,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC;YAAE,MAAM,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7G,CAAC;AAQD,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAkB,EAAE,MAAc;IACpE,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,MAAM,MAAM,KAAK,CAAC;IACtC,MAAM,UAAU,GAAG,MAAM,MAAM,KAAK,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAgB,CAAC;IACrC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7D,IAAI,GAAW,CAAC;QAChB,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;aACxE,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;YACnF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,SAAS;YAC1C,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;;YAAM,SAAS;QAChB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QACzB,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,IAAI,EAAE,GAAG,IAAI;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AACnE,CAAC;AAQD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAkB,EAAE,MAAc,EAAE,GAAW;IACjF,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC3C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAChF,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,kDAAkD,EAAE,CAAC;IAC1F,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/F,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,oBAAoB,IAAI,CAAC,MAAM,eAAe,IAAI,WAAW,EAAE,CAAC;IAC7H,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IAC5D,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,GAAG,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,0BAA0B,QAAQ,EAAE,EAAE,CAAC;IAC5G,MAAM,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC/C,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG;YAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,wCAAwC,EAAE,CAAC;QAC5I,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IAC5D,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cotal-ai/core",
3
3
  "description": "The Cotal protocol: endpoint, subjects, message types, the NATS client layer, and the extension contracts.",
4
- "version": "0.66.1",
4
+ "version": "0.67.0",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
7
7
  "cotal",