@emseepea/server 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/events-cloud-tasks-transport.d.ts +34 -0
- package/dist/events-cloud-tasks-transport.d.ts.map +1 -0
- package/dist/events-cloud-tasks-transport.js +232 -0
- package/dist/events-cloud-tasks-transport.js.map +1 -0
- package/dist/events-google-sdk-lifetime.d.ts +7 -0
- package/dist/events-google-sdk-lifetime.d.ts.map +1 -0
- package/dist/events-google-sdk-lifetime.js +70 -0
- package/dist/events-google-sdk-lifetime.js.map +1 -0
- package/dist/events-postgres-delivery-migrations.d.ts +18 -0
- package/dist/events-postgres-delivery-migrations.d.ts.map +1 -0
- package/dist/events-postgres-delivery-migrations.js +146 -0
- package/dist/events-postgres-delivery-migrations.js.map +1 -0
- package/dist/events-postgres-delivery-owned.d.ts +16 -0
- package/dist/events-postgres-delivery-owned.d.ts.map +1 -0
- package/dist/events-postgres-delivery-owned.js +178 -0
- package/dist/events-postgres-delivery-owned.js.map +1 -0
- package/dist/events-postgres-delivery.d.ts +29 -0
- package/dist/events-postgres-delivery.d.ts.map +1 -0
- package/dist/events-postgres-delivery.js +299 -0
- package/dist/events-postgres-delivery.js.map +1 -0
- package/dist/events-postgres-dispatch-migrations.d.ts +19 -0
- package/dist/events-postgres-dispatch-migrations.d.ts.map +1 -0
- package/dist/events-postgres-dispatch-migrations.js +162 -0
- package/dist/events-postgres-dispatch-migrations.js.map +1 -0
- package/dist/events-postgres-dispatch.d.ts +39 -0
- package/dist/events-postgres-dispatch.d.ts.map +1 -0
- package/dist/events-postgres-dispatch.js +270 -0
- package/dist/events-postgres-dispatch.js.map +1 -0
- package/dist/events-postgres-lifecycle-migrations.d.ts +17 -0
- package/dist/events-postgres-lifecycle-migrations.d.ts.map +1 -0
- package/dist/events-postgres-lifecycle-migrations.js +125 -0
- package/dist/events-postgres-lifecycle-migrations.js.map +1 -0
- package/dist/events-postgres-lifecycle.d.ts +13 -0
- package/dist/events-postgres-lifecycle.d.ts.map +1 -0
- package/dist/events-postgres-lifecycle.js +176 -0
- package/dist/events-postgres-lifecycle.js.map +1 -0
- package/dist/events-postgres-migrations.d.ts +32 -0
- package/dist/events-postgres-migrations.d.ts.map +1 -0
- package/dist/events-postgres-migrations.js +329 -0
- package/dist/events-postgres-migrations.js.map +1 -0
- package/dist/events-postgres-owned.d.ts +16 -0
- package/dist/events-postgres-owned.d.ts.map +1 -0
- package/dist/events-postgres-owned.js +161 -0
- package/dist/events-postgres-owned.js.map +1 -0
- package/dist/events-postgres.d.ts +53 -0
- package/dist/events-postgres.d.ts.map +1 -0
- package/dist/events-postgres.js +289 -0
- package/dist/events-postgres.js.map +1 -0
- package/dist/index.js +58 -9
- package/dist/index.js.map +1 -1
- package/package.json +29 -5
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { createPostgresEventDeliveryMigrator, PostgresEventDeliveryMigrationError, } from './events-postgres-delivery-migrations.js';
|
|
2
|
+
import { createOwnedEventOperations } from './events-postgres-owned.js';
|
|
3
|
+
export class PostgresEventDispatchMigrationError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
phase;
|
|
6
|
+
captureCommitted;
|
|
7
|
+
lifecycleCommitted;
|
|
8
|
+
deliveryCommitted;
|
|
9
|
+
constructor(code, phase = 'dispatch', captureCommitted = false, lifecycleCommitted = false, deliveryCommitted = false) {
|
|
10
|
+
super(code);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.phase = phase;
|
|
13
|
+
this.captureCommitted = captureCommitted;
|
|
14
|
+
this.lifecycleCommitted = lifecycleCommitted;
|
|
15
|
+
this.deliveryCommitted = deliveryCommitted;
|
|
16
|
+
this.name = 'PostgresEventDispatchMigrationError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const bad = () => { throw new PostgresEventDispatchMigrationError('INCOMPATIBLE_SCHEMA'); };
|
|
20
|
+
const tables = ['emseepea_event_dispatch_migrations', 'emseepea_event_dispatch_state'];
|
|
21
|
+
const names = ['namespace', 'source_kind', 'source_id', 'subscription_id', 'generation'];
|
|
22
|
+
const k = names.join(', ');
|
|
23
|
+
const ddl = [
|
|
24
|
+
`CREATE TABLE public.emseepea_event_dispatch_migrations(singleton pg_catalog.bool PRIMARY KEY DEFAULT true CHECK(singleton),version pg_catalog.int4 NOT NULL,revision pg_catalog.text NOT NULL)`,
|
|
25
|
+
`CREATE TABLE public.emseepea_event_dispatch_state(${names.map(n => `${n} pg_catalog.text NOT NULL`).join(',')},
|
|
26
|
+
config_hash pg_catalog.text NOT NULL CHECK(config_hash ~ '^[0-9a-f]{64}$'),
|
|
27
|
+
transport_generation pg_catalog.int4 NOT NULL DEFAULT 0 CHECK(transport_generation>=0 AND transport_generation<=2147483646),
|
|
28
|
+
task_id pg_catalog.text CHECK(task_id ~ '^emseepea-[0-9a-f]{64}$'),
|
|
29
|
+
lease_id pg_catalog.text,lease_until pg_catalog.timestamptz,due_at pg_catalog.timestamptz NOT NULL DEFAULT pg_catalog.clock_timestamp(),
|
|
30
|
+
recovery_count pg_catalog.int4 NOT NULL DEFAULT 0 CHECK(recovery_count>=0),
|
|
31
|
+
category pg_catalog.text NOT NULL DEFAULT 'fresh' CHECK(category IN('fresh','present','unknown','unavailable','conflict','ineligible')),
|
|
32
|
+
terminal pg_catalog.bool NOT NULL DEFAULT false,
|
|
33
|
+
PRIMARY KEY(${k}),FOREIGN KEY(${k}) REFERENCES public.emseepea_event_intents(${k}) ON DELETE RESTRICT,
|
|
34
|
+
CHECK((lease_id IS NULL)=(lease_until IS NULL)),CHECK((transport_generation=0)=(task_id IS NULL)))`,
|
|
35
|
+
`CREATE INDEX emseepea_event_dispatch_due ON public.emseepea_event_dispatch_state(namespace,due_at,source_kind,source_id,subscription_id,generation) WHERE NOT terminal`,
|
|
36
|
+
];
|
|
37
|
+
const expected = {
|
|
38
|
+
emseepea_event_dispatch_migrations: ['singleton:16:-1:true', 'version:23:-1:true', 'revision:25:-1:true'],
|
|
39
|
+
emseepea_event_dispatch_state: [...names.map(n => `${n}:25:-1:true`), 'config_hash:25:-1:true', 'transport_generation:23:-1:true', 'task_id:25:-1:false', 'lease_id:25:-1:false', 'lease_until:1184:-1:false', 'due_at:1184:-1:true', 'recovery_count:23:-1:true', 'category:25:-1:true', 'terminal:16:-1:true'],
|
|
40
|
+
};
|
|
41
|
+
const constraints = [
|
|
42
|
+
[tables[0], 'p', 'PRIMARY KEY (singleton)'], [tables[0], 'c', 'CHECK (singleton)'],
|
|
43
|
+
[tables[1], 'p', `PRIMARY KEY (${k})`], [tables[1], 'f', `FOREIGN KEY (${k}) REFERENCES emseepea_event_intents(${k}) ON DELETE RESTRICT`],
|
|
44
|
+
[tables[1], 'c', "CHECK ((config_hash ~ '^[0-9a-f]{64}$'::text))"],
|
|
45
|
+
[tables[1], 'c', 'CHECK (((transport_generation >= 0) AND (transport_generation <= 2147483646)))'],
|
|
46
|
+
[tables[1], 'c', "CHECK ((task_id ~ '^emseepea-[0-9a-f]{64}$'::text))"],
|
|
47
|
+
[tables[1], 'c', 'CHECK ((recovery_count >= 0))'],
|
|
48
|
+
[tables[1], 'c', "CHECK ((category = ANY (ARRAY['fresh'::text, 'present'::text, 'unknown'::text, 'unavailable'::text, 'conflict'::text, 'ineligible'::text])))"],
|
|
49
|
+
[tables[1], 'c', 'CHECK (((lease_id IS NULL) = (lease_until IS NULL)))'],
|
|
50
|
+
[tables[1], 'c', 'CHECK (((transport_generation = 0) = (task_id IS NULL)))'],
|
|
51
|
+
];
|
|
52
|
+
const catalog = `SELECT c.relname,c.relkind,c.relrowsecurity,c.relforcerowsecurity,pg_catalog.pg_get_userbyid(c.relowner)=current_user AS owned,
|
|
53
|
+
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,
|
|
54
|
+
pg_catalog.jsonb_object_agg(a.attname,pg_catalog.pg_get_expr(d.adbin,d.adrelid)) AS defaults
|
|
55
|
+
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
|
|
56
|
+
JOIN pg_catalog.pg_attribute a ON a.attrelid=c.oid AND a.attnum>0 AND NOT a.attisdropped
|
|
57
|
+
LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid=c.oid AND d.adnum=a.attnum
|
|
58
|
+
WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[])
|
|
59
|
+
GROUP BY c.oid,c.relname,c.relkind,c.relrowsecurity,c.relforcerowsecurity,c.relowner`;
|
|
60
|
+
async function verify(run) {
|
|
61
|
+
const rows = (await run(catalog, [tables])).rows;
|
|
62
|
+
if (rows.length !== 2)
|
|
63
|
+
bad();
|
|
64
|
+
for (const row of rows) {
|
|
65
|
+
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]))
|
|
66
|
+
bad();
|
|
67
|
+
const defaults = row.defaults;
|
|
68
|
+
if (!defaults || typeof defaults !== 'object')
|
|
69
|
+
bad();
|
|
70
|
+
for (const column of expected[String(row.relname)] ?? []) {
|
|
71
|
+
const name = column.split(':')[0];
|
|
72
|
+
const value = row.relname === tables[0] && name === 'singleton' ? 'true' : row.relname === tables[1] && ['transport_generation', 'recovery_count'].includes(name) ? '0' :
|
|
73
|
+
row.relname === tables[1] && name === 'due_at' ? 'clock_timestamp()' : row.relname === tables[1] && name === 'category' ? "'fresh'::text" : row.relname === tables[1] && name === 'terminal' ? 'false' : null;
|
|
74
|
+
if (defaults[name] !== value)
|
|
75
|
+
bad();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const wanted = new Set(constraints.map(row => JSON.stringify(row)));
|
|
79
|
+
const found = (await run(`SELECT c.relname,t.contype,pg_catalog.pg_get_constraintdef(t.oid) AS definition,t.convalidated,t.condeferrable,t.condeferred,
|
|
80
|
+
CASE WHEN t.contype IN('p','u') THEN i.indisvalid AND i.indisready AND i.indisunique ELSE true END AS key_valid
|
|
81
|
+
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
|
|
82
|
+
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;
|
|
83
|
+
for (const row of found)
|
|
84
|
+
if (row.convalidated !== true || row.condeferrable !== false || row.condeferred !== false || row.key_valid !== true || !wanted.delete(JSON.stringify([row.relname, row.contype, row.definition])))
|
|
85
|
+
bad();
|
|
86
|
+
if (wanted.size)
|
|
87
|
+
bad();
|
|
88
|
+
const indexes = (await run(`SELECT c.relname,x.relname AS index_name,i.indisvalid,i.indisready,i.indisunique,
|
|
89
|
+
pg_catalog.pg_get_expr(i.indpred,i.indrelid) AS predicate,
|
|
90
|
+
ARRAY(SELECT a.attname::pg_catalog.text FROM pg_catalog.unnest(i.indkey) WITH ORDINALITY z(num,ord)
|
|
91
|
+
JOIN pg_catalog.pg_attribute a ON a.attrelid=i.indrelid AND a.attnum=z.num ORDER BY z.ord) AS keys
|
|
92
|
+
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
|
|
93
|
+
JOIN pg_catalog.pg_class x ON x.oid=i.indexrelid WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[])`, [tables])).rows;
|
|
94
|
+
if (indexes.length !== 3)
|
|
95
|
+
bad();
|
|
96
|
+
for (const row of indexes) {
|
|
97
|
+
const due = row.index_name === 'emseepea_event_dispatch_due';
|
|
98
|
+
const keys = due ? ['namespace', 'due_at', 'source_kind', 'source_id', 'subscription_id', 'generation'] : row.relname === tables[0] ? ['singleton'] : names;
|
|
99
|
+
if (row.indisvalid !== true || row.indisready !== true || row.indisunique !== !due || row.predicate !== (due ? '(NOT terminal)' : null) || JSON.stringify(row.keys) !== JSON.stringify(keys) || due && row.relname !== tables[1])
|
|
100
|
+
bad();
|
|
101
|
+
}
|
|
102
|
+
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 WHERE n.nspname='public' AND c.relname=ANY($1::pg_catalog.text[]) AND NOT t.tgisinternal`, [tables])).rows;
|
|
103
|
+
if (triggers.length)
|
|
104
|
+
bad();
|
|
105
|
+
const marker = (await run('SELECT singleton,version,revision FROM public.emseepea_event_dispatch_migrations')).rows;
|
|
106
|
+
if (marker.length !== 1 || marker[0]?.singleton !== true || marker[0].version !== 1 || marker[0].revision !== 'dispatch-v1')
|
|
107
|
+
bad();
|
|
108
|
+
}
|
|
109
|
+
/** Runs the capture, lifecycle, and delivery migrations before the dispatch
|
|
110
|
+
* migration. If a later migration fails, earlier prerequisite schemas can
|
|
111
|
+
* remain installed. Serving constructors never call this function.
|
|
112
|
+
*/
|
|
113
|
+
export function createPostgresEventDispatchMigrator(pool) {
|
|
114
|
+
let prerequisite;
|
|
115
|
+
try {
|
|
116
|
+
prerequisite = createPostgresEventDeliveryMigrator(pool);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (error instanceof PostgresEventDeliveryMigrationError) {
|
|
120
|
+
throw new PostgresEventDispatchMigrationError(error.code, error.phase, error.captureCommitted, error.lifecycleCommitted, false);
|
|
121
|
+
}
|
|
122
|
+
throw new PostgresEventDispatchMigrationError('UNAVAILABLE');
|
|
123
|
+
}
|
|
124
|
+
const owned = createOwnedEventOperations();
|
|
125
|
+
let closing = false;
|
|
126
|
+
async function migrate(invocation) {
|
|
127
|
+
if (closing)
|
|
128
|
+
throw new PostgresEventDispatchMigrationError('UNAVAILABLE');
|
|
129
|
+
let captureCommitted = false, lifecycleCommitted = false, deliveryCommitted = false;
|
|
130
|
+
try {
|
|
131
|
+
await prerequisite.migrate(invocation);
|
|
132
|
+
captureCommitted = true;
|
|
133
|
+
lifecycleCommitted = true;
|
|
134
|
+
deliveryCommitted = true;
|
|
135
|
+
await owned.run(pool, invocation, async (run) => {
|
|
136
|
+
await run('SELECT pg_catalog.pg_advisory_xact_lock(1740126,3)');
|
|
137
|
+
const found = (await run(catalog, [tables])).rows;
|
|
138
|
+
if (found.length === 0) {
|
|
139
|
+
for (const statement of ddl)
|
|
140
|
+
await run(statement);
|
|
141
|
+
await run("INSERT INTO public.emseepea_event_dispatch_migrations VALUES(true,1,'dispatch-v1')");
|
|
142
|
+
}
|
|
143
|
+
await verify(run);
|
|
144
|
+
}, false, error => error instanceof PostgresEventDispatchMigrationError);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (error instanceof PostgresEventDispatchMigrationError) {
|
|
148
|
+
throw new PostgresEventDispatchMigrationError(error.code, 'dispatch', captureCommitted, lifecycleCommitted, deliveryCommitted);
|
|
149
|
+
}
|
|
150
|
+
if (error instanceof PostgresEventDeliveryMigrationError) {
|
|
151
|
+
throw new PostgresEventDispatchMigrationError(error.code, error.phase, error.captureCommitted, error.lifecycleCommitted, false);
|
|
152
|
+
}
|
|
153
|
+
const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
|
|
154
|
+
throw new PostgresEventDispatchMigrationError(code === 'INCOMPATIBLE_SCHEMA' ? 'INCOMPATIBLE_SCHEMA' : code === 'OUTCOME_UNKNOWN' ? 'OUTCOME_UNKNOWN' : 'UNAVAILABLE', 'dispatch', captureCommitted, lifecycleCommitted, deliveryCommitted);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return Object.freeze({
|
|
158
|
+
migrate(invocation) { return owned.track(migrate(invocation)); },
|
|
159
|
+
async settle(invocation) { closing = true; const results = await Promise.allSettled([prerequisite.settle(invocation), owned.settle(invocation)]); return results.every(result => result.status === 'fulfilled' && result.value === true); },
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=events-postgres-dispatch-migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-postgres-dispatch-migrations.js","sourceRoot":"","sources":["../src/events-postgres-dispatch-migrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ExternalMcpEventInvocation } from './events-external.js';
|
|
2
|
+
import type { OwnedEventPool } from './events-postgres-owned.js';
|
|
3
|
+
type Invocation = ExternalMcpEventInvocation;
|
|
4
|
+
/** Private provider boundary. The packaged provider must verify exact task equivalence. */
|
|
5
|
+
export interface EventDispatchTransport {
|
|
6
|
+
readonly fingerprint: string;
|
|
7
|
+
queue(invocation: Invocation): Promise<'present' | 'unavailable'>;
|
|
8
|
+
inspect(task: Readonly<{
|
|
9
|
+
deliveryId: string;
|
|
10
|
+
taskId: string;
|
|
11
|
+
}>, invocation: Invocation): Promise<'matching' | 'conflict' | 'missing' | 'unavailable'>;
|
|
12
|
+
create(task: Readonly<{
|
|
13
|
+
deliveryId: string;
|
|
14
|
+
taskId: string;
|
|
15
|
+
}>, invocation: Invocation): Promise<'created' | 'exists' | 'unavailable'>;
|
|
16
|
+
}
|
|
17
|
+
export interface EventDispatchOptions {
|
|
18
|
+
readonly namespace: string;
|
|
19
|
+
readonly pool: OwnedEventPool;
|
|
20
|
+
readonly transport: EventDispatchTransport;
|
|
21
|
+
readonly isPaused: () => boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface EventDispatchResult {
|
|
24
|
+
readonly selected: number;
|
|
25
|
+
readonly created: number;
|
|
26
|
+
readonly observed: number;
|
|
27
|
+
readonly conflicts: number;
|
|
28
|
+
readonly unknown: number;
|
|
29
|
+
readonly deferred: number;
|
|
30
|
+
readonly status: 'complete' | 'retry_pending' | 'paused' | 'stopping';
|
|
31
|
+
}
|
|
32
|
+
/** Internal implementation seam; no route, provider credentials, timer or adopter callback API. */
|
|
33
|
+
export declare function createPostgresEventDispatchRuntime(options: EventDispatchOptions): Readonly<{
|
|
34
|
+
reconcile: (invocation: Invocation) => Promise<EventDispatchResult>;
|
|
35
|
+
dispatch: (deliveryId: string, invocation: Invocation) => Promise<EventDispatchResult>;
|
|
36
|
+
settle(invocation: Invocation): Promise<boolean>;
|
|
37
|
+
}>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=events-postgres-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-postgres-dispatch.d.ts","sourceRoot":"","sources":["../src/events-postgres-dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,KAAK,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,4BAA4B,CAAC;AAG3E,KAAK,UAAU,GAAC,0BAA0B,CAAC;AAE3C,2FAA2F;AAC3F,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,WAAW,EAAC,MAAM,CAAC;IAC5B,KAAK,CAAC,UAAU,EAAC,UAAU,GAAE,OAAO,CAAC,SAAS,GAAC,aAAa,CAAC,CAAC;IAC9D,OAAO,CAAC,IAAI,EAAC,QAAQ,CAAC;QAAC,UAAU,EAAC,MAAM,CAAC;QAAA,MAAM,EAAC,MAAM,CAAA;KAAC,CAAC,EAAC,UAAU,EAAC,UAAU,GAAE,OAAO,CAAC,UAAU,GAAC,UAAU,GAAC,SAAS,GAAC,aAAa,CAAC,CAAC;IACvI,MAAM,CAAC,IAAI,EAAC,QAAQ,CAAC;QAAC,UAAU,EAAC,MAAM,CAAC;QAAA,MAAM,EAAC,MAAM,CAAA;KAAC,CAAC,EAAC,UAAU,EAAC,UAAU,GAAE,OAAO,CAAC,SAAS,GAAC,QAAQ,GAAC,aAAa,CAAC,CAAC;CACzH;AACD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAC,MAAM,CAAC;IAAA,QAAQ,CAAC,IAAI,EAAC,cAAc,CAAC;IAAA,QAAQ,CAAC,SAAS,EAAC,sBAAsB,CAAC;IACjG,QAAQ,CAAC,QAAQ,EAAC,MAAI,OAAO,CAAC;CAC9B;AACD,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,CAAC,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,CAAC,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,CAAC,SAAS,EAAC,MAAM,CAAC;IACpG,QAAQ,CAAC,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,CAAC,QAAQ,EAAC,MAAM,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAC,UAAU,GAAC,eAAe,GAAC,QAAQ,GAAC,UAAU,CAAC;CAC/D;AAiBD,mGAAmG;AACnG,wBAAgB,kCAAkC,CAAC,OAAO,EAAC,oBAAoB;4BAgJvD,UAAU;2BACX,MAAM,cAAY,UAAU;uBACzB,UAAU,GAAE,OAAO,CAAC,OAAO,CAAC;GAWrD"}
|
|
@@ -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"}
|