@emseepea/server 0.23.1 → 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/app-shutdown.d.ts +11 -0
- package/dist/app-shutdown.d.ts.map +1 -0
- package/dist/app-shutdown.js +46 -0
- package/dist/app-shutdown.js.map +1 -0
- 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-external.d.ts +62 -0
- package/dist/events-external.d.ts.map +1 -0
- package/dist/events-external.js +289 -0
- package/dist/events-external.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/events.d.ts +30 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +146 -134
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +219 -90
- package/dist/index.js.map +1 -1
- package/package.json +31 -6
|
@@ -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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { isIP } from 'node:net';
|
|
3
|
+
import { ExternalMcpEventError } from './events-external.js';
|
|
4
|
+
import { mcpEventSubscriptionIdentity } from './events.js';
|
|
5
|
+
import { createOwnedEventOperations } from './events-postgres-owned.js';
|
|
6
|
+
export { createPostgresEventLifecycleMigrator } from './events-postgres-lifecycle-migrations.js';
|
|
7
|
+
const fail = (code) => { throw new ExternalMcpEventError(code); };
|
|
8
|
+
function text(value, max = 240) {
|
|
9
|
+
if (typeof value !== 'string' || !value || Buffer.byteLength(value) > max || /\u0000|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(value))
|
|
10
|
+
fail('INVALID_INPUT');
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function json(value, depth = 0) {
|
|
14
|
+
if (depth > 32)
|
|
15
|
+
fail('INVALID_INPUT');
|
|
16
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number' && Number.isFinite(value) && !Object.is(value, -0))
|
|
17
|
+
return value;
|
|
18
|
+
if (typeof value === 'string') {
|
|
19
|
+
if (value)
|
|
20
|
+
text(value, 65536);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
if (!value || typeof value !== 'object' || !(Array.isArray(value) ? Object.getPrototypeOf(value) === Array.prototype : [null, Object.prototype].includes(Object.getPrototypeOf(value))))
|
|
24
|
+
fail('INVALID_INPUT');
|
|
25
|
+
const fields = Object.getOwnPropertyDescriptors(value), array = Array.isArray(value), result = array ? [] : Object.create(null);
|
|
26
|
+
if (array && Reflect.ownKeys(fields).length !== value.length + 1)
|
|
27
|
+
fail('INVALID_INPUT');
|
|
28
|
+
for (const key of Reflect.ownKeys(fields)) {
|
|
29
|
+
if (typeof key !== 'string' || /\u0000|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u.test(key))
|
|
30
|
+
fail('INVALID_INPUT');
|
|
31
|
+
const item = fields[key];
|
|
32
|
+
if (!('value' in item) || !item.enumerable && !(array && key === 'length'))
|
|
33
|
+
fail('INVALID_INPUT');
|
|
34
|
+
if (array && key === 'length')
|
|
35
|
+
continue;
|
|
36
|
+
if (array && !/^(0|[1-9][0-9]*)$/.test(key))
|
|
37
|
+
fail('INVALID_INPUT');
|
|
38
|
+
result[key] = json(item.value, depth + 1);
|
|
39
|
+
}
|
|
40
|
+
return Object.freeze(result);
|
|
41
|
+
}
|
|
42
|
+
function request(value) {
|
|
43
|
+
const copy = json(value);
|
|
44
|
+
if (!copy || Array.isArray(copy) || typeof copy !== 'object' || Buffer.byteLength(JSON.stringify(copy)) > 65536)
|
|
45
|
+
fail('INVALID_INPUT');
|
|
46
|
+
return copy;
|
|
47
|
+
}
|
|
48
|
+
function identity(value) {
|
|
49
|
+
const id = text(value.id), ownerKey = text(value.ownerKey, 256), name = text(value.name), url = text(value.url, 8192), args = value.arguments;
|
|
50
|
+
if (!args || typeof args !== 'object' || Array.isArray(args))
|
|
51
|
+
fail('INVALID_INPUT');
|
|
52
|
+
let parsed;
|
|
53
|
+
try {
|
|
54
|
+
parsed = new URL(url);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return fail('INVALID_INPUT');
|
|
58
|
+
}
|
|
59
|
+
if (parsed.href !== url || parsed.protocol !== 'https:' || parsed.username || parsed.password || parsed.hash || parsed.port && parsed.port !== '443' || isIP(parsed.hostname.replace(/^\[|\]$/g, '')) || parsed.hostname === 'localhost' || parsed.hostname.endsWith('.localhost') || parsed.hostname.endsWith('.local'))
|
|
60
|
+
fail('INVALID_INPUT');
|
|
61
|
+
if (mcpEventSubscriptionIdentity(ownerKey, name, args, url) !== id)
|
|
62
|
+
fail('INVALID_INPUT');
|
|
63
|
+
return Object.freeze({ id, ownerKey, name, url, arguments: args });
|
|
64
|
+
}
|
|
65
|
+
const dbTime = `pg_catalog.floor(EXTRACT(epoch FROM pg_catalog.clock_timestamp())*1000)::pg_catalog.float8`;
|
|
66
|
+
const conflict = () => fail('SUBSCRIPTION_CHANGED');
|
|
67
|
+
const validMs = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
|
|
68
|
+
/** Creates the experimental PostgreSQL lifecycle implementation. Run the explicit migration first and configure finite timeouts on both PostgreSQL pools. */
|
|
69
|
+
export function createPostgresEventLifecycle(options) {
|
|
70
|
+
const namespace = text(options?.namespace);
|
|
71
|
+
if (!options.observationPool || !options.mutationPool || typeof options.observationPool.connect !== 'function' || typeof options.mutationPool.connect !== 'function')
|
|
72
|
+
fail('INVALID_INPUT');
|
|
73
|
+
const owned = createOwnedEventOperations();
|
|
74
|
+
async function locked(run, i) {
|
|
75
|
+
const inserted = (await run(`INSERT INTO public.emseepea_event_heads(namespace,subscription_id,owner_key,url,revision,generation)
|
|
76
|
+
VALUES($1,$2,$3,NULL,$4,NULL) ON CONFLICT(namespace,subscription_id) DO NOTHING RETURNING revision`, [namespace, i.id, i.ownerKey, randomUUID()])).rows.length === 1;
|
|
77
|
+
const row = (await run(`SELECT owner_key,url,revision,generation FROM public.emseepea_event_heads WHERE namespace=$1 AND subscription_id=$2 FOR UPDATE`, [namespace, i.id])).rows[0];
|
|
78
|
+
if (!row || row.owner_key !== i.ownerKey || typeof row.revision !== 'string')
|
|
79
|
+
return conflict();
|
|
80
|
+
return { row, inserted };
|
|
81
|
+
}
|
|
82
|
+
async function current(run, i, generation) {
|
|
83
|
+
if (generation === null)
|
|
84
|
+
return null;
|
|
85
|
+
const row = (await run(`SELECT owner_key,event_name,arguments,active,pg_catalog.floor(EXTRACT(epoch FROM expires_at)*1000)::pg_catalog.float8 AS expires_at
|
|
86
|
+
FROM public.emseepea_event_capture_subscriptions WHERE namespace=$1 AND subscription_id=$2 AND generation=$3`, [namespace, i.id, generation])).rows[0];
|
|
87
|
+
if (!row || row.owner_key !== i.ownerKey || row.event_name !== i.name || mcpEventSubscriptionIdentity(i.ownerKey, i.name, row.arguments, i.url) !== i.id || !validMs(row.expires_at) || typeof row.active !== 'boolean')
|
|
88
|
+
return fail('UNAVAILABLE');
|
|
89
|
+
return row;
|
|
90
|
+
}
|
|
91
|
+
return Object.freeze({
|
|
92
|
+
async observe(input, invocation) {
|
|
93
|
+
const i = identity(request(input));
|
|
94
|
+
return owned.run(options.observationPool, invocation, async (run) => {
|
|
95
|
+
const row = (await run(`WITH clock AS MATERIALIZED(SELECT ${dbTime} AS now)
|
|
96
|
+
SELECT clock.now,h.owner_key,h.url,h.revision,h.generation,s.owner_key AS capture_owner,s.event_name,s.arguments,s.active,
|
|
97
|
+
pg_catalog.floor(EXTRACT(epoch FROM s.expires_at)*1000)::pg_catalog.float8 AS expires_at
|
|
98
|
+
FROM clock LEFT JOIN public.emseepea_event_heads h ON h.namespace=$1 AND h.subscription_id=$2
|
|
99
|
+
LEFT JOIN public.emseepea_event_capture_subscriptions s ON s.namespace=h.namespace AND s.subscription_id=h.subscription_id AND s.generation=h.generation`, [namespace, i.id])).rows[0];
|
|
100
|
+
if (!row || !validMs(row.now))
|
|
101
|
+
return fail('UNAVAILABLE');
|
|
102
|
+
const base = { id: i.id, ownerKey: i.ownerKey, observedAt: row.now };
|
|
103
|
+
if (row.revision === null)
|
|
104
|
+
return { ...base, revision: null, generation: null, active: false, subscription: null };
|
|
105
|
+
if (row.owner_key !== i.ownerKey || typeof row.revision !== 'string' || !(row.generation === null || typeof row.generation === 'string'))
|
|
106
|
+
return fail('UNAVAILABLE');
|
|
107
|
+
if (row.url === null)
|
|
108
|
+
return { ...base, revision: row.revision, generation: row.generation, active: false, subscription: null };
|
|
109
|
+
if (row.url !== i.url || row.capture_owner !== i.ownerKey || row.event_name !== i.name || !validMs(row.expires_at) || typeof row.active !== 'boolean' || mcpEventSubscriptionIdentity(i.ownerKey, i.name, row.arguments, i.url) !== i.id)
|
|
110
|
+
return fail('UNAVAILABLE');
|
|
111
|
+
return { ...base, revision: row.revision, generation: row.generation, active: row.active && row.expires_at > row.now,
|
|
112
|
+
subscription: { id: i.id, ownerKey: i.ownerKey, name: i.name, arguments: row.arguments, url: i.url, expiresAt: row.expires_at } };
|
|
113
|
+
}, true);
|
|
114
|
+
},
|
|
115
|
+
async activate(input, invocation) {
|
|
116
|
+
const value = request(input), i = identity(value);
|
|
117
|
+
const expected = value.expectedRevision;
|
|
118
|
+
if (!(expected === null || typeof expected === 'string' && text(expected)) || !['new', 'renew'].includes(value.intent) || !Number.isSafeInteger(value.ttlMs) || Number(value.ttlMs) < 1 || Number(value.ttlMs) > 86400000)
|
|
119
|
+
fail('INVALID_INPUT');
|
|
120
|
+
const secret = text(value.secret, 100);
|
|
121
|
+
if (!secret.startsWith('whsec_'))
|
|
122
|
+
fail('INVALID_INPUT');
|
|
123
|
+
const decoded = Buffer.from(secret.slice(6), 'base64');
|
|
124
|
+
if (decoded.length < 24 || decoded.length > 64 || decoded.toString('base64') !== secret.slice(6))
|
|
125
|
+
fail('INVALID_INPUT');
|
|
126
|
+
return owned.run(options.mutationPool, invocation, async (run) => {
|
|
127
|
+
const { row, inserted } = await locked(run, i);
|
|
128
|
+
if (expected === null ? !inserted : inserted || row.revision !== expected)
|
|
129
|
+
return conflict();
|
|
130
|
+
if (row.url !== null && row.generation === null)
|
|
131
|
+
return fail('UNAVAILABLE');
|
|
132
|
+
const prior = await current(run, i, row.generation);
|
|
133
|
+
if (row.url !== null && row.url !== i.url)
|
|
134
|
+
return fail('UNAVAILABLE');
|
|
135
|
+
const now = (await run(`SELECT ${dbTime} AS now`)).rows[0]?.now;
|
|
136
|
+
if (!validMs(now))
|
|
137
|
+
return fail('UNAVAILABLE');
|
|
138
|
+
const active = row.url !== null && prior?.active === true && Number(prior.expires_at) > now;
|
|
139
|
+
if (value.intent === 'renew' ? !active : active)
|
|
140
|
+
return conflict();
|
|
141
|
+
const expiresAt = now + Number(value.ttlMs), generation = value.intent === 'renew' ? String(row.generation) : randomUUID(), revision = randomUUID();
|
|
142
|
+
if (value.intent === 'new') {
|
|
143
|
+
await run('UPDATE public.emseepea_event_capture_subscriptions SET active=false WHERE namespace=$1 AND subscription_id=$2 AND active', [namespace, i.id]);
|
|
144
|
+
await run('DELETE FROM public.emseepea_event_keys WHERE namespace=$1 AND subscription_id=$2', [namespace, i.id]);
|
|
145
|
+
await run(`INSERT INTO public.emseepea_event_capture_subscriptions(namespace,subscription_id,generation,owner_key,event_name,arguments,active,expires_at)
|
|
146
|
+
VALUES($1,$2,$3,$4,$5,$6::pg_catalog.jsonb,true,pg_catalog.to_timestamp($7::pg_catalog.float8/1000))`, [namespace, i.id, generation, i.ownerKey, i.name, JSON.stringify(i.arguments), expiresAt]);
|
|
147
|
+
await run(`INSERT INTO public.emseepea_event_keys(namespace,subscription_id,generation,secret,previous_secret,previous_until,verified_until)
|
|
148
|
+
VALUES($1,$2,$3,$4,NULL,NULL,pg_catalog.to_timestamp($5::pg_catalog.float8/1000))`, [namespace, i.id, generation, secret, Math.min(now + 300000, expiresAt)]);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const key = (await run('SELECT secret FROM public.emseepea_event_keys WHERE namespace=$1 AND subscription_id=$2 AND generation=$3', [namespace, i.id, generation])).rows[0];
|
|
152
|
+
if (typeof key?.secret !== 'string')
|
|
153
|
+
return fail('UNAVAILABLE');
|
|
154
|
+
await run(`UPDATE public.emseepea_event_keys SET previous_secret=CASE WHEN secret=$4 THEN previous_secret ELSE secret END,
|
|
155
|
+
previous_until=CASE WHEN secret=$4 THEN previous_until ELSE pg_catalog.to_timestamp($5::pg_catalog.float8/1000) END,
|
|
156
|
+
secret=$4,verified_until=pg_catalog.to_timestamp($5::pg_catalog.float8/1000) WHERE namespace=$1 AND subscription_id=$2 AND generation=$3`, [namespace, i.id, generation, secret, Math.min(now + 300000, expiresAt)]);
|
|
157
|
+
await run(`UPDATE public.emseepea_event_capture_subscriptions SET expires_at=pg_catalog.to_timestamp($4::pg_catalog.float8/1000) WHERE namespace=$1 AND subscription_id=$2 AND generation=$3`, [namespace, i.id, generation, expiresAt]);
|
|
158
|
+
}
|
|
159
|
+
await run('UPDATE public.emseepea_event_heads SET url=$3,revision=$4,generation=$5 WHERE namespace=$1 AND subscription_id=$2', [namespace, i.id, i.url, revision, generation]);
|
|
160
|
+
return { id: i.id, revision, generation, observedAt: now, expiresAt };
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
async revoke(input, invocation) {
|
|
164
|
+
const i = identity(request(input));
|
|
165
|
+
await owned.run(options.mutationPool, invocation, async (run) => {
|
|
166
|
+
await locked(run, i);
|
|
167
|
+
await run('UPDATE public.emseepea_event_capture_subscriptions SET active=false WHERE namespace=$1 AND subscription_id=$2 AND active', [namespace, i.id]);
|
|
168
|
+
await run("UPDATE public.emseepea_event_intents SET state='revoked' WHERE namespace=$1 AND subscription_id=$2 AND state='pending'", [namespace, i.id]);
|
|
169
|
+
await run('DELETE FROM public.emseepea_event_keys WHERE namespace=$1 AND subscription_id=$2', [namespace, i.id]);
|
|
170
|
+
await run('UPDATE public.emseepea_event_heads SET url=NULL,revision=$3 WHERE namespace=$1 AND subscription_id=$2', [namespace, i.id, randomUUID()]);
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
settle: owned.settle,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=events-postgres-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-postgres-lifecycle.js","sourceRoot":"","sources":["../src/events-postgres-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PostgresEventClient, PostgresEventInvocation } from "./events-postgres.js";
|
|
2
|
+
export interface PostgresEventMigrationClient extends PostgresEventClient {
|
|
3
|
+
release(error?: Error): void;
|
|
4
|
+
}
|
|
5
|
+
export interface PostgresEventMigrationPool {
|
|
6
|
+
connect(): Promise<PostgresEventMigrationClient>;
|
|
7
|
+
}
|
|
8
|
+
export declare class PostgresEventMigrationError extends Error {
|
|
9
|
+
readonly code: "INVALID_INPUT" | "DEADLINE" | "ABORTED" | "INCOMPATIBLE_SCHEMA" | "UNAVAILABLE" | "OUTCOME_UNKNOWN";
|
|
10
|
+
constructor(code: "INVALID_INPUT" | "DEADLINE" | "ABORTED" | "INCOMPATIBLE_SCHEMA" | "UNAVAILABLE" | "OUTCOME_UNKNOWN");
|
|
11
|
+
}
|
|
12
|
+
/** Deployment migrations. `createPostgresEventCapture` never applies them. */
|
|
13
|
+
export declare const postgresEventCaptureMigrations: readonly Readonly<{
|
|
14
|
+
version: 1;
|
|
15
|
+
revision: "capture-v1";
|
|
16
|
+
statements: readonly string[];
|
|
17
|
+
}>[];
|
|
18
|
+
/** Runs deployment migrations using only the acquired connection, which this function owns.
|
|
19
|
+
* Supported pools must also configure finite acquisition and query timeouts. A local timeout
|
|
20
|
+
* does not prove that PostgreSQL cancelled the operation. Connections with an uncertain outcome
|
|
21
|
+
* are discarded.
|
|
22
|
+
*/
|
|
23
|
+
export declare function migratePostgresEventCapture(pool: PostgresEventMigrationPool, invocation: PostgresEventInvocation): Promise<void>;
|
|
24
|
+
/** Creates lifecycle-managed migration operations for composed deployments. The standalone
|
|
25
|
+
* migration function retains its existing contract. This owner stops accepting work when
|
|
26
|
+
* shutdown begins, never closes the supplied pool, and does not treat a caller-facing
|
|
27
|
+
* deadline as proof of SQL cancellation. */
|
|
28
|
+
export declare function createPostgresEventCaptureMigrator(pool: PostgresEventMigrationPool): Readonly<{
|
|
29
|
+
migrate(invocation: PostgresEventInvocation): Promise<void>;
|
|
30
|
+
settle(invocation: PostgresEventInvocation): Promise<boolean>;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=events-postgres-migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-postgres-migrations.d.ts","sourceRoot":"","sources":["../src/events-postgres-migrations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEzF,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IAAG,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAA;CAAE;AAC1G,MAAM,WAAW,0BAA0B;IAAG,OAAO,IAAI,OAAO,CAAC,4BAA4B,CAAC,CAAA;CAAE;AAChG,qBAAa,2BAA4B,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,qBAAqB,GAAG,aAAa,GAAG,iBAAiB;gBAA1G,IAAI,EAAE,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,qBAAqB,GAAG,aAAa,GAAG,iBAAiB;CAGhI;AA2BD,8EAA8E;AAC9E,eAAO,MAAM,8BAA8B;;;;IAAuF,CAAC;AAuFnI;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,0BAA0B,EAAE,UAAU,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EtI;AAED;;;4CAG4C;AAC5C,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,0BAA0B;wBA8BrD,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;uBAsBxC,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;GAKtE"}
|