@evelinka-ai/core 0.1.6 → 0.3.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 (77) hide show
  1. package/dist/agent-lib/managed-tool.d.ts +13 -1
  2. package/dist/agent-lib/managed-tool.d.ts.map +1 -1
  3. package/dist/agent-lib/managed-tool.js +20 -1
  4. package/dist/agent-lib/managed-tool.js.map +1 -1
  5. package/dist/channels/model-catalog.d.ts.map +1 -1
  6. package/dist/channels/model-catalog.js +4 -1
  7. package/dist/channels/model-catalog.js.map +1 -1
  8. package/dist/channels/model-providers.d.ts +33 -0
  9. package/dist/channels/model-providers.d.ts.map +1 -0
  10. package/dist/channels/model-providers.js +86 -0
  11. package/dist/channels/model-providers.js.map +1 -0
  12. package/dist/channels/providers.d.ts +41 -0
  13. package/dist/channels/providers.d.ts.map +1 -0
  14. package/dist/channels/providers.js +168 -0
  15. package/dist/channels/providers.js.map +1 -0
  16. package/dist/lib/budgets/api-keys.d.ts +15 -0
  17. package/dist/lib/budgets/api-keys.d.ts.map +1 -0
  18. package/dist/lib/budgets/api-keys.js +83 -0
  19. package/dist/lib/budgets/api-keys.js.map +1 -0
  20. package/dist/lib/budgets/prepaid-call.d.ts +46 -0
  21. package/dist/lib/budgets/prepaid-call.d.ts.map +1 -0
  22. package/dist/lib/budgets/prepaid-call.js +32 -0
  23. package/dist/lib/budgets/prepaid-call.js.map +1 -0
  24. package/dist/lib/budgets/prepaid-response-store.d.ts +17 -0
  25. package/dist/lib/budgets/prepaid-response-store.d.ts.map +1 -0
  26. package/dist/lib/budgets/prepaid-response-store.js +85 -0
  27. package/dist/lib/budgets/prepaid-response-store.js.map +1 -0
  28. package/dist/lib/coordination/checkpoints.d.ts +33 -0
  29. package/dist/lib/coordination/checkpoints.d.ts.map +1 -0
  30. package/dist/lib/coordination/checkpoints.js +105 -0
  31. package/dist/lib/coordination/checkpoints.js.map +1 -0
  32. package/dist/lib/coordination/head-lease.d.ts +91 -0
  33. package/dist/lib/coordination/head-lease.d.ts.map +1 -0
  34. package/dist/lib/coordination/head-lease.js +402 -0
  35. package/dist/lib/coordination/head-lease.js.map +1 -0
  36. package/dist/lib/coordination/pg.d.ts +30 -0
  37. package/dist/lib/coordination/pg.d.ts.map +1 -0
  38. package/dist/lib/coordination/pg.js +52 -0
  39. package/dist/lib/coordination/pg.js.map +1 -0
  40. package/dist/lib/coordination/reconciler.d.ts +156 -0
  41. package/dist/lib/coordination/reconciler.d.ts.map +1 -0
  42. package/dist/lib/coordination/reconciler.js +287 -0
  43. package/dist/lib/coordination/reconciler.js.map +1 -0
  44. package/dist/lib/coordination/work-queue.d.ts +81 -0
  45. package/dist/lib/coordination/work-queue.d.ts.map +1 -0
  46. package/dist/lib/coordination/work-queue.js +305 -0
  47. package/dist/lib/coordination/work-queue.js.map +1 -0
  48. package/dist/lib/media/webp.d.ts +8 -0
  49. package/dist/lib/media/webp.d.ts.map +1 -0
  50. package/dist/lib/media/webp.js +15 -0
  51. package/dist/lib/media/webp.js.map +1 -0
  52. package/dist/lib/models/custom-providers.d.ts +44 -0
  53. package/dist/lib/models/custom-providers.d.ts.map +1 -0
  54. package/dist/lib/models/custom-providers.js +183 -0
  55. package/dist/lib/models/custom-providers.js.map +1 -0
  56. package/dist/lib/models/model-catalog.d.ts.map +1 -1
  57. package/dist/lib/models/model-catalog.js +2 -1
  58. package/dist/lib/models/model-catalog.js.map +1 -1
  59. package/dist/lib/models/model-config.d.ts +5 -1
  60. package/dist/lib/models/model-config.d.ts.map +1 -1
  61. package/dist/lib/models/model-config.js +37 -8
  62. package/dist/lib/models/model-config.js.map +1 -1
  63. package/dist/lib/observability/event-bus.d.ts +1 -0
  64. package/dist/lib/observability/event-bus.d.ts.map +1 -1
  65. package/dist/lib/observability/event-bus.js.map +1 -1
  66. package/dist/lib/observability/recorder-hook.d.ts +1 -0
  67. package/dist/lib/observability/recorder-hook.d.ts.map +1 -1
  68. package/dist/lib/observability/recorder-hook.js +2 -2
  69. package/dist/lib/observability/recorder-hook.js.map +1 -1
  70. package/dist/lib/observability/recorder.d.ts +28 -0
  71. package/dist/lib/observability/recorder.d.ts.map +1 -1
  72. package/dist/lib/observability/recorder.js +123 -34
  73. package/dist/lib/observability/recorder.js.map +1 -1
  74. package/dist/tenant.d.ts +12 -0
  75. package/dist/tenant.d.ts.map +1 -1
  76. package/dist/tenant.js.map +1 -1
  77. package/package.json +47 -2
@@ -0,0 +1,156 @@
1
+ import { type LeaseRow, type ReapResult } from "./head-lease.js";
2
+ import type { DeferOpts, QuarantineOpts } from "./work-queue.js";
3
+ export declare const UNCONFIRMED_GRACE_MS: number;
4
+ export declare const CLOSED_TOMBSTONE_TTL_MS: number;
5
+ export declare const CLAIM_ROUNDS_PER_PASS = 5;
6
+ export declare const CLAIM_ROWS_PER_PASS = 30;
7
+ export declare const TRANSIENT_BACKOFF_MS = 60000;
8
+ export type TargetState = {
9
+ kind: "open";
10
+ head: string | null;
11
+ } | {
12
+ kind: "closed";
13
+ } | {
14
+ kind: "missing";
15
+ } | {
16
+ kind: "invisible";
17
+ } | {
18
+ kind: "unavailable";
19
+ };
20
+ export type DispatchOutcome = "dispatched" | "deduped" | "queued" | "refused";
21
+ export interface ReconcilerSettings {
22
+ cadenceMs: number;
23
+ dispatchCap: number;
24
+ restartBudget: number;
25
+ quarantineMs: number;
26
+ settleMs: number;
27
+ }
28
+ export interface ReconcilerQueue<K, Item extends QueueItem<K>, Reason extends string> {
29
+ claimDue(limit: number): Promise<Item[]>;
30
+ list(): Promise<Item[] | null>;
31
+ read(key: K): Promise<Item | null | undefined>;
32
+ upsert(item: K & {
33
+ targetHead: string;
34
+ baseHead?: string | null;
35
+ reason: Reason;
36
+ countAttempt?: boolean;
37
+ lastError?: string | null;
38
+ }): Promise<boolean>;
39
+ complete(key: K, head: string | null): Promise<boolean>;
40
+ defer(key: K, opts: DeferOpts<Reason>): Promise<string | null>;
41
+ quarantine(key: K, opts: QuarantineOpts): Promise<string | null>;
42
+ }
43
+ export type QueueItem<K> = K & {
44
+ targetHead: string;
45
+ baseHead: string | null;
46
+ reason: string;
47
+ attempts: number;
48
+ };
49
+ export interface LostHead<K> {
50
+ key: K;
51
+ head: string;
52
+ name: string;
53
+ lease: LeaseRow;
54
+ genuine: boolean;
55
+ counted: boolean;
56
+ nextAttemptAt: string;
57
+ readAttempts: () => Promise<number | null>;
58
+ }
59
+ export interface UnconfirmedHead<K> {
60
+ key: K | null;
61
+ head: string;
62
+ base: string | null;
63
+ at: string;
64
+ }
65
+ export interface ReconcilerPolicy<K, Item extends QueueItem<K>, Reason extends string, D, U extends UnconfirmedHead<K> = UnconfirmedHead<K>> {
66
+ now(): number;
67
+ settings(): ReconcilerSettings;
68
+ queue: ReconcilerQueue<K, Item, Reason>;
69
+ leases: {
70
+ reap(): Promise<LeaseRow[] | ReapResult>;
71
+ list(): Promise<LeaseRow[] | null>;
72
+ };
73
+ keys: {
74
+ fromLease(itemKey: string): K | null;
75
+ toLease(key: K, head: string): string;
76
+ id(key: K): string;
77
+ of(item: Item): K;
78
+ };
79
+ reasons: {
80
+ restart: Reason;
81
+ refused: Reason;
82
+ reconcile: Reason;
83
+ successor: Reason;
84
+ external: ReadonlySet<Reason>;
85
+ };
86
+ lost: {
87
+ requeued(info: LostHead<K>): Promise<void>;
88
+ quarantined(info: LostHead<K> & {
89
+ attempts: number;
90
+ until: string | null;
91
+ }): Promise<void>;
92
+ budgetExhausted(info: {
93
+ attempts: number;
94
+ budget: number;
95
+ head: string;
96
+ genuine: boolean;
97
+ }): string;
98
+ };
99
+ recovery: {
100
+ candidates(): Promise<Array<{
101
+ key: K | null;
102
+ head: string;
103
+ finish(): Promise<boolean>;
104
+ }>>;
105
+ };
106
+ unconfirmed: {
107
+ list(): U[];
108
+ maxAgeMs: number;
109
+ settled(u: U & {
110
+ key: K;
111
+ }): Promise<boolean>;
112
+ requeued(u: U & {
113
+ key: K;
114
+ }, nextAttemptAt: string): Promise<void>;
115
+ };
116
+ items: {
117
+ name(key: K): string | null;
118
+ state(name: string, key: K): Promise<TargetState>;
119
+ confirmedHead(name: string, key: K): string | null;
120
+ forget(name: string, key: K): boolean;
121
+ invisible(name: string, key: K, head: string, until: string | null): Promise<void>;
122
+ tombstoned(name: string, key: K, kind: "closed" | "missing"): Promise<void>;
123
+ toDispatch(item: Item, name: string): D;
124
+ dispatch(d: D): Promise<{
125
+ outcome: DispatchOutcome;
126
+ }>;
127
+ texts: {
128
+ noName: string;
129
+ invisible: string;
130
+ closed: string;
131
+ missing: string;
132
+ };
133
+ };
134
+ sweeps: Record<string, () => Promise<number>>;
135
+ }
136
+ export interface ReconcilerCounters {
137
+ skipped: boolean;
138
+ reaped: number;
139
+ requeued: number;
140
+ quarantined: number;
141
+ tombstoned: number;
142
+ dispatched: number;
143
+ deferred: number;
144
+ swept: Record<string, number>;
145
+ recovered: number;
146
+ deferredReap: number;
147
+ tombstoneDeferred: number;
148
+ recoverySkipped: boolean;
149
+ unconfirmedSkipped: boolean;
150
+ }
151
+ export interface ReconcilerState {
152
+ lastPassAt: number;
153
+ }
154
+ export declare const createReconcilerState: () => ReconcilerState;
155
+ export declare function runReconcilerPass<K, Item extends QueueItem<K>, Reason extends string, D, U extends UnconfirmedHead<K>>(policy: ReconcilerPolicy<K, Item, Reason, D, U>, state: ReconcilerState): Promise<ReconcilerCounters>;
156
+ //# sourceMappingURL=reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciler.d.ts","sourceRoot":"","sources":["../../../src/lib/coordination/reconciler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,287 @@
1
+ import { logger } from "../observability/logger.js";
2
+ import { splitLeaseKey } from "./head-lease.js";
3
+ const log = logger.child({ module: "reconciler" });
4
+ export const UNCONFIRMED_GRACE_MS = 3 * 60_000;
5
+ export const CLOSED_TOMBSTONE_TTL_MS = 30 * 24 * 3_600_000;
6
+ export const CLAIM_ROUNDS_PER_PASS = 5;
7
+ export const CLAIM_ROWS_PER_PASS = 30;
8
+ export const TRANSIENT_BACKOFF_MS = 60_000;
9
+ export const createReconcilerState = () => ({ lastPassAt: 0 });
10
+ export async function runReconcilerPass(policy, state) {
11
+ const result = {
12
+ skipped: false,
13
+ reaped: 0,
14
+ requeued: 0,
15
+ quarantined: 0,
16
+ tombstoned: 0,
17
+ dispatched: 0,
18
+ deferred: 0,
19
+ swept: {},
20
+ recovered: 0,
21
+ deferredReap: 0,
22
+ tombstoneDeferred: 0,
23
+ recoverySkipped: false,
24
+ unconfirmedSkipped: false,
25
+ };
26
+ const cfg = policy.settings();
27
+ const now = policy.now();
28
+ if (now - state.lastPassAt < cfg.cadenceMs) {
29
+ result.skipped = true;
30
+ return result;
31
+ }
32
+ state.lastPassAt = now;
33
+ const eta = (ms) => new Date(policy.now() + ms).toISOString();
34
+ const attemptsOf = async (key) => {
35
+ const row = await policy.queue.read(key);
36
+ return row ? row.attempts : null;
37
+ };
38
+ try {
39
+ const reap = await policy.leases.reap();
40
+ const reaped = Array.isArray(reap) ? reap : reap.reaped;
41
+ result.deferredReap = Array.isArray(reap) ? 0 : reap.deferred.length;
42
+ for (const lease of reaped) {
43
+ result.reaped++;
44
+ const split = splitLeaseKey(lease.key);
45
+ const key = split ? policy.keys.fromLease(split.itemKey) : null;
46
+ if (!split || key === null)
47
+ continue;
48
+ const { head } = split;
49
+ const genuine = lease.runId !== "";
50
+ const nextAttemptAt = eta(0);
51
+ const prior = genuine ? null : await policy.queue.read(key);
52
+ const repeatRefusal = !genuine &&
53
+ prior !== null &&
54
+ prior !== undefined &&
55
+ prior.targetHead === head &&
56
+ !policy.reasons.external.has(prior.reason);
57
+ const counted = genuine || repeatRefusal;
58
+ await policy.queue.upsert({
59
+ ...key,
60
+ targetHead: head,
61
+ reason: genuine ? policy.reasons.restart : policy.reasons.refused,
62
+ countAttempt: counted,
63
+ lastError: genuine
64
+ ? lease.reapReason === "stalled"
65
+ ? `run ${lease.runId.slice(0, 8)} stalled: the engine still reports it live but its lease has not renewed since ${lease.heartbeatAt} — reaped past the stall ceiling`
66
+ : `run ${lease.runId.slice(0, 8)} lost with its process (boot ${lease.bootId.slice(0, 8)}, last heartbeat ${lease.heartbeatAt})`
67
+ : "dispatched turn never started (reservation expired)",
68
+ });
69
+ result.requeued++;
70
+ const name = policy.items.name(key);
71
+ if (name === null)
72
+ continue;
73
+ const info = {
74
+ key,
75
+ head,
76
+ name,
77
+ lease,
78
+ genuine,
79
+ counted,
80
+ nextAttemptAt,
81
+ readAttempts: () => attemptsOf(key),
82
+ };
83
+ await policy.lost.requeued(info);
84
+ if (counted) {
85
+ const attempts = await attemptsOf(key);
86
+ if (attempts !== null && attempts > cfg.restartBudget) {
87
+ const until = await policy.queue.quarantine(key, {
88
+ reason: policy.lost.budgetExhausted({
89
+ attempts,
90
+ budget: cfg.restartBudget,
91
+ head,
92
+ genuine,
93
+ }),
94
+ ttlMs: cfg.quarantineMs,
95
+ });
96
+ result.quarantined++;
97
+ await policy.lost.quarantined({ ...info, attempts, until });
98
+ }
99
+ }
100
+ }
101
+ }
102
+ catch (err) {
103
+ log.error({ err }, "reconciler: lease reap pass failed");
104
+ }
105
+ const leaseRows = await policy.leases.list();
106
+ const leaseKeys = new Set((leaseRows ?? []).map((l) => l.key));
107
+ try {
108
+ if (leaseRows === null) {
109
+ result.recoverySkipped = true;
110
+ log.warn("reconciler: lease inventory unavailable — recovery pass skipped");
111
+ }
112
+ for (const c of leaseRows === null ? [] : await policy.recovery.candidates()) {
113
+ if (c.key === null)
114
+ continue;
115
+ if (leaseKeys.has(policy.keys.toLease(c.key, c.head)))
116
+ continue;
117
+ if (await c.finish())
118
+ result.recovered++;
119
+ }
120
+ }
121
+ catch (err) {
122
+ log.error({ err }, "reconciler: recovered-run pass failed");
123
+ }
124
+ try {
125
+ const work = leaseRows === null ? null : await policy.queue.list();
126
+ if (leaseRows === null || work === null) {
127
+ result.unconfirmedSkipped = true;
128
+ log.warn({ leases: leaseRows !== null, queue: work !== null }, "reconciler: inventory unavailable — unconfirmed-heads pass skipped");
129
+ }
130
+ const queued = new Set((work ?? []).map((w) => policy.keys.id(w)));
131
+ for (const u of result.unconfirmedSkipped ? [] : policy.unconfirmed.list()) {
132
+ const age = now - Date.parse(u.at);
133
+ if (!Number.isFinite(age) || age <= UNCONFIRMED_GRACE_MS)
134
+ continue;
135
+ if (age > policy.unconfirmed.maxAgeMs)
136
+ continue;
137
+ if (u.key === null)
138
+ continue;
139
+ const known = { ...u, key: u.key };
140
+ if (queued.has(policy.keys.id(u.key)))
141
+ continue;
142
+ if (leaseKeys.has(policy.keys.toLease(u.key, u.head)))
143
+ continue;
144
+ if (await policy.unconfirmed.settled(known))
145
+ continue;
146
+ await policy.queue.upsert({
147
+ ...u.key,
148
+ targetHead: u.head,
149
+ baseHead: u.base,
150
+ reason: policy.reasons.reconcile,
151
+ lastError: "dispatched head never confirmed — no live run, no queue entry",
152
+ });
153
+ result.requeued++;
154
+ await policy.unconfirmed.requeued(known, eta(0));
155
+ }
156
+ }
157
+ catch (err) {
158
+ log.error({ err }, "reconciler: unconfirmed-head pass failed");
159
+ }
160
+ for (const [name, sweep] of Object.entries(policy.sweeps)) {
161
+ try {
162
+ result.swept[name] = await sweep();
163
+ }
164
+ catch (err) {
165
+ result.swept[name] = 0;
166
+ log.error({ err, sweep: name }, "reconciler: sweep failed");
167
+ }
168
+ }
169
+ let attempts = 0;
170
+ let rows = 0;
171
+ for (let round = 0; round < CLAIM_ROUNDS_PER_PASS; round++) {
172
+ const want = Math.min(cfg.dispatchCap - attempts, CLAIM_ROWS_PER_PASS - rows);
173
+ if (want <= 0)
174
+ break;
175
+ let items = [];
176
+ try {
177
+ items = await policy.queue.claimDue(want);
178
+ }
179
+ catch (err) {
180
+ log.error({ err }, "reconciler: claiming due work failed");
181
+ break;
182
+ }
183
+ if (!items.length)
184
+ break;
185
+ rows += items.length;
186
+ for (const item of items) {
187
+ attempts += await handleItem(policy, cfg, item, result);
188
+ }
189
+ if (items.length < want)
190
+ break;
191
+ }
192
+ return result;
193
+ }
194
+ async function handleItem(policy, cfg, item, result) {
195
+ const { queue, items } = policy;
196
+ const key = policy.keys.of(item);
197
+ let attempted = false;
198
+ try {
199
+ const name = items.name(key);
200
+ if (!name) {
201
+ await queue.quarantine(key, { reason: items.texts.noName, ttlMs: cfg.quarantineMs });
202
+ result.quarantined++;
203
+ return 0;
204
+ }
205
+ const target = await items.state(name, key);
206
+ if (target.kind === "unavailable") {
207
+ await queue.defer(key, {
208
+ reason: item.reason,
209
+ backoffMs: TRANSIENT_BACKOFF_MS,
210
+ error: "target lookup unavailable",
211
+ });
212
+ result.deferred++;
213
+ return 0;
214
+ }
215
+ if (target.kind === "invisible") {
216
+ const until = await queue.quarantine(key, {
217
+ reason: items.texts.invisible,
218
+ ttlMs: cfg.quarantineMs,
219
+ });
220
+ result.quarantined++;
221
+ await items.invisible(name, key, item.targetHead, until);
222
+ return 0;
223
+ }
224
+ if (target.kind === "closed" || target.kind === "missing") {
225
+ const parkedUntil = await queue.quarantine(key, {
226
+ reason: target.kind === "closed" ? items.texts.closed : items.texts.missing,
227
+ ttlMs: CLOSED_TOMBSTONE_TTL_MS,
228
+ });
229
+ const marked = items.forget(name, key);
230
+ if (parkedUntil === null || !marked) {
231
+ log.warn({ name, parkedUntil, marked }, "closed tombstone did not persist — deferred");
232
+ await queue.defer(key, {
233
+ reason: item.reason,
234
+ backoffMs: TRANSIENT_BACKOFF_MS,
235
+ error: "closed tombstone not persisted",
236
+ });
237
+ result.tombstoneDeferred++;
238
+ return 0;
239
+ }
240
+ result.tombstoned++;
241
+ await items.tombstoned(name, key, target.kind);
242
+ return 0;
243
+ }
244
+ const head = target.head ?? item.targetHead;
245
+ if (head !== item.targetHead) {
246
+ await queue.upsert({
247
+ ...key,
248
+ targetHead: head,
249
+ baseHead: item.baseHead,
250
+ reason: policy.reasons.reconcile,
251
+ });
252
+ }
253
+ const confirmed = items.confirmedHead(name, key);
254
+ if (confirmed === head) {
255
+ await queue.complete(key, head);
256
+ return 0;
257
+ }
258
+ const d = items.toDispatch({ ...item, targetHead: head, baseHead: item.baseHead ?? confirmed }, name);
259
+ attempted = true;
260
+ const r = await items.dispatch(d);
261
+ if (r.outcome === "dispatched" || r.outcome === "deduped") {
262
+ await queue.complete(key, head);
263
+ result.dispatched += r.outcome === "dispatched" ? 1 : 0;
264
+ }
265
+ else if (r.outcome === "queued") {
266
+ await queue.defer(key, { reason: policy.reasons.successor, backoffMs: cfg.settleMs });
267
+ result.deferred++;
268
+ }
269
+ else {
270
+ result.deferred++;
271
+ }
272
+ return 1;
273
+ }
274
+ catch (err) {
275
+ log.error({ err, item: policy.keys.id(key) }, "reconciler: work item failed");
276
+ await queue
277
+ .defer(key, {
278
+ reason: item.reason,
279
+ backoffMs: TRANSIENT_BACKOFF_MS,
280
+ error: String(err),
281
+ })
282
+ .catch(() => null);
283
+ result.deferred++;
284
+ return attempted ? 1 : 0;
285
+ }
286
+ }
287
+ //# sourceMappingURL=reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["../../../src/lib/coordination/reconciler.ts"],"names":[],"mappings":"AA+CA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAkC,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;AAInD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,MAAM,CAAC;AAK/C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;AAI3D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAmL3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAEhF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAOrC,MAA+C,EAC/C,KAAsB;IAEtB,MAAM,MAAM,GAAuB;QACjC,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,CAAC;QACT,QAAQ,EAAE,CAAC;QACX,WAAW,EAAE,CAAC;QACd,UAAU,EAAE,CAAC;QACb,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,CAAC;QACX,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,CAAC;QACZ,YAAY,EAAE,CAAC;QACf,iBAAiB,EAAE,CAAC;QACpB,eAAe,EAAE,KAAK;QACtB,kBAAkB,EAAE,KAAK;KAC1B,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,UAAU,GAAG,GAAG,CAAC;IAEvB,MAAM,GAAG,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9E,MAAM,UAAU,GAAG,KAAK,EAAE,GAAM,EAA0B,EAAE;QAC1D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IACnC,CAAC,CAAC;IAGF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACxD,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAChE,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,IAAI;gBAAE,SAAS;YACrC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;YACvB,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;YACnC,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5D,MAAM,aAAa,GACjB,CAAC,OAAO;gBACR,KAAK,KAAK,IAAI;gBACd,KAAK,KAAK,SAAS;gBACnB,KAAK,CAAC,UAAU,KAAK,IAAI;gBACzB,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAgB,CAAC,CAAC;YACvD,MAAM,OAAO,GAAG,OAAO,IAAI,aAAa,CAAC;YACzC,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACxB,GAAG,GAAG;gBACN,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO;gBACjE,YAAY,EAAE,OAAO;gBAIrB,SAAS,EAAE,OAAO;oBAChB,CAAC,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS;wBAC9B,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,kFAAkF,KAAK,CAAC,WAAW,kCAAkC;wBACrK,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,gCAAgC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,KAAK,CAAC,WAAW,GAAG;oBAClI,CAAC,CAAC,qDAAqD;aAC1D,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpC,IAAI,IAAI,KAAK,IAAI;gBAAE,SAAS;YAC5B,MAAM,IAAI,GAAgB;gBACxB,GAAG;gBACH,IAAI;gBACJ,IAAI;gBACJ,KAAK;gBACL,OAAO;gBACP,OAAO;gBACP,aAAa;gBACb,YAAY,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;aACpC,CAAC;YACF,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjC,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC;oBACtD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE;wBAC/C,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;4BAClC,QAAQ;4BACR,MAAM,EAAE,GAAG,CAAC,aAAa;4BACzB,IAAI;4BACJ,OAAO;yBACR,CAAC;wBACF,KAAK,EAAE,GAAG,CAAC,YAAY;qBACxB,CAAC,CAAC;oBACH,MAAM,CAAC,WAAW,EAAE,CAAC;oBACrB,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,oCAAoC,CAAC,CAAC;IAC3D,CAAC;IAGD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC;QACH,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;QAC9E,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC;YAC7E,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI;gBAAE,SAAS;YAC7B,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YAChE,IAAI,MAAM,CAAC,CAAC,MAAM,EAAE;gBAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,uCAAuC,CAAC,CAAC;IAC9D,CAAC;IAGD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACnE,IAAI,SAAS,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC;YACjC,GAAG,CAAC,IAAI,CACN,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,EACpD,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3E,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,oBAAoB;gBAAE,SAAS;YACnE,IAAI,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ;gBAAE,SAAS;YAChD,IAAI,CAAC,CAAC,GAAG,KAAK,IAAI;gBAAE,SAAS;YAC7B,MAAM,KAAK,GAAmB,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YACnD,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAAE,SAAS;YAChD,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YAChE,IAAI,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,SAAS;YACtD,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;gBACxB,GAAG,CAAC,CAAC,GAAG;gBACR,UAAU,EAAE,CAAC,CAAC,IAAI;gBAClB,QAAQ,EAAE,CAAC,CAAC,IAAI;gBAChB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;gBAChC,SAAS,EAAE,+DAA+D;aAC3E,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,0CAA0C,CAAC,CAAC;IACjE,CAAC;IAGD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,EAAE,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACvB,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,0BAA0B,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAMD,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,qBAAqB,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,GAAG,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC,CAAC;QAC9E,IAAI,IAAI,IAAI,CAAC;YAAE,MAAM;QACrB,IAAI,KAAK,GAAW,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,sCAAsC,CAAC,CAAC;YAC3D,MAAM;QACR,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,MAAM;QACzB,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;QACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,QAAQ,IAAI,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI;YAAE,MAAM;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD,KAAK,UAAU,UAAU,CACvB,MAA4C,EAC5C,GAAuB,EACvB,IAAU,EACV,MAA0B;IAE1B,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAChC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAGjC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;YACrF,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC5C,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAClC,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAgB;gBAC7B,SAAS,EAAE,oBAAoB;gBAC/B,KAAK,EAAE,2BAA2B;aACnC,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE;gBACxC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBAC7B,KAAK,EAAE,GAAG,CAAC,YAAY;aACxB,CAAC,CAAC;YACH,MAAM,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAK1D,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE;gBAC9C,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO;gBAC3E,KAAK,EAAE,uBAAuB;aAC/B,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAIpC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,6CAA6C,CAAC,CAAC;gBACvF,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE;oBACrB,MAAM,EAAE,IAAI,CAAC,MAAgB;oBAC7B,SAAS,EAAE,oBAAoB;oBAC/B,KAAK,EAAE,gCAAgC;iBACxC,CAAC,CAAC;gBACH,MAAM,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,OAAO,CAAC,CAAC;YACX,CAAC;YACD,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/C,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC;QAC5C,IAAI,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,MAAM,CAAC;gBACjB,GAAG,GAAG;gBACN,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;aACjC,CAAC,CAAC;QACL,CAAC;QACD,MAAM,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAChC,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,CACxB,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE,EACnE,IAAI,CACL,CAAC;QACF,SAAS,GAAG,IAAI,CAAC;QACjB,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1D,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;aAAM,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtF,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,8BAA8B,CAAC,CAAC;QAC9E,MAAM,KAAK;aACR,KAAK,CAAC,GAAG,EAAE;YACV,MAAM,EAAE,IAAI,CAAC,MAAgB;YAC7B,SAAS,EAAE,oBAAoB;YAC/B,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;SACnB,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { type PgDeps, type QueryPool } from "./pg.js";
2
+ export type WorkPool = QueryPool;
3
+ export interface WorkDeps extends PgDeps {
4
+ now?: () => number;
5
+ }
6
+ export type PolicyColumns = Record<string, readonly string[]>;
7
+ type PolicyValues<P extends PolicyColumns> = {
8
+ [C in keyof P]: P[C][number] | null;
9
+ };
10
+ export interface WorkQueueConfig<M extends Record<string, string>, P extends PolicyColumns, Reason extends string> {
11
+ table: string;
12
+ key: M;
13
+ policy?: P;
14
+ reasons: {
15
+ initial: Reason;
16
+ tombstone: Reason;
17
+ replaySafe: ReadonlySet<Reason>;
18
+ };
19
+ ledgerTtlMs?: number;
20
+ claimWindowMs?: number;
21
+ }
22
+ export type KeyOf<M extends Record<string, string>> = {
23
+ [F in keyof M]: number;
24
+ };
25
+ export type WorkItem<K, Reason extends string, P extends PolicyColumns> = K & PolicyValues<P> & {
26
+ targetHead: string;
27
+ baseHead: string | null;
28
+ reason: Reason;
29
+ nextAt: string;
30
+ attempts: number;
31
+ lastError: string | null;
32
+ quarantinedUntil: string | null;
33
+ quarantineReason: string | null;
34
+ dispatchedHead: string | null;
35
+ eventAt: string | null;
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ };
39
+ export type UpsertInput<K, Reason extends string, P extends PolicyColumns> = K & Partial<PolicyValues<P>> & {
40
+ targetHead: string;
41
+ baseHead?: string | null;
42
+ reason: Reason;
43
+ nextAt?: string;
44
+ countAttempt?: boolean;
45
+ lastError?: string | null;
46
+ eventAt?: string | null;
47
+ };
48
+ export interface ReadWorkOpts {
49
+ includeDispatched?: boolean;
50
+ }
51
+ export interface DeferOpts<Reason extends string> {
52
+ reason: Reason;
53
+ backoffMs: number;
54
+ countAttempt?: boolean;
55
+ error?: string | null;
56
+ }
57
+ export interface QuarantineOpts {
58
+ reason: string;
59
+ ttlMs: number;
60
+ }
61
+ export declare const DISPATCHED_LEDGER_TTL_MS: number;
62
+ export declare const CLAIM_WINDOW_MS = 90000;
63
+ export interface WorkQueue<K, Reason extends string, P extends PolicyColumns> {
64
+ readonly table: string;
65
+ readonly ledgerTtlMs: number;
66
+ readonly claimWindowMs: number;
67
+ ensureSchema(p: QueryPool): Promise<void>;
68
+ upsert(item: UpsertInput<K, Reason, P>, deps?: WorkDeps): Promise<boolean>;
69
+ read(key: K, deps?: WorkDeps, opts?: ReadWorkOpts): Promise<WorkItem<K, Reason, P> | null | undefined>;
70
+ list(deps?: WorkDeps, opts?: ReadWorkOpts): Promise<WorkItem<K, Reason, P>[] | null>;
71
+ claimDue(limit: number, deps?: WorkDeps): Promise<WorkItem<K, Reason, P>[]>;
72
+ complete(key: K, head: string | null, deps?: WorkDeps): Promise<boolean>;
73
+ defer(key: K, opts: DeferOpts<Reason>, deps?: WorkDeps): Promise<string | null>;
74
+ quarantine(key: K, opts: QuarantineOpts, deps?: WorkDeps): Promise<string | null>;
75
+ purgeDispatched(ttlMs?: number, deps?: WorkDeps): Promise<number>;
76
+ tombstone(key: K, head: string, opts: QuarantineOpts, deps?: WorkDeps): Promise<boolean>;
77
+ clearQuarantine(key: K, deps?: WorkDeps): Promise<boolean | null>;
78
+ }
79
+ export declare function defineWorkQueue<M extends Record<string, string>, const P extends PolicyColumns, Reason extends string>(config: WorkQueueConfig<M, P, Reason>): WorkQueue<KeyOf<M>, Reason, P>;
80
+ export {};
81
+ //# sourceMappingURL=work-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-queue.d.ts","sourceRoot":"","sources":["../../../src/lib/coordination/work-queue.ts"],"names":[],"mappings":"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"}