@catalyst-cloud/sdk 0.9.2 → 0.10.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/README.md CHANGED
@@ -244,6 +244,32 @@ switch (moved.outcome) {
244
244
 
245
245
  The contract cache is in memory per client by default; pass `contractCache: { get, set }` to keep it on disk (the bundle does). `fetch`, `now` and `timeoutMs` are injectable so a test never opens a socket.
246
246
 
247
+ ### Durable event cache for node and Bun
248
+
249
+ `@catalyst-cloud/sdk/events` mirrors the tenant's exact durable Catalyst event backbone into an append-only local cache. It uses bounded HTTP replay with an idle backoff; local consumers tail files and never poll GitHub, Linear, or cloud tables. Start and stop it with the process that currently needs the tenant instead of installing another permanent daemon.
250
+
251
+ ```ts
252
+ import { CatalystEventSync, tailCachedEvents } from "@catalyst-cloud/sdk/events";
253
+
254
+ const sync = new CatalystEventSync({
255
+ baseUrl: "https://staging.catalystcloud.dev",
256
+ auth: { kind: "token", token: process.env.CATALYST_CLOUD_TOKEN! },
257
+ tenantId: "tenant-1",
258
+ });
259
+ const running = sync.start();
260
+ for await (const event of tailCachedEvents({ tenantId: "tenant-1", signal })) {
261
+ console.log(event.type, event.sequence);
262
+ }
263
+ await sync.stop();
264
+ await running;
265
+ ```
266
+
267
+ The default path is `$XDG_STATE_HOME/catalyst/events/<tenant>/backbone/`, falling back to `~/.local/state/catalyst/events/<tenant>/backbone/`. Daily `YYYY-MM-DD[-NNN].jsonl` segments contain the cloud's `CatalystEvent` envelope unchanged. `cursor.json` is owned by the one sync writer; readers keep their own offsets elsewhere and do not write into this directory. The stable replay identity is `(tenantId, sequence, eventId)`.
268
+
269
+ The writer fsyncs appended records before atomically advancing its cursor. On restart it truncates an incomplete final line and derives the resume cursor from the last complete record, making a crash between append and checkpoint safe. Server archive gaps and reads behind the local retention floor raise `EventHistoryGapError` with the head, suggested resume point, and reason; the SDK does not silently skip history. New caches bootstrap at the current backbone head. Closed daily segments are retained for seven days or until the cache reaches 256 MiB, whichever happens first. The active segment rotates before the same byte bound, so it cannot grow without limit; `retainDays` and `maxCacheBytes` configure these bounds.
270
+
271
+ This API only reads the durable backbone. It does not publish events or treat raw provider events, the legacy coordination feed, or analytical samples as execution or billing authority. Use the existing authorized cloud operations to report outcomes and changes.
272
+
247
273
  ## API
248
274
 
249
275
  | Export | What it is |
@@ -256,6 +282,7 @@ The contract cache is in memory per client by default; pass `contractCache: { ge
256
282
  | `createTenantClient` | The typed HTTP client — `contract()`, `me()`, `issues.list/get`, `pulls.list/get`, `projects.list`, `agent.*` (issueState, issueLabel, issueComment, issueCreate, reaction, attachment, attachments, session, ask, askAccept). |
257
283
  | `TenantContract` · `routeByName` · `teamByKey` · `teamForTicket` · `stageIdForSlot` · `labelIdFor` | The contract document's shape and the pure accessors over it, each returning a typed miss rather than throwing. |
258
284
  | `TenantClientFailure` · `PageCursor` · `pageCursor` · `memoryContractCache` | The shared failure arms, the opaque page token, and the default contract cache store. |
285
+ | `CatalystEventSync` · `readCachedEvents` · `tailCachedEvents` · `EventHistoryGapError` | Node/Bun durable-backbone replay, local cache readers, and explicit history-gap handling from `@catalyst-cloud/sdk/events`. |
259
286
 
260
287
  `start()` resolves only when `stop()` is called. On a backend, `await` it to keep the process alive; in a browser, never await it — just call `stop()` on teardown.
261
288
 
@@ -0,0 +1,79 @@
1
+ import type { CatalystEvent } from "@catalyst-cloud/schema";
2
+ import type { AuthStrategy } from "./live-sync-client.js";
3
+ import { type WriterGuardOptions } from "./replica/writer-lock.js";
4
+ export type { CatalystEvent } from "@catalyst-cloud/schema";
5
+ export interface EventCachePaths {
6
+ directory: string;
7
+ cursor: string;
8
+ lock: string;
9
+ }
10
+ export interface EventSyncOptions {
11
+ baseUrl: string;
12
+ auth: Exclude<AuthStrategy, {
13
+ kind: "cookie";
14
+ }>;
15
+ tenantId: string;
16
+ directory?: string;
17
+ fetch?: typeof fetch;
18
+ requestTimeoutMs?: number;
19
+ idleMinMs?: number;
20
+ idleMaxMs?: number;
21
+ retainDays?: number;
22
+ maxCacheBytes?: number;
23
+ writerGuard?: WriterGuardOptions;
24
+ now?: () => Date;
25
+ sleep?: (ms: number, signal: AbortSignal) => Promise<void>;
26
+ }
27
+ export interface EventSyncStatus {
28
+ state: "idle" | "syncing" | "stopped" | "failed";
29
+ cursor: number | null;
30
+ head: number | null;
31
+ lastSyncAt: string | null;
32
+ error: string | null;
33
+ }
34
+ export interface EventSyncResult {
35
+ appended: number;
36
+ cursor: number;
37
+ head: number;
38
+ }
39
+ export declare class EventHistoryGapError extends Error {
40
+ readonly head: number;
41
+ readonly resumeFrom: number;
42
+ readonly reason: string;
43
+ constructor(message: string, head: number, resumeFrom: number, reason: string);
44
+ }
45
+ export declare function defaultEventCacheDirectory(tenantId: string): string;
46
+ export declare function eventCachePaths(tenantId: string, directory?: string): EventCachePaths;
47
+ export declare class CatalystEventSync {
48
+ private readonly options;
49
+ readonly paths: EventCachePaths;
50
+ private readonly fetchImpl;
51
+ private readonly now;
52
+ private readonly sleeper;
53
+ private lock;
54
+ private controller;
55
+ private running;
56
+ private recoveredCursor;
57
+ private floor;
58
+ private current;
59
+ constructor(options: EventSyncOptions);
60
+ status(): EventSyncStatus;
61
+ syncOnce(signal?: AbortSignal): Promise<EventSyncResult>;
62
+ start(): Promise<void>;
63
+ stop(): Promise<void>;
64
+ private loop;
65
+ private request;
66
+ private readCurrentHead;
67
+ private readPage;
68
+ }
69
+ export interface ReadCachedEventsOptions {
70
+ tenantId: string;
71
+ directory?: string;
72
+ after?: number;
73
+ }
74
+ export declare function readCachedEvents(options: ReadCachedEventsOptions): Promise<CatalystEvent[]>;
75
+ export declare function tailCachedEvents(options: ReadCachedEventsOptions & {
76
+ signal: AbortSignal;
77
+ }): AsyncGenerator<CatalystEvent>;
78
+ export declare function eventIdentity(event: CatalystEvent): string;
79
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAW5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAHvB,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM;CAK1B;AASD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKnE;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,CAOjB;AAiOD,qBAAa,iBAAiB;IAkBhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBpC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqD;IAC7E,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,OAAO,CAMb;gBAE2B,OAAO,EAAE,gBAAgB;IAOtD,MAAM,IAAI,eAAe;IAInB,QAAQ,CACZ,MAAM,GAAE,WAA0C,GACjD,OAAO,CAAC,eAAe,CAAC;IA0D3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAehB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBb,IAAI;YAqCJ,OAAO;YAiBP,eAAe;YASf,QAAQ;CAoCvB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,aAAa,EAAE,CAAC,CAsC1B;AAED,wBAAuB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACzD,cAAc,CAAC,aAAa,CAAC,CAgC/B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAE1D"}
package/dist/events.js ADDED
@@ -0,0 +1,492 @@
1
+ import { mkdir, open, readFile, readdir, rename, rm, stat, truncate, watch, writeFile, } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { claimWriterLock, } from "./replica/writer-lock.js";
5
+ const HEAD_HEADER = "x-catalyst-event-backbone-head-seq";
6
+ const MAX_EVENT_LINE_BYTES = 1024 * 1024;
7
+ const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
8
+ const DEFAULT_IDLE_MIN_MS = 1_000;
9
+ const DEFAULT_IDLE_MAX_MS = 30_000;
10
+ const DEFAULT_RETAIN_DAYS = 7;
11
+ const DEFAULT_MAX_CACHE_BYTES = 256 * 1024 * 1024;
12
+ const SEGMENT_PATTERN = /^\d{4}-\d{2}-\d{2}(?:-\d{3})?\.jsonl$/;
13
+ export class EventHistoryGapError extends Error {
14
+ head;
15
+ resumeFrom;
16
+ reason;
17
+ constructor(message, head, resumeFrom, reason) {
18
+ super(message);
19
+ this.head = head;
20
+ this.resumeFrom = resumeFrom;
21
+ this.reason = reason;
22
+ this.name = "EventHistoryGapError";
23
+ }
24
+ }
25
+ class EventSyncHttpError extends Error {
26
+ status;
27
+ constructor(status) {
28
+ super(`event sync: backbone returned ${status}`);
29
+ this.status = status;
30
+ this.name = "EventSyncHttpError";
31
+ }
32
+ }
33
+ export function defaultEventCacheDirectory(tenantId) {
34
+ const state = globalThis
35
+ .process?.env?.XDG_STATE_HOME || join(homedir(), ".local", "state");
36
+ return join(state, "catalyst", "events", tenantId, "backbone");
37
+ }
38
+ export function eventCachePaths(tenantId, directory) {
39
+ const root = directory ?? defaultEventCacheDirectory(tenantId);
40
+ return {
41
+ directory: root,
42
+ cursor: join(root, "cursor.json"),
43
+ lock: join(root, ".sync"),
44
+ };
45
+ }
46
+ function positiveInteger(value, name) {
47
+ if ((typeof value !== "string" && typeof value !== "number") ||
48
+ String(value).trim() === "")
49
+ throw new Error(`event sync: invalid ${name}`);
50
+ const parsed = Number(value);
51
+ if (!Number.isSafeInteger(parsed) || parsed < 0)
52
+ throw new Error(`event sync: invalid ${name}`);
53
+ return parsed;
54
+ }
55
+ function parseEvent(value) {
56
+ if (!value || typeof value !== "object" || Array.isArray(value))
57
+ throw new Error("event sync: invalid event");
58
+ const event = value;
59
+ if (typeof event.tenantId !== "string" ||
60
+ !Number.isSafeInteger(event.sequence) ||
61
+ (event.sequence ?? -1) < 0 ||
62
+ typeof event.eventId !== "string" ||
63
+ typeof event.type !== "string" ||
64
+ !Number.isSafeInteger(event.schemaVersion) ||
65
+ typeof event.recordedAt !== "string" ||
66
+ !("payload" in event))
67
+ throw new Error("event sync: invalid event");
68
+ return event;
69
+ }
70
+ async function readNdjson(response) {
71
+ if (!response.body)
72
+ return [];
73
+ const reader = response.body.getReader();
74
+ const decoder = new TextDecoder();
75
+ let pending = "";
76
+ const rows = [];
77
+ const consume = (line) => {
78
+ if (!line)
79
+ return;
80
+ if (new TextEncoder().encode(line).byteLength > MAX_EVENT_LINE_BYTES)
81
+ throw new Error("event sync: event line exceeds 1 MiB");
82
+ rows.push({ event: parseEvent(JSON.parse(line)), line });
83
+ };
84
+ for (;;) {
85
+ const { done, value } = await reader.read();
86
+ pending += decoder.decode(value, { stream: !done });
87
+ let newline = pending.indexOf("\n");
88
+ while (newline >= 0) {
89
+ consume(pending.slice(0, newline));
90
+ pending = pending.slice(newline + 1);
91
+ newline = pending.indexOf("\n");
92
+ }
93
+ if (pending.length > MAX_EVENT_LINE_BYTES)
94
+ throw new Error("event sync: event line exceeds 1 MiB");
95
+ if (done)
96
+ break;
97
+ }
98
+ if (pending)
99
+ consume(pending);
100
+ return rows;
101
+ }
102
+ function segmentName(date, index = 0) {
103
+ const day = date.toISOString().slice(0, 10);
104
+ return index === 0
105
+ ? `${day}.jsonl`
106
+ : `${day}-${String(index).padStart(3, "0")}.jsonl`;
107
+ }
108
+ async function writeJsonAtomic(path, value) {
109
+ const pid = globalThis.process?.pid ?? 0;
110
+ const temporary = `${path}.${pid}.tmp`;
111
+ await writeFile(temporary, JSON.stringify(value) + "\n", { mode: 0o600 });
112
+ await rename(temporary, path);
113
+ }
114
+ async function readCursor(path) {
115
+ try {
116
+ const value = JSON.parse(await readFile(path, "utf8"));
117
+ return typeof value.cursor === "number" &&
118
+ Number.isSafeInteger(value.cursor) &&
119
+ value.cursor >= 0
120
+ ? {
121
+ cursor: value.cursor,
122
+ floor: typeof value.floor === "number" &&
123
+ Number.isSafeInteger(value.floor)
124
+ ? value.floor
125
+ : -1,
126
+ }
127
+ : null;
128
+ }
129
+ catch (error) {
130
+ if (error.code === "ENOENT")
131
+ return null;
132
+ throw error;
133
+ }
134
+ }
135
+ async function repairTail(directory) {
136
+ const segments = (await readdir(directory))
137
+ .filter((name) => SEGMENT_PATTERN.test(name))
138
+ .sort();
139
+ for (const name of segments.reverse()) {
140
+ const path = join(directory, name);
141
+ const bytes = await readFile(path);
142
+ if (bytes.length === 0)
143
+ continue;
144
+ const lastNewline = bytes.lastIndexOf(10);
145
+ if (lastNewline !== bytes.length - 1)
146
+ await truncate(path, lastNewline < 0 ? 0 : lastNewline + 1);
147
+ const complete = bytes
148
+ .subarray(0, lastNewline < 0 ? 0 : lastNewline)
149
+ .toString("utf8")
150
+ .trimEnd();
151
+ const line = complete.slice(complete.lastIndexOf("\n") + 1);
152
+ if (line)
153
+ return parseEvent(JSON.parse(line)).sequence;
154
+ }
155
+ return null;
156
+ }
157
+ async function retainBoundedSegments(directory, now, retainDays, maxBytes, current, floor) {
158
+ const segments = (await readdir(directory))
159
+ .filter((name) => SEGMENT_PATTERN.test(name))
160
+ .sort();
161
+ const sizes = new Map();
162
+ for (const name of segments)
163
+ sizes.set(name, (await stat(join(directory, name))).size);
164
+ let total = [...sizes.values()].reduce((sum, size) => sum + size, 0);
165
+ const cutoff = new Date(now);
166
+ cutoff.setUTCDate(cutoff.getUTCDate() - retainDays);
167
+ const remove = [];
168
+ for (const name of segments) {
169
+ if (name === current)
170
+ continue;
171
+ const expired = name.slice(0, 10) < cutoff.toISOString().slice(0, 10);
172
+ if (!expired && total <= maxBytes)
173
+ continue;
174
+ remove.push(name);
175
+ total -= sizes.get(name) ?? 0;
176
+ }
177
+ for (const name of remove) {
178
+ const body = await readFile(join(directory, name), "utf8");
179
+ const lines = body.trimEnd().split("\n");
180
+ const last = lines.at(-1);
181
+ if (last)
182
+ floor = Math.max(floor, parseEvent(JSON.parse(last)).sequence);
183
+ }
184
+ await Promise.all(remove.map((name) => rm(join(directory, name), { force: true })));
185
+ return floor;
186
+ }
187
+ async function appendBoundedRows(directory, date, rows, maxBytes) {
188
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < MAX_EVENT_LINE_BYTES)
189
+ throw new Error("event sync: maxCacheBytes must be at least 1 MiB");
190
+ const day = date.toISOString().slice(0, 10);
191
+ const existing = (await readdir(directory))
192
+ .filter((name) => name.startsWith(day) && SEGMENT_PATTERN.test(name))
193
+ .sort();
194
+ let index = existing.length === 0 ? 0 : existing.length - 1;
195
+ let name = segmentName(date, index);
196
+ let size = 0;
197
+ try {
198
+ size = (await stat(join(directory, name))).size;
199
+ }
200
+ catch (error) {
201
+ if (error.code !== "ENOENT")
202
+ throw error;
203
+ }
204
+ let handle = await open(join(directory, name), "a", 0o600);
205
+ try {
206
+ for (const row of rows) {
207
+ const line = `${row.line}\n`;
208
+ const bytes = new TextEncoder().encode(line).byteLength;
209
+ if (size > 0 && size + bytes > maxBytes) {
210
+ await handle.sync();
211
+ await handle.close();
212
+ name = segmentName(date, ++index);
213
+ handle = await open(join(directory, name), "a", 0o600);
214
+ size = 0;
215
+ }
216
+ await handle.write(line);
217
+ size += bytes;
218
+ }
219
+ await handle.sync();
220
+ }
221
+ finally {
222
+ await handle.close();
223
+ }
224
+ return name;
225
+ }
226
+ function abortableSleep(ms, signal) {
227
+ return new Promise((resolve, reject) => {
228
+ if (signal.aborted) {
229
+ reject(signal.reason);
230
+ return;
231
+ }
232
+ const finish = () => {
233
+ signal.removeEventListener("abort", abort);
234
+ resolve();
235
+ };
236
+ const timer = setTimeout(finish, ms);
237
+ const abort = () => {
238
+ clearTimeout(timer);
239
+ signal.removeEventListener("abort", abort);
240
+ reject(signal.reason);
241
+ };
242
+ signal.addEventListener("abort", abort, { once: true });
243
+ });
244
+ }
245
+ export class CatalystEventSync {
246
+ options;
247
+ paths;
248
+ fetchImpl;
249
+ now;
250
+ sleeper;
251
+ lock = null;
252
+ controller = null;
253
+ running = null;
254
+ recoveredCursor = null;
255
+ floor = -1;
256
+ current = {
257
+ state: "stopped",
258
+ cursor: null,
259
+ head: null,
260
+ lastSyncAt: null,
261
+ error: null,
262
+ };
263
+ constructor(options) {
264
+ this.options = options;
265
+ this.paths = eventCachePaths(options.tenantId, options.directory);
266
+ this.fetchImpl = options.fetch ?? fetch;
267
+ this.now = options.now ?? (() => new Date());
268
+ this.sleeper = options.sleep ?? abortableSleep;
269
+ }
270
+ status() {
271
+ return { ...this.current };
272
+ }
273
+ async syncOnce(signal = new AbortController().signal) {
274
+ await mkdir(this.paths.directory, { recursive: true, mode: 0o700 });
275
+ if (!this.lock) {
276
+ this.lock = claimWriterLock(this.paths.lock, this.options.writerGuard ?? {});
277
+ this.recoveredCursor = await repairTail(this.paths.directory);
278
+ }
279
+ this.current = { ...this.current, state: "syncing", error: null };
280
+ const checkpoint = await readCursor(this.paths.cursor);
281
+ this.floor = Math.max(this.floor, checkpoint?.floor ?? -1);
282
+ let cursor = Math.max(checkpoint?.cursor ?? -1, this.recoveredCursor ?? -1, this.current.cursor ?? -1);
283
+ if (cursor < 0) {
284
+ cursor = await this.readCurrentHead(signal);
285
+ this.floor = cursor;
286
+ }
287
+ const result = await this.readPage(cursor, signal);
288
+ const now = this.now();
289
+ const maxCacheBytes = this.options.maxCacheBytes ?? DEFAULT_MAX_CACHE_BYTES;
290
+ let segment = segmentName(now);
291
+ if (result.rows.length > 0) {
292
+ segment = await appendBoundedRows(this.paths.directory, now, result.rows, maxCacheBytes);
293
+ cursor = result.rows[result.rows.length - 1].event.sequence;
294
+ this.recoveredCursor = cursor;
295
+ }
296
+ this.floor = await retainBoundedSegments(this.paths.directory, now, this.options.retainDays ?? DEFAULT_RETAIN_DAYS, maxCacheBytes, segment, this.floor);
297
+ await writeJsonAtomic(this.paths.cursor, {
298
+ version: 1,
299
+ cursor,
300
+ floor: this.floor,
301
+ });
302
+ this.current = {
303
+ state: "idle",
304
+ cursor,
305
+ head: result.head,
306
+ lastSyncAt: this.now().toISOString(),
307
+ error: null,
308
+ };
309
+ return { appended: result.rows.length, cursor, head: result.head };
310
+ }
311
+ start() {
312
+ if (this.running)
313
+ return this.running;
314
+ this.controller = new AbortController();
315
+ this.running = this.loop(this.controller.signal).finally(() => {
316
+ if (this.current.state !== "failed")
317
+ this.current = { ...this.current, state: "stopped" };
318
+ this.lock?.release();
319
+ this.lock = null;
320
+ this.recoveredCursor = null;
321
+ this.running = null;
322
+ this.controller = null;
323
+ });
324
+ return this.running;
325
+ }
326
+ async stop() {
327
+ const controller = this.controller;
328
+ if (!this.running) {
329
+ this.lock?.release();
330
+ this.lock = null;
331
+ this.current = { ...this.current, state: "stopped" };
332
+ return;
333
+ }
334
+ controller?.abort(new Error("event sync stopped"));
335
+ try {
336
+ await this.running;
337
+ }
338
+ catch (error) {
339
+ if (!controller?.signal.aborted)
340
+ throw error;
341
+ }
342
+ }
343
+ async loop(signal) {
344
+ let idle = this.options.idleMinMs ?? DEFAULT_IDLE_MIN_MS;
345
+ const maxIdle = this.options.idleMaxMs ?? DEFAULT_IDLE_MAX_MS;
346
+ try {
347
+ while (!signal.aborted) {
348
+ try {
349
+ const result = await this.syncOnce(signal);
350
+ idle =
351
+ result.appended > 0
352
+ ? (this.options.idleMinMs ?? DEFAULT_IDLE_MIN_MS)
353
+ : Math.min(maxIdle, idle * 2);
354
+ }
355
+ catch (error) {
356
+ if (error instanceof EventHistoryGapError ||
357
+ (error instanceof EventSyncHttpError && error.status < 500))
358
+ throw error;
359
+ this.current = {
360
+ ...this.current,
361
+ state: "idle",
362
+ error: error instanceof Error ? error.message : String(error),
363
+ };
364
+ idle = Math.min(maxIdle, idle * 2);
365
+ }
366
+ await this.sleeper(idle, signal);
367
+ }
368
+ }
369
+ catch (error) {
370
+ if (signal.aborted)
371
+ return;
372
+ this.current = {
373
+ ...this.current,
374
+ state: "failed",
375
+ error: error instanceof Error ? error.message : String(error),
376
+ };
377
+ throw error;
378
+ }
379
+ }
380
+ async request(since, signal) {
381
+ const timeout = AbortSignal.timeout(this.options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS);
382
+ const token = this.options.auth.kind === "token"
383
+ ? this.options.auth.token
384
+ : await this.options.auth.getToken();
385
+ return this.fetchImpl(`${this.options.baseUrl.replace(/\/$/, "")}/api/v1/events/backbone?since=${since}`, {
386
+ headers: { authorization: `Bearer ${token}` },
387
+ signal: AbortSignal.any([signal, timeout]),
388
+ });
389
+ }
390
+ async readCurrentHead(signal) {
391
+ const response = await this.request(Number.MAX_SAFE_INTEGER, signal);
392
+ if (response.status !== 409)
393
+ throw new EventSyncHttpError(response.status);
394
+ const body = (await response.json());
395
+ if (body.error !== "cursor_ahead_of_head")
396
+ throw new Error("event sync: head bootstrap contract mismatch");
397
+ return positiveInteger(body.resumeFrom, "bootstrap cursor");
398
+ }
399
+ async readPage(cursor, signal) {
400
+ const response = await this.request(cursor, signal);
401
+ if (!response.ok && response.status !== 409)
402
+ throw new EventSyncHttpError(response.status);
403
+ const head = positiveInteger(response.headers.get(HEAD_HEADER), "head header");
404
+ if (response.status === 409) {
405
+ const body = (await response.json());
406
+ throw new EventHistoryGapError("event sync: durable history has a gap", head, positiveInteger(body.resumeFrom, "resume cursor"), typeof body.reason === "string"
407
+ ? body.reason
408
+ : String(body.error ?? "cursor_refused"));
409
+ }
410
+ const rows = await readNdjson(response);
411
+ let previous = cursor;
412
+ for (const row of rows) {
413
+ if (row.event.tenantId !== this.options.tenantId)
414
+ throw new Error("event sync: tenant mismatch");
415
+ if (row.event.sequence <= previous)
416
+ throw new Error("event sync: non-monotonic sequence");
417
+ previous = row.event.sequence;
418
+ }
419
+ return { head, rows };
420
+ }
421
+ }
422
+ export async function readCachedEvents(options) {
423
+ const { directory } = eventCachePaths(options.tenantId, options.directory);
424
+ const checkpoint = await readCursor(eventCachePaths(options.tenantId, options.directory).cursor);
425
+ if (options.after !== undefined &&
426
+ checkpoint &&
427
+ options.after < checkpoint.floor)
428
+ throw new EventHistoryGapError("event cache: requested sequence precedes retained history", checkpoint.cursor, checkpoint.floor, "local-retention");
429
+ let names;
430
+ try {
431
+ names = (await readdir(directory))
432
+ .filter((name) => SEGMENT_PATTERN.test(name))
433
+ .sort();
434
+ }
435
+ catch (error) {
436
+ if (error.code === "ENOENT")
437
+ return [];
438
+ throw error;
439
+ }
440
+ const events = [];
441
+ for (const name of names) {
442
+ const body = await readFile(join(directory, name), "utf8");
443
+ const complete = body.endsWith("\n")
444
+ ? body.slice(0, -1)
445
+ : body.slice(0, body.lastIndexOf("\n") + 1);
446
+ for (const line of complete.split("\n")) {
447
+ if (!line)
448
+ continue;
449
+ const event = parseEvent(JSON.parse(line));
450
+ if (event.sequence > (options.after ?? -1))
451
+ events.push(event);
452
+ }
453
+ }
454
+ return events;
455
+ }
456
+ export async function* tailCachedEvents(options) {
457
+ const paths = eventCachePaths(options.tenantId, options.directory);
458
+ const { directory } = paths;
459
+ let cursor = options.after ?? (await readCursor(paths.cursor))?.cursor ?? -1;
460
+ const emit = async () => {
461
+ const rows = await readCachedEvents({ ...options, after: cursor });
462
+ if (rows.length > 0)
463
+ cursor = rows[rows.length - 1].sequence;
464
+ return rows;
465
+ };
466
+ const changes = watch(directory, { signal: options.signal })[Symbol.asyncIterator]();
467
+ const nextChange = () => changes.next().then((value) => ({ value }), (error) => ({ error }));
468
+ let pending = nextChange();
469
+ try {
470
+ for (const event of await emit())
471
+ yield event;
472
+ for (;;) {
473
+ const outcome = await pending;
474
+ if ("error" in outcome)
475
+ throw outcome.error;
476
+ const change = outcome.value;
477
+ if (change.done)
478
+ return;
479
+ pending = nextChange();
480
+ for (const event of await emit())
481
+ yield event;
482
+ }
483
+ }
484
+ finally {
485
+ await changes.return?.();
486
+ await pending;
487
+ }
488
+ }
489
+ export function eventIdentity(event) {
490
+ return JSON.stringify([event.tenantId, event.sequence, event.eventId]);
491
+ }
492
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,MAAM,EACN,EAAE,EACF,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EACL,eAAe,GAGhB,MAAM,0BAA0B,CAAC;AAIlC,MAAM,WAAW,GAAG,oCAAoC,CAAC;AACzD,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAClC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AACnC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,uBAAuB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAClD,MAAM,eAAe,GAAG,uCAAuC,CAAC;AAsChE,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IACA;IACA;IAJX,YACE,OAAe,EACN,IAAY,EACZ,UAAkB,EAClB,MAAc;QAEvB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAClB,WAAM,GAAN,MAAM,CAAQ;QAGvB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,kBAAmB,SAAQ,KAAK;IACf;IAArB,YAAqB,MAAc;QACjC,KAAK,CAAC,iCAAiC,MAAM,EAAE,CAAC,CAAC;QAD9B,WAAM,GAAN,MAAM,CAAQ;QAEjC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACzD,MAAM,KAAK,GACR,UAAyE;SACvE,OAAO,EAAE,GAAG,EAAE,cAAc,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxE,OAAO,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,SAAkB;IAElB,MAAM,IAAI,GAAG,SAAS,IAAI,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC/D,OAAO;QACL,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,IAAY;IACnD,IACE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;QAE3B,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,KAA+B,CAAC;IAC9C,IACE,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;QACrC,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;QAC1B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,aAAa,CAAC;QAC1C,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;QAErB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,OAAO,KAAsB,CAAC;AAChC,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,QAAkB;IAElB,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,IAAI,GAAkD,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,oBAAoB;YAClE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC;IACF,SAAS,CAAC;QACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,OAAO,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACnC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YACrC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,oBAAoB;YACvC,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,IAAI,IAAI;YAAE,MAAM;IAClB,CAAC;IACD,IAAI,OAAO;QAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,IAAU,EAAE,KAAK,GAAG,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,OAAO,KAAK,KAAK,CAAC;QAChB,CAAC,CAAC,GAAG,GAAG,QAAQ;QAChB,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,KAAc;IACzD,MAAM,GAAG,GAAI,UAA6C,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,GAAG,MAAM,CAAC;IACvC,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAOD,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAEpD,CAAC;QACF,OAAO,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;YACrC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC;YAClC,KAAK,CAAC,MAAM,IAAI,CAAC;YACjB,CAAC,CAAC;gBACE,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EACH,OAAQ,KAA6B,CAAC,KAAK,KAAK,QAAQ;oBACxD,MAAM,CAAC,aAAa,CAAE,KAA2B,CAAC,KAAK,CAAC;oBACtD,CAAC,CAAE,KAA2B,CAAC,KAAK;oBACpC,CAAC,CAAC,CAAC,CAAC;aACT;YACH,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA2B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAChE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,SAAiB;IACzC,MAAM,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC5C,IAAI,EAAE,CAAC;IACV,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACjC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC1C,IAAI,WAAW,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;YAClC,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,KAAK;aACnB,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;aAC9C,QAAQ,CAAC,MAAM,CAAC;aAChB,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5D,IAAI,IAAI;YAAE,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACzD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,SAAiB,EACjB,GAAS,EACT,UAAkB,EAClB,QAAgB,EAChB,OAAe,EACf,KAAa;IAEb,MAAM,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC5C,IAAI,EAAE,CAAC;IACV,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,QAAQ;QACzB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,OAAO;YAAE,SAAS;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,IAAI,KAAK,IAAI,QAAQ;YAAE,SAAS;QAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,IAAI;YAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,CACf,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CACjE,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,SAAiB,EACjB,IAAU,EACV,IAA6B,EAC7B,QAAgB;IAEhB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,oBAAoB;QACpE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACpE,IAAI,EAAE,CAAC;IACV,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5D,IAAI,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACpC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA2B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;IAClE,CAAC;IACD,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC;YAC7B,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;YACxD,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,GAAG,QAAQ,EAAE,CAAC;gBACxC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBACpB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;gBACrB,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACvD,IAAI,GAAG,CAAC,CAAC;YACX,CAAC;YACD,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC;QACD,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,EAAU,EAAE,MAAmB;IACrD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,EAAE;YAClB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACrC,MAAM,KAAK,GAAG,GAAG,EAAE;YACjB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,iBAAiB;IAkBC;IAjBpB,KAAK,CAAkB;IACf,SAAS,CAAe;IACxB,GAAG,CAAa;IAChB,OAAO,CAAqD;IACrE,IAAI,GAA4B,IAAI,CAAC;IACrC,UAAU,GAA2B,IAAI,CAAC;IAC1C,OAAO,GAAyB,IAAI,CAAC;IACrC,eAAe,GAAkB,IAAI,CAAC;IACtC,KAAK,GAAG,CAAC,CAAC,CAAC;IACX,OAAO,GAAoB;QACjC,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,IAAI;KACZ,CAAC;IAEF,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;QACpD,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC;IACjD,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,SAAsB,IAAI,eAAe,EAAE,CAAC,MAAM;QAElD,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,IAAI,GAAG,eAAe,CACzB,IAAI,CAAC,KAAK,CAAC,IAAI,EACf,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAC/B,CAAC;YACF,IAAI,CAAC,eAAe,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAClE,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CACnB,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC,EACxB,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,EAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAC1B,CAAC;QACF,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QACtB,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;QAC5E,IAAI,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,GAAG,MAAM,iBAAiB,CAC/B,IAAI,CAAC,KAAK,CAAC,SAAS,EACpB,GAAG,EACH,MAAM,CAAC,IAAI,EACX,aAAa,CACd,CAAC;YACF,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC7D,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC;QAChC,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,MAAM,qBAAqB,CACtC,IAAI,CAAC,KAAK,CAAC,SAAS,EACpB,GAAG,EACH,IAAI,CAAC,OAAO,CAAC,UAAU,IAAI,mBAAmB,EAC9C,aAAa,EACb,OAAO,EACP,IAAI,CAAC,KAAK,CACX,CAAC;QACF,MAAM,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACvC,OAAO,EAAE,CAAC;YACV,MAAM;YACN,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,GAAG;YACb,KAAK,EAAE,MAAM;YACb,MAAM;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;YACpC,KAAK,EAAE,IAAI;SACZ,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACrE,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YAC5D,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ;gBACjC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QACD,UAAU,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO;gBAAE,MAAM,KAAK,CAAC;QAC/C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,MAAmB;QACpC,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,mBAAmB,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,mBAAmB,CAAC;QAC9D,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAC3C,IAAI;wBACF,MAAM,CAAC,QAAQ,GAAG,CAAC;4BACjB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,mBAAmB,CAAC;4BACjD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IACE,KAAK,YAAY,oBAAoB;wBACrC,CAAC,KAAK,YAAY,kBAAkB,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;wBAE3D,MAAM,KAAK,CAAC;oBACd,IAAI,CAAC,OAAO,GAAG;wBACb,GAAG,IAAI,CAAC,OAAO;wBACf,KAAK,EAAE,MAAM;wBACb,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC9D,CAAC;oBACF,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gBACrC,CAAC;gBACD,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO;YAC3B,IAAI,CAAC,OAAO,GAAG;gBACb,GAAG,IAAI,CAAC,OAAO;gBACf,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC;YACF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,MAAmB;QACtD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CACjC,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAC5D,CAAC;QACF,MAAM,KAAK,GACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO;YAChC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;YACzB,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,SAAS,CACnB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,iCAAiC,KAAK,EAAE,EAClF;YACE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;YAC7C,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAC3C,CACF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,MAAmB;QAC/C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACrE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;QAChE,IAAI,IAAI,CAAC,KAAK,KAAK,sBAAsB;YACvC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IAC9D,CAAC;IAEO,KAAK,CAAC,QAAQ,CACpB,MAAc,EACd,MAAmB;QAKnB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YACzC,MAAM,IAAI,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,eAAe,CAC1B,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EACjC,aAAa,CACd,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;YAChE,MAAM,IAAI,oBAAoB,CAC5B,uCAAuC,EACvC,IAAI,EACJ,eAAe,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,EACjD,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;gBAC7B,CAAC,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAC3C,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,QAAQ,GAAG,MAAM,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ;gBAC9C,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YACjD,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,QAAQ;gBAChC,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChC,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;CACF;AAQD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgC;IAEhC,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,MAAM,UAAU,CACjC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAC5D,CAAC;IACF,IACE,OAAO,CAAC,KAAK,KAAK,SAAS;QAC3B,UAAU;QACV,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK;QAEhC,MAAM,IAAI,oBAAoB,CAC5B,2DAA2D,EAC3D,UAAU,CAAC,MAAM,EACjB,UAAU,CAAC,KAAK,EAChB,iBAAiB,CAClB,CAAC;IACJ,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;aAC/B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC5C,IAAI,EAAE,CAAC;IACZ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA2B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAC9D,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3C,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,gBAAgB,CACrC,OAA0D;IAE1D,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACnE,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,IAAI,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,MAAM,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;QACtB,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,QAAQ,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAC1D,MAAM,CAAC,aAAa,CACrB,EAAE,CAAC;IACJ,MAAM,UAAU,GAAG,GAAG,EAAE,CACtB,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CACjB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EACtB,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAChC,CAAC;IACJ,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE;YAAE,MAAM,KAAK,CAAC;QAC9C,SAAS,CAAC;YACR,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;YAC9B,IAAI,OAAO,IAAI,OAAO;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC;YAC5C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;YAC7B,IAAI,MAAM,CAAC,IAAI;gBAAE,OAAO;YACxB,OAAO,GAAG,UAAU,EAAE,CAAC;YACvB,KAAK,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE;gBAAE,MAAM,KAAK,CAAC;QAChD,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAoB;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACzE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catalyst-cloud/sdk",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Keep a live local copy of your Linear and GitHub project data — pushed in real time, without polling rate limits or webhook tunnels.",
5
5
  "license": "MIT",
6
6
  "author": "Coalesce Labs",
@@ -39,6 +39,11 @@
39
39
  "types": "./dist/node.d.ts",
40
40
  "import": "./dist/node.js",
41
41
  "default": "./dist/node.js"
42
+ },
43
+ "./events": {
44
+ "types": "./dist/events.d.ts",
45
+ "import": "./dist/events.js",
46
+ "default": "./dist/events.js"
42
47
  }
43
48
  },
44
49
  "files": [