@emseepea/server 0.24.0 → 0.25.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 (63) hide show
  1. package/dist/events-cloud-tasks-transport.d.ts +30 -0
  2. package/dist/events-cloud-tasks-transport.d.ts.map +1 -0
  3. package/dist/events-cloud-tasks-transport.js +213 -0
  4. package/dist/events-cloud-tasks-transport.js.map +1 -0
  5. package/dist/events-google-sdk-guards.d.ts +8 -0
  6. package/dist/events-google-sdk-guards.d.ts.map +1 -0
  7. package/dist/events-google-sdk-guards.js +31 -0
  8. package/dist/events-google-sdk-guards.js.map +1 -0
  9. package/dist/events-google-sdk-lifetime.d.ts +7 -0
  10. package/dist/events-google-sdk-lifetime.d.ts.map +1 -0
  11. package/dist/events-google-sdk-lifetime.js +70 -0
  12. package/dist/events-google-sdk-lifetime.js.map +1 -0
  13. package/dist/events-google-worker-runtime.d.ts +21 -0
  14. package/dist/events-google-worker-runtime.d.ts.map +1 -0
  15. package/dist/events-google-worker-runtime.js +149 -0
  16. package/dist/events-google-worker-runtime.js.map +1 -0
  17. package/dist/events-google-worker.d.ts +4 -0
  18. package/dist/events-google-worker.d.ts.map +1 -0
  19. package/dist/events-google-worker.js +3 -0
  20. package/dist/events-google-worker.js.map +1 -0
  21. package/dist/events-postgres-delivery-migrations.d.ts +18 -0
  22. package/dist/events-postgres-delivery-migrations.d.ts.map +1 -0
  23. package/dist/events-postgres-delivery-migrations.js +146 -0
  24. package/dist/events-postgres-delivery-migrations.js.map +1 -0
  25. package/dist/events-postgres-delivery-owned.d.ts +16 -0
  26. package/dist/events-postgres-delivery-owned.d.ts.map +1 -0
  27. package/dist/events-postgres-delivery-owned.js +178 -0
  28. package/dist/events-postgres-delivery-owned.js.map +1 -0
  29. package/dist/events-postgres-delivery.d.ts +29 -0
  30. package/dist/events-postgres-delivery.d.ts.map +1 -0
  31. package/dist/events-postgres-delivery.js +299 -0
  32. package/dist/events-postgres-delivery.js.map +1 -0
  33. package/dist/events-postgres-dispatch-migrations.d.ts +19 -0
  34. package/dist/events-postgres-dispatch-migrations.d.ts.map +1 -0
  35. package/dist/events-postgres-dispatch-migrations.js +162 -0
  36. package/dist/events-postgres-dispatch-migrations.js.map +1 -0
  37. package/dist/events-postgres-dispatch.d.ts +39 -0
  38. package/dist/events-postgres-dispatch.d.ts.map +1 -0
  39. package/dist/events-postgres-dispatch.js +270 -0
  40. package/dist/events-postgres-dispatch.js.map +1 -0
  41. package/dist/events-postgres-lifecycle-migrations.d.ts +17 -0
  42. package/dist/events-postgres-lifecycle-migrations.d.ts.map +1 -0
  43. package/dist/events-postgres-lifecycle-migrations.js +125 -0
  44. package/dist/events-postgres-lifecycle-migrations.js.map +1 -0
  45. package/dist/events-postgres-lifecycle.d.ts +13 -0
  46. package/dist/events-postgres-lifecycle.d.ts.map +1 -0
  47. package/dist/events-postgres-lifecycle.js +176 -0
  48. package/dist/events-postgres-lifecycle.js.map +1 -0
  49. package/dist/events-postgres-migrations.d.ts +32 -0
  50. package/dist/events-postgres-migrations.d.ts.map +1 -0
  51. package/dist/events-postgres-migrations.js +329 -0
  52. package/dist/events-postgres-migrations.js.map +1 -0
  53. package/dist/events-postgres-owned.d.ts +16 -0
  54. package/dist/events-postgres-owned.d.ts.map +1 -0
  55. package/dist/events-postgres-owned.js +161 -0
  56. package/dist/events-postgres-owned.js.map +1 -0
  57. package/dist/events-postgres.d.ts +53 -0
  58. package/dist/events-postgres.d.ts.map +1 -0
  59. package/dist/events-postgres.js +289 -0
  60. package/dist/events-postgres.js.map +1 -0
  61. package/dist/index.js +58 -9
  62. package/dist/index.js.map +1 -1
  63. package/package.json +33 -5
@@ -0,0 +1,270 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { performance } from 'node:perf_hooks';
3
+ import { ExternalMcpEventError } from './events-external.js';
4
+ import { createDeliverySessionOwner } from './events-postgres-delivery-owned.js';
5
+ const names = ['namespace', 'source_kind', 'source_id', 'subscription_id', 'generation'];
6
+ const key = (row) => names.map(name => row[name]);
7
+ const equal = (alias) => names.map((name, i) => `${alias}.${name}=$${i + 1}`).join(' AND ');
8
+ const join = (a, b) => names.map(name => `${a}.${name}=${b}.${name}`).join(' AND ');
9
+ const dbNow = "pg_catalog.floor(EXTRACT(epoch FROM pg_catalog.clock_timestamp())*1000)::pg_catalog.float8";
10
+ const invalid = () => { throw new ExternalMcpEventError('INVALID_INPUT'); };
11
+ const validId = (value) => typeof value === 'string' && value.length > 0 && Buffer.byteLength(value) <= 240 &&
12
+ !value.includes('\u0000') && !/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(value);
13
+ const eligible = `i.state='pending' AND i.event_id=s.event_id AND s.owner_key=c.owner_key AND c.owner_key=h.owner_key
14
+ AND s.event_name=c.event_name AND h.generation=c.generation AND h.url IS NOT NULL AND c.active
15
+ AND c.expires_at>pg_catalog.clock_timestamp() AND (w.terminal IS NULL)`;
16
+ const joins = `JOIN public.emseepea_event_sources s ON s.namespace=i.namespace AND s.source_kind=i.source_kind AND s.source_id=i.source_id
17
+ JOIN public.emseepea_event_capture_subscriptions c ON c.namespace=i.namespace AND c.subscription_id=i.subscription_id AND c.generation=i.generation
18
+ JOIN public.emseepea_event_heads h ON h.namespace=i.namespace AND h.subscription_id=i.subscription_id
19
+ LEFT JOIN public.emseepea_event_delivery_state w ON ${join('w', 'i')}`;
20
+ /** Internal implementation seam; no route, provider credentials, timer or adopter callback API. */
21
+ export function createPostgresEventDispatchRuntime(options) {
22
+ const namespace = options?.namespace, transport = options?.transport, fingerprint = transport?.fingerprint;
23
+ if (!validId(namespace) ||
24
+ !options.pool || typeof options.pool.connect !== 'function' || typeof options.isPaused !== 'function' ||
25
+ typeof fingerprint !== 'string' || !/^[0-9a-f]{64}$/.test(fingerprint) ||
26
+ typeof transport.queue !== 'function' || typeof transport.inspect !== 'function' || typeof transport.create !== 'function')
27
+ invalid();
28
+ const owner = createDeliverySessionOwner(options.pool), pending = new Set();
29
+ let busy = false, closing = false;
30
+ function track(promise) {
31
+ pending.add(promise);
32
+ void promise.then(() => pending.delete(promise), () => pending.delete(promise));
33
+ return promise;
34
+ }
35
+ function paused() { const value = options.isPaused(); if (typeof value !== 'boolean')
36
+ return invalid(); return value; }
37
+ async function operation(target, input) {
38
+ const result = { selected: 0, created: 0, observed: 0, conflicts: 0, unknown: 0, deferred: 0, status: 'complete' };
39
+ if (!input?.signal || !Number.isFinite(input.deadlineMs))
40
+ return invalid();
41
+ if (target !== undefined && !validId(target))
42
+ return invalid();
43
+ if (closing)
44
+ return { ...result, status: 'stopping' };
45
+ if (busy)
46
+ return { ...result, status: 'retry_pending' };
47
+ busy = true;
48
+ const end = performance.now() + Math.min(25000, input.deadlineMs - Date.now());
49
+ function check(required = 0) {
50
+ if (closing || input.signal.aborted)
51
+ throw new ExternalMcpEventError('ABORTED');
52
+ if (paused())
53
+ throw new Error('DISPATCH_PAUSED');
54
+ if (end - performance.now() < required)
55
+ throw new ExternalMcpEventError('DEADLINE');
56
+ }
57
+ const invocation = () => ({ signal: input.signal, deadlineMs: Date.now() + Math.max(0, end - performance.now() - 1000) });
58
+ async function sql(work) {
59
+ check(5000);
60
+ return owner.run(invocation(), session => session.transaction(work));
61
+ }
62
+ async function provider(work) {
63
+ check(4000);
64
+ let timer, stop;
65
+ const controller = new AbortController(), until = Math.min(end - 1000, performance.now() + 3000);
66
+ try {
67
+ const actual = track(Promise.resolve().then(() => { check(4000); return work({ signal: controller.signal, deadlineMs: Date.now() + Math.max(0, until - performance.now()) }); }));
68
+ const value = await Promise.race([actual, new Promise((_resolve, reject) => {
69
+ timer = setTimeout(() => { controller.abort(); reject(new ExternalMcpEventError('DEADLINE')); }, Math.max(1, until - performance.now()));
70
+ stop = () => { controller.abort(); reject(new ExternalMcpEventError('ABORTED')); };
71
+ input.signal.addEventListener('abort', stop, { once: true });
72
+ if (input.signal.aborted)
73
+ stop();
74
+ })]);
75
+ check();
76
+ if (performance.now() >= until)
77
+ throw new ExternalMcpEventError('DEADLINE');
78
+ return value;
79
+ }
80
+ finally {
81
+ if (timer)
82
+ clearTimeout(timer);
83
+ if (stop)
84
+ input.signal.removeEventListener('abort', stop);
85
+ }
86
+ }
87
+ async function seed() {
88
+ await sql(async (run) => {
89
+ await run(`INSERT INTO public.emseepea_event_dispatch_state(${names.join(',')},config_hash)
90
+ SELECT ${names.map(name => `i.${name}`).join(',')},$2 FROM public.emseepea_event_intents i ${joins}
91
+ WHERE i.namespace=$1 AND ${eligible} AND ($3::pg_catalog.text IS NULL OR i.delivery_id=$3)
92
+ AND NOT EXISTS(SELECT 1 FROM public.emseepea_event_dispatch_state d WHERE ${join('d', 'i')})
93
+ ORDER BY i.delivery_id LIMIT 100 ON CONFLICT(${names.join(',')}) DO NOTHING`, [namespace, fingerprint, target ?? null]);
94
+ });
95
+ }
96
+ async function claim() {
97
+ return sql(async (run) => {
98
+ const row = (await run(`SELECT d.*,i.delivery_id FROM public.emseepea_event_dispatch_state d
99
+ JOIN public.emseepea_event_intents i ON ${join('d', 'i')}
100
+ WHERE d.namespace=$1 AND NOT d.terminal AND d.due_at<=pg_catalog.clock_timestamp()
101
+ AND (d.lease_until IS NULL OR d.lease_until<=pg_catalog.clock_timestamp())
102
+ AND ($2::pg_catalog.text IS NULL OR i.delivery_id=$2)
103
+ ORDER BY d.due_at,i.delivery_id FOR UPDATE OF d SKIP LOCKED LIMIT 1`, [namespace, target ?? null])).rows[0];
104
+ if (!row)
105
+ return null;
106
+ if (names.some(name => typeof row[name] !== 'string') || typeof row.delivery_id !== 'string' || !Number.isInteger(row.transport_generation) ||
107
+ Number(row.transport_generation) < 0 || Number(row.transport_generation) > 2147483646 || !Number.isInteger(row.recovery_count) ||
108
+ typeof row.config_hash !== 'string')
109
+ throw new ExternalMcpEventError('UNAVAILABLE');
110
+ const lease = randomUUID();
111
+ await run(`UPDATE public.emseepea_event_dispatch_state d SET lease_id=$6,lease_until=pg_catalog.clock_timestamp()+interval '30 seconds',
112
+ recovery_count=CASE WHEN recovery_count<2147483647 THEN recovery_count+1 ELSE recovery_count END,
113
+ due_at=pg_catalog.clock_timestamp()+pg_catalog.make_interval(secs=>(CASE WHEN recovery_count>=6 THEN 60 ELSE pg_catalog.power(2,recovery_count)::pg_catalog.int4 END)::pg_catalog.float8)
114
+ WHERE ${equal('d')}`, [...key(row), lease]);
115
+ row.lease_id = lease;
116
+ const fresh = (await run(`SELECT ${eligible} AS eligible,${dbNow} AS now,
117
+ pg_catalog.ceil(EXTRACT(epoch FROM w.lease_until)*1000)::pg_catalog.float8 AS worker_lease_until,
118
+ pg_catalog.ceil(EXTRACT(epoch FROM w.due_at)*1000)::pg_catalog.float8 AS worker_due_at
119
+ FROM public.emseepea_event_intents i ${joins} WHERE ${equal('i')}`, key(row))).rows[0];
120
+ row.eligible = fresh?.eligible === true;
121
+ if (fresh) {
122
+ if (!Number.isSafeInteger(fresh.now))
123
+ throw new ExternalMcpEventError('UNAVAILABLE');
124
+ for (const name of ['worker_lease_until', 'worker_due_at'])
125
+ if (fresh[name] !== null && !Number.isSafeInteger(fresh[name]))
126
+ throw new ExternalMcpEventError('UNAVAILABLE');
127
+ const until = Math.max(Number(fresh.worker_lease_until ?? 0), Number(fresh.worker_due_at ?? 0));
128
+ row.waitUntil = until > Number(fresh.now) ? until : null;
129
+ }
130
+ else
131
+ row.waitUntil = null;
132
+ return row;
133
+ });
134
+ }
135
+ async function finish(row, category, terminal = false, deferUntil = null) {
136
+ check(5000);
137
+ const found = await sql(async (run) => (await run(`UPDATE public.emseepea_event_dispatch_state d
138
+ SET category=$8,terminal=$9,lease_id=NULL,lease_until=NULL,
139
+ due_at=CASE WHEN $12::pg_catalog.float8 IS NULL THEN due_at ELSE
140
+ GREATEST(due_at,pg_catalog.clock_timestamp()+interval '1 second',pg_catalog.to_timestamp($12::pg_catalog.float8/1000)) END
141
+ WHERE ${equal('d')} AND lease_id=$6 AND config_hash=$7 AND lease_until>pg_catalog.clock_timestamp()
142
+ AND transport_generation=$10 AND task_id IS NOT DISTINCT FROM $11 RETURNING namespace`, [...key(row), row.lease_id, row.config_hash, category, terminal, row.transport_generation, row.task_id ?? null, deferUntil])).rows);
143
+ if (found.length !== 1)
144
+ throw new ExternalMcpEventError('OUTCOME_UNKNOWN');
145
+ }
146
+ async function reserve(row) {
147
+ check(12000);
148
+ const previous = Number(row.transport_generation);
149
+ if (previous >= 2147483646)
150
+ throw new ExternalMcpEventError('UNAVAILABLE');
151
+ const generation = previous + 1, taskId = 'emseepea-' + createHash('sha256').update(JSON.stringify([fingerprint, namespace, row.delivery_id, generation])).digest('hex');
152
+ const found = await sql(async (run) => (await run(`UPDATE public.emseepea_event_dispatch_state d SET transport_generation=$8,task_id=$9,category='unknown'
153
+ WHERE ${equal('d')} AND lease_id=$6 AND config_hash=$7 AND lease_until>pg_catalog.clock_timestamp()
154
+ AND transport_generation=$10 AND task_id IS NOT DISTINCT FROM $11 RETURNING namespace`, [...key(row), row.lease_id, fingerprint, generation, taskId, previous, row.task_id ?? null])).rows);
155
+ if (found.length !== 1)
156
+ throw new ExternalMcpEventError('OUTCOME_UNKNOWN');
157
+ row.transport_generation = generation;
158
+ row.task_id = taskId;
159
+ }
160
+ try {
161
+ check(5000);
162
+ if (await provider(inv => transport.queue(inv)) !== 'present') {
163
+ result.status = 'retry_pending';
164
+ result.deferred++;
165
+ return result;
166
+ }
167
+ await seed();
168
+ while (result.selected < 100) {
169
+ check(18000);
170
+ const row = await claim();
171
+ if (!row)
172
+ break;
173
+ result.selected++;
174
+ if (row.config_hash !== fingerprint) {
175
+ await finish(row, 'conflict');
176
+ result.conflicts++;
177
+ continue;
178
+ }
179
+ if (!row.eligible) {
180
+ await finish(row, 'ineligible', true);
181
+ result.deferred++;
182
+ continue;
183
+ }
184
+ if (typeof row.waitUntil === 'number') {
185
+ await finish(row, 'unavailable', false, row.waitUntil);
186
+ result.deferred++;
187
+ continue;
188
+ }
189
+ let create = Number(row.transport_generation) === 0;
190
+ if (!create) {
191
+ if (typeof row.task_id !== 'string' || !/^emseepea-[0-9a-f]{64}$/.test(row.task_id))
192
+ throw new ExternalMcpEventError('UNAVAILABLE');
193
+ const state = await provider(inv => transport.inspect({ deliveryId: String(row.delivery_id), taskId: String(row.task_id) }, inv));
194
+ if (state === 'matching') {
195
+ await finish(row, 'present');
196
+ result.observed++;
197
+ continue;
198
+ }
199
+ if (state === 'conflict') {
200
+ await finish(row, 'conflict');
201
+ result.conflicts++;
202
+ continue;
203
+ }
204
+ if (state !== 'missing') {
205
+ await finish(row, 'unknown');
206
+ result.unknown++;
207
+ continue;
208
+ }
209
+ check(15000);
210
+ if (await provider(inv => transport.queue(inv)) !== 'present') {
211
+ await finish(row, 'unavailable');
212
+ result.deferred++;
213
+ continue;
214
+ }
215
+ create = true;
216
+ }
217
+ if (create) {
218
+ await reserve(row);
219
+ check(8000);
220
+ const state = await provider(inv => transport.create({ deliveryId: String(row.delivery_id), taskId: String(row.task_id) }, inv));
221
+ await finish(row, state === 'created' ? 'present' : 'unknown');
222
+ if (state === 'created')
223
+ result.created++;
224
+ else
225
+ result.unknown++;
226
+ }
227
+ if (target !== undefined)
228
+ break;
229
+ }
230
+ return result;
231
+ }
232
+ catch (error) {
233
+ result.status = error instanceof Error && error.message === 'DISPATCH_PAUSED' ? 'paused' : closing ? 'stopping' : 'retry_pending';
234
+ result.unknown++;
235
+ return result;
236
+ }
237
+ finally {
238
+ // A visible timeout never frees the single slot while raw SDK/SQL or disposal is outstanding.
239
+ const drained = owner.quiesce();
240
+ const held = track(Promise.allSettled([...pending, drained]));
241
+ void held.then(async () => { if (await drained)
242
+ busy = false; });
243
+ }
244
+ }
245
+ return Object.freeze({
246
+ reconcile: (invocation) => operation(undefined, invocation),
247
+ dispatch: (deliveryId, invocation) => operation(deliveryId, invocation),
248
+ async settle(invocation) {
249
+ closing = true;
250
+ const end = performance.now() + Math.max(0, invocation.deadlineMs - Date.now());
251
+ const settling = owner.settle(invocation);
252
+ while (pending.size) {
253
+ if (invocation.signal.aborted || performance.now() >= end)
254
+ return false;
255
+ let timer;
256
+ try {
257
+ const done = await Promise.race([Promise.allSettled(pending).then(() => true), new Promise(resolve => { timer = setTimeout(() => resolve(false), Math.max(1, end - performance.now())); })]);
258
+ if (!done)
259
+ return false;
260
+ }
261
+ finally {
262
+ if (timer)
263
+ clearTimeout(timer);
264
+ }
265
+ }
266
+ return settling;
267
+ },
268
+ });
269
+ }
270
+ //# sourceMappingURL=events-postgres-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-postgres-dispatch.js","sourceRoot":"","sources":["../src/events-postgres-dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type PostgresEventMigrationPool } from './events-postgres-migrations.js';
2
+ import type { PostgresEventInvocation } from './events-postgres.js';
3
+ export declare class PostgresEventLifecycleMigrationError extends Error {
4
+ readonly code: 'INCOMPATIBLE_SCHEMA' | 'UNAVAILABLE' | 'OUTCOME_UNKNOWN';
5
+ readonly phase: 'capture' | 'lifecycle';
6
+ readonly captureCommitted: boolean;
7
+ constructor(code: 'INCOMPATIBLE_SCHEMA' | 'UNAVAILABLE' | 'OUTCOME_UNKNOWN', phase?: 'capture' | 'lifecycle', captureCommitted?: boolean);
8
+ }
9
+ /** Runs the capture migration before the lifecycle migration. If the lifecycle migration fails, `capture-v1` can remain installed.
10
+ * The lifecycle migration rejects an existing populated capture-only subscription store because it cannot establish verification state safely.
11
+ * Serving constructors never call this function. The deployment owner must configure database grants.
12
+ */
13
+ export declare function createPostgresEventLifecycleMigrator(pool: PostgresEventMigrationPool): Readonly<{
14
+ migrate(invocation: PostgresEventInvocation): Promise<void>;
15
+ settle(invocation: PostgresEventInvocation): Promise<boolean>;
16
+ }>;
17
+ //# sourceMappingURL=events-postgres-lifecycle-migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-postgres-lifecycle-migrations.d.ts","sourceRoot":"","sources":["../src/events-postgres-lifecycle-migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AACtH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,qBAAa,oCAAqC,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,EAAC,qBAAqB,GAAC,aAAa,GAAC,iBAAiB;IAC7E,QAAQ,CAAC,KAAK,EAAC,SAAS,GAAC,WAAW;IAAc,QAAQ,CAAC,gBAAgB;gBADxD,IAAI,EAAC,qBAAqB,GAAC,aAAa,GAAC,iBAAiB,EACpE,KAAK,GAAC,SAAS,GAAC,WAAuB,EAAW,gBAAgB,UAAM;CACpF;AAuDD;;;GAGG;AACH,wBAAgB,oCAAoC,CAAC,IAAI,EAAC,0BAA0B;wBA6B7D,uBAAuB;uBAClB,uBAAuB;GAMlD"}
@@ -0,0 +1,125 @@
1
+ import { createPostgresEventCaptureMigrator } from './events-postgres-migrations.js';
2
+ import { createOwnedEventOperations } from './events-postgres-owned.js';
3
+ export class PostgresEventLifecycleMigrationError extends Error {
4
+ code;
5
+ phase;
6
+ captureCommitted;
7
+ constructor(code, phase = 'lifecycle', captureCommitted = false) {
8
+ super(code);
9
+ this.code = code;
10
+ this.phase = phase;
11
+ this.captureCommitted = captureCommitted;
12
+ this.name = 'PostgresEventLifecycleMigrationError';
13
+ }
14
+ }
15
+ const incompatible = () => { throw new PostgresEventLifecycleMigrationError('INCOMPATIBLE_SCHEMA'); };
16
+ const tables = ['emseepea_event_lifecycle_migrations', 'emseepea_event_heads', 'emseepea_event_keys'];
17
+ const ddl = [
18
+ `CREATE TABLE public.emseepea_event_lifecycle_migrations(singleton pg_catalog.bool PRIMARY KEY DEFAULT true CHECK(singleton),version pg_catalog.int4 NOT NULL,revision pg_catalog.text NOT NULL)`,
19
+ `CREATE TABLE public.emseepea_event_heads(namespace pg_catalog.text NOT NULL,subscription_id pg_catalog.text NOT NULL,owner_key pg_catalog.text NOT NULL,url pg_catalog.text,revision pg_catalog.text NOT NULL,generation pg_catalog.text,PRIMARY KEY(namespace,subscription_id))`,
20
+ `CREATE TABLE public.emseepea_event_keys(namespace pg_catalog.text NOT NULL,subscription_id pg_catalog.text NOT NULL,generation pg_catalog.text NOT NULL,secret pg_catalog.text NOT NULL,previous_secret pg_catalog.text,previous_until pg_catalog.timestamptz,verified_until pg_catalog.timestamptz NOT NULL,
21
+ PRIMARY KEY(namespace,subscription_id,generation),FOREIGN KEY(namespace,subscription_id,generation) REFERENCES public.emseepea_event_capture_subscriptions(namespace,subscription_id,generation),CHECK((previous_secret IS NULL)=(previous_until IS NULL)))`,
22
+ ];
23
+ const expected = {
24
+ emseepea_event_lifecycle_migrations: ['singleton:16:-1:true', 'version:23:-1:true', 'revision:25:-1:true'],
25
+ emseepea_event_heads: ['namespace:25:-1:true', 'subscription_id:25:-1:true', 'owner_key:25:-1:true', 'url:25:-1:false', 'revision:25:-1:true', 'generation:25:-1:false'],
26
+ emseepea_event_keys: ['namespace:25:-1:true', 'subscription_id:25:-1:true', 'generation:25:-1:true', 'secret:25:-1:true', 'previous_secret:25:-1:false', 'previous_until:1184:-1:false', 'verified_until:1184:-1:true'],
27
+ };
28
+ const catalog = `SELECT c.relname,c.relkind,c.relrowsecurity,c.relforcerowsecurity,pg_catalog.pg_get_userbyid(c.relowner)=current_user AS owned,
29
+ pg_catalog.array_agg(a.attname::pg_catalog.text||':'||a.atttypid::pg_catalog.text||':'||a.atttypmod::pg_catalog.text||':'||a.attnotnull::pg_catalog.text ORDER BY a.attnum) AS columns,
30
+ pg_catalog.jsonb_object_agg(a.attname,pg_catalog.pg_get_expr(d.adbin,d.adrelid)) AS defaults
31
+ FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
32
+ JOIN pg_catalog.pg_attribute a ON a.attrelid=c.oid AND a.attnum>0 AND NOT a.attisdropped
33
+ LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid=c.oid AND d.adnum=a.attnum
34
+ WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[]) GROUP BY c.oid,c.relname,c.relkind,c.relrowsecurity,c.relforcerowsecurity,c.relowner`;
35
+ async function verify(run) {
36
+ const rows = (await run(catalog, [tables])).rows;
37
+ if (rows.length !== 3)
38
+ incompatible();
39
+ for (const row of rows) {
40
+ if (typeof row.relname !== 'string' || row.relkind !== 'r' || row.owned !== true || row.relrowsecurity !== false || row.relforcerowsecurity !== false || JSON.stringify(row.columns) !== JSON.stringify(expected[row.relname]))
41
+ incompatible();
42
+ const defaults = row.defaults;
43
+ if (!defaults || typeof defaults !== 'object')
44
+ incompatible();
45
+ for (const item of expected[String(row.relname)] ?? []) {
46
+ const column = item.split(':')[0];
47
+ if (defaults[column] !== (row.relname === tables[0] && column === 'singleton' ? 'true' : null))
48
+ incompatible();
49
+ }
50
+ }
51
+ const wanted = new Set([
52
+ [tables[0], 'p', 'PRIMARY KEY (singleton)'], [tables[0], 'c', 'CHECK (singleton)'],
53
+ [tables[1], 'p', 'PRIMARY KEY (namespace, subscription_id)'],
54
+ [tables[2], 'p', 'PRIMARY KEY (namespace, subscription_id, generation)'],
55
+ [tables[2], 'f', 'FOREIGN KEY (namespace, subscription_id, generation) REFERENCES emseepea_event_capture_subscriptions(namespace, subscription_id, generation)'],
56
+ [tables[2], 'c', 'CHECK (((previous_secret IS NULL) = (previous_until IS NULL)))'],
57
+ ].map(value => JSON.stringify(value)));
58
+ const constraints = (await run(`SELECT c.relname,t.contype,pg_catalog.pg_get_constraintdef(t.oid) AS definition,t.convalidated,t.condeferrable,t.condeferred,
59
+ CASE WHEN t.contype='p' THEN i.indisvalid AND i.indisready AND i.indisunique ELSE true END AS key_valid
60
+ FROM pg_catalog.pg_constraint t JOIN pg_catalog.pg_class c ON c.oid=t.conrelid JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
61
+ LEFT JOIN pg_catalog.pg_index i ON i.indexrelid=t.conindid WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[])`, [tables])).rows;
62
+ for (const row of constraints)
63
+ if (row.convalidated !== true || row.condeferrable !== false || row.condeferred !== false || row.key_valid !== true || !wanted.delete(JSON.stringify([row.relname, row.contype, row.definition])))
64
+ incompatible();
65
+ if (wanted.size)
66
+ incompatible();
67
+ const indexes = (await run(`SELECT i.indexrelid FROM pg_catalog.pg_index i JOIN pg_catalog.pg_class c ON c.oid=i.indrelid JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
68
+ WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[])`, [tables])).rows;
69
+ if (indexes.length !== 3)
70
+ incompatible();
71
+ const triggers = (await run(`SELECT t.oid FROM pg_catalog.pg_trigger t JOIN pg_catalog.pg_class c ON c.oid=t.tgrelid JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
72
+ WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[]) AND NOT t.tgisinternal`, [tables])).rows;
73
+ if (triggers.length)
74
+ incompatible();
75
+ const marker = (await run('SELECT singleton,version,revision FROM public.emseepea_event_lifecycle_migrations')).rows;
76
+ if (marker.length !== 1 || marker[0]?.singleton !== true || marker[0].version !== 1 || marker[0].revision !== 'lifecycle-v1')
77
+ incompatible();
78
+ }
79
+ /** Runs the capture migration before the lifecycle migration. If the lifecycle migration fails, `capture-v1` can remain installed.
80
+ * The lifecycle migration rejects an existing populated capture-only subscription store because it cannot establish verification state safely.
81
+ * Serving constructors never call this function. The deployment owner must configure database grants.
82
+ */
83
+ export function createPostgresEventLifecycleMigrator(pool) {
84
+ if (!pool || typeof pool.connect !== 'function')
85
+ throw new PostgresEventLifecycleMigrationError('UNAVAILABLE');
86
+ const owned = createOwnedEventOperations();
87
+ let closing = false;
88
+ const prerequisite = createPostgresEventCaptureMigrator(pool);
89
+ async function migrate(invocation) {
90
+ if (closing)
91
+ throw new PostgresEventLifecycleMigrationError('UNAVAILABLE');
92
+ let captureCommitted = false;
93
+ try {
94
+ await prerequisite.migrate(invocation);
95
+ captureCommitted = true;
96
+ await owned.run(pool, invocation, async (run) => {
97
+ await run('SELECT pg_catalog.pg_advisory_xact_lock(1740126,1)');
98
+ const found = (await run(catalog, [tables])).rows;
99
+ if (found.length === 0) {
100
+ await run('LOCK TABLE public.emseepea_event_capture_subscriptions IN SHARE ROW EXCLUSIVE MODE');
101
+ const present = (await run('SELECT 1 FROM public.emseepea_event_capture_subscriptions LIMIT 1')).rows;
102
+ if (present.length)
103
+ incompatible();
104
+ for (const statement of ddl)
105
+ await run(statement);
106
+ await run("INSERT INTO public.emseepea_event_lifecycle_migrations VALUES(true,1,'lifecycle-v1')");
107
+ }
108
+ await verify(run);
109
+ }, false, error => error instanceof PostgresEventLifecycleMigrationError);
110
+ }
111
+ catch (error) {
112
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
113
+ throw new PostgresEventLifecycleMigrationError(code === 'OUTCOME_UNKNOWN' ? 'OUTCOME_UNKNOWN' : code === 'INCOMPATIBLE_SCHEMA' ? 'INCOMPATIBLE_SCHEMA' : 'UNAVAILABLE', captureCommitted ? 'lifecycle' : 'capture', captureCommitted);
114
+ }
115
+ }
116
+ return Object.freeze({
117
+ migrate(invocation) { return owned.track(migrate(invocation)); },
118
+ async settle(invocation) {
119
+ closing = true;
120
+ const results = await Promise.all([prerequisite.settle(invocation), owned.settle(invocation)]);
121
+ return results.every(Boolean);
122
+ },
123
+ });
124
+ }
125
+ //# sourceMappingURL=events-postgres-lifecycle-migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-postgres-lifecycle-migrations.js","sourceRoot":"","sources":["../src/events-postgres-lifecycle-migrations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ExternalMcpEventLifecycle } from './events-external.js';
2
+ import { type OwnedEventPool } from './events-postgres-owned.js';
3
+ export { createPostgresEventLifecycleMigrator } from './events-postgres-lifecycle-migrations.js';
4
+ export interface PostgresEventLifecycleOptions {
5
+ readonly namespace: string;
6
+ /** The observation pool must have `SELECT` access to subscription heads and subscriptions only. It must not have access to signing keys. */
7
+ readonly observationPool: OwnedEventPool;
8
+ /** The mutation pool must allow only the required lifecycle data changes. Keep it separate from the caller-owned capture role. */
9
+ readonly mutationPool: OwnedEventPool;
10
+ }
11
+ /** Creates the experimental PostgreSQL lifecycle implementation. Run the explicit migration first and configure finite timeouts on both PostgreSQL pools. */
12
+ export declare function createPostgresEventLifecycle(options: PostgresEventLifecycleOptions): ExternalMcpEventLifecycle;
13
+ //# sourceMappingURL=events-postgres-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-postgres-lifecycle.d.ts","sourceRoot":"","sources":["../src/events-postgres-lifecycle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,yBAAyB,EAAmE,MAAM,sBAAsB,CAAC;AAE9J,OAAO,EAA8B,KAAK,cAAc,EAAiB,MAAM,4BAA4B,CAAC;AAC5G,OAAO,EAAE,oCAAoC,EAAE,MAAM,2CAA2C,CAAC;AACjG,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAC,MAAM,CAAC;IAC1B,4IAA4I;IAC5I,QAAQ,CAAC,eAAe,EAAC,cAAc,CAAC;IACxC,kIAAkI;IAClI,QAAQ,CAAC,YAAY,EAAC,cAAc,CAAC;CACtC;AAuCD,6JAA6J;AAC7J,wBAAgB,4BAA4B,CAAC,OAAO,EAAC,6BAA6B,GAAE,yBAAyB,CAuF5G"}