@relaycast/engine 2.5.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/node/database.d.ts +8 -4
- package/dist/adapters/node/database.d.ts.map +1 -1
- package/dist/adapters/node/database.js +48 -3
- package/dist/adapters/node/database.js.map +1 -1
- package/dist/adapters/node/event-queue.d.ts +54 -6
- package/dist/adapters/node/event-queue.d.ts.map +1 -1
- package/dist/adapters/node/event-queue.js +129 -13
- package/dist/adapters/node/event-queue.js.map +1 -1
- package/dist/adapters/node/index.d.ts +7 -2
- package/dist/adapters/node/index.d.ts.map +1 -1
- package/dist/adapters/node/index.js +7 -3
- package/dist/adapters/node/index.js.map +1 -1
- package/dist/engine/console.d.ts +6 -0
- package/dist/engine/console.d.ts.map +1 -1
- package/dist/engine/console.js +9 -2
- package/dist/engine/console.js.map +1 -1
- package/dist/engine/deliveryWrites.d.ts +27 -0
- package/dist/engine/deliveryWrites.d.ts.map +1 -0
- package/dist/engine/deliveryWrites.js +83 -0
- package/dist/engine/deliveryWrites.js.map +1 -0
- package/dist/engine/dm.d.ts.map +1 -1
- package/dist/engine/dm.js +61 -49
- package/dist/engine/dm.js.map +1 -1
- package/dist/engine/eventQueue.d.ts +74 -0
- package/dist/engine/eventQueue.d.ts.map +1 -1
- package/dist/engine/eventQueue.js +105 -1
- package/dist/engine/eventQueue.js.map +1 -1
- package/dist/engine/groupDm.d.ts +1 -4
- package/dist/engine/groupDm.d.ts.map +1 -1
- package/dist/engine/groupDm.js +59 -58
- package/dist/engine/groupDm.js.map +1 -1
- package/dist/engine/message.d.ts +1 -5
- package/dist/engine/message.d.ts.map +1 -1
- package/dist/engine/message.js +88 -62
- package/dist/engine/message.js.map +1 -1
- package/dist/engine/receipt.d.ts.map +1 -1
- package/dist/engine/receipt.js +23 -18
- package/dist/engine/receipt.js.map +1 -1
- package/dist/engine/thread.d.ts +1 -4
- package/dist/engine/thread.d.ts.map +1 -1
- package/dist/engine/thread.js +31 -33
- package/dist/engine/thread.js.map +1 -1
- package/dist/engine/wsTransform.d.ts.map +1 -1
- package/dist/engine/wsTransform.js +1 -0
- package/dist/engine/wsTransform.js.map +1 -1
- package/dist/engine.js +3 -3
- package/dist/engine.js.map +1 -1
- package/dist/env.d.ts +4 -4
- package/dist/env.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/origin.d.ts +19 -15
- package/dist/lib/origin.d.ts.map +1 -1
- package/dist/lib/origin.js +34 -29
- package/dist/lib/origin.js.map +1 -1
- package/dist/lib/serverTelemetry.js +3 -3
- package/dist/lib/serverTelemetry.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +6 -0
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +5 -1
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/logger.js +5 -5
- package/dist/middleware/logger.js.map +1 -1
- package/dist/ports/database.d.ts +84 -6
- package/dist/ports/database.d.ts.map +1 -1
- package/dist/ports/database.js +53 -1
- package/dist/ports/database.js.map +1 -1
- package/dist/ports/event-queue.d.ts +20 -5
- package/dist/ports/event-queue.d.ts.map +1 -1
- package/dist/ports/index.d.ts +2 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -1
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/realtime.d.ts +2 -2
- package/dist/ports/realtime.d.ts.map +1 -1
- package/dist/routes/action.d.ts.map +1 -1
- package/dist/routes/action.js +6 -5
- package/dist/routes/action.js.map +1 -1
- package/dist/routes/agent.d.ts.map +1 -1
- package/dist/routes/agent.js +19 -14
- package/dist/routes/agent.js.map +1 -1
- package/dist/routes/channel.d.ts.map +1 -1
- package/dist/routes/channel.js +19 -18
- package/dist/routes/channel.js.map +1 -1
- package/dist/routes/dm.d.ts.map +1 -1
- package/dist/routes/dm.js +13 -6
- package/dist/routes/dm.js.map +1 -1
- package/dist/routes/file.d.ts.map +1 -1
- package/dist/routes/file.js +3 -2
- package/dist/routes/file.js.map +1 -1
- package/dist/routes/groupDm.d.ts.map +1 -1
- package/dist/routes/groupDm.js +13 -6
- package/dist/routes/groupDm.js.map +1 -1
- package/dist/routes/inboundWebhook.d.ts.map +1 -1
- package/dist/routes/inboundWebhook.js +3 -2
- package/dist/routes/inboundWebhook.js.map +1 -1
- package/dist/routes/message.d.ts.map +1 -1
- package/dist/routes/message.js +18 -7
- package/dist/routes/message.js.map +1 -1
- package/dist/routes/reaction.d.ts.map +1 -1
- package/dist/routes/reaction.js +5 -4
- package/dist/routes/reaction.js.map +1 -1
- package/dist/routes/receipt.d.ts.map +1 -1
- package/dist/routes/receipt.js +3 -2
- package/dist/routes/receipt.js.map +1 -1
- package/dist/routes/thread.d.ts.map +1 -1
- package/dist/routes/thread.js +13 -6
- package/dist/routes/thread.js.map +1 -1
- package/dist/routes/webhookOutbox.d.ts +19 -0
- package/dist/routes/webhookOutbox.d.ts.map +1 -0
- package/dist/routes/webhookOutbox.js +33 -0
- package/dist/routes/webhookOutbox.js.map +1 -0
- package/package.json +3 -3
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import Database, { type RunResult } from 'better-sqlite3';
|
|
2
|
-
import type { EngineDb } from '../../ports/database.js';
|
|
3
|
-
/**
|
|
4
|
-
|
|
2
|
+
import type { EngineDb, TransactionCapability } from '../../ports/database.js';
|
|
3
|
+
/**
|
|
4
|
+
* The engine handle specialized to better-sqlite3's synchronous run-result,
|
|
5
|
+
* with the optional transaction capability attached (better-sqlite3 supports
|
|
6
|
+
* interactive transactions, unlike D1).
|
|
7
|
+
*/
|
|
8
|
+
export type NodeEngineDb = EngineDb<RunResult> & TransactionCapability;
|
|
5
9
|
export interface SqliteDbHandle {
|
|
6
10
|
db: NodeEngineDb;
|
|
7
11
|
/** The raw better-sqlite3 connection (for migrations, pragmas, backups). */
|
|
@@ -12,7 +16,7 @@ export interface SqliteDbHandle {
|
|
|
12
16
|
* (created if absent) or `':memory:'` for tests. Sets WAL + foreign keys.
|
|
13
17
|
*
|
|
14
18
|
* The better-sqlite3 driver is synchronous; Drizzle query builders are thenable
|
|
15
|
-
* so the engine's `await db.select()...` works unchanged. Only the sync
|
|
19
|
+
* so the engine's `await db.select()...` works unchanged. Only the sync->async
|
|
16
20
|
* surface kind is bridged by the cast here — the run-result type (`RunResult`)
|
|
17
21
|
* is preserved, so {@link NodeEngineDb} stays precisely typed.
|
|
18
22
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/database.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/database.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG1D,OAAO,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,qBAAqB,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,YAAY,CAAC;IACjB,4EAA4E;IAC5E,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;CAC3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CA8CxD;AAwBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAuC3E"}
|
|
@@ -9,17 +9,62 @@ import * as schema from '../../db/schema.js';
|
|
|
9
9
|
* (created if absent) or `':memory:'` for tests. Sets WAL + foreign keys.
|
|
10
10
|
*
|
|
11
11
|
* The better-sqlite3 driver is synchronous; Drizzle query builders are thenable
|
|
12
|
-
* so the engine's `await db.select()...` works unchanged. Only the sync
|
|
12
|
+
* so the engine's `await db.select()...` works unchanged. Only the sync->async
|
|
13
13
|
* surface kind is bridged by the cast here — the run-result type (`RunResult`)
|
|
14
14
|
* is preserved, so {@link NodeEngineDb} stays precisely typed.
|
|
15
15
|
*/
|
|
16
16
|
export function getSqliteDb(path) {
|
|
17
17
|
const sqlite = new Database(path);
|
|
18
|
-
sqlite
|
|
19
|
-
sqlite.pragma('foreign_keys = ON');
|
|
18
|
+
configureSqlite(sqlite, { enableWal: true });
|
|
20
19
|
const db = drizzle(sqlite, { schema });
|
|
20
|
+
const isolatedTransactions = path !== ':memory:';
|
|
21
|
+
// Attach the transaction capability (`runAtomicWrites` detects it on the
|
|
22
|
+
// handle and prefers it over a batch).
|
|
23
|
+
//
|
|
24
|
+
// Drizzle's better-sqlite3 `db.transaction()` requires a synchronous
|
|
25
|
+
// callback (better-sqlite3's native wrapper commits when the sync call
|
|
26
|
+
// returns), but engine write paths are async. For file-backed databases we
|
|
27
|
+
// therefore open the transaction on a short-lived, dedicated connection so
|
|
28
|
+
// unrelated statements on the main handle cannot join the open transaction.
|
|
29
|
+
// `:memory:` databases are connection-local, so tests keep the shared
|
|
30
|
+
// connection while still serializing transactional callers.
|
|
31
|
+
let txTail = Promise.resolve();
|
|
32
|
+
db.withTransaction = (fn) => {
|
|
33
|
+
const run = async () => {
|
|
34
|
+
const txSqlite = isolatedTransactions ? new Database(path) : sqlite;
|
|
35
|
+
try {
|
|
36
|
+
if (isolatedTransactions)
|
|
37
|
+
configureSqlite(txSqlite);
|
|
38
|
+
const txDb = (isolatedTransactions
|
|
39
|
+
? drizzle(txSqlite, { schema })
|
|
40
|
+
: db);
|
|
41
|
+
txSqlite.exec('BEGIN IMMEDIATE');
|
|
42
|
+
const result = await fn(txDb);
|
|
43
|
+
txSqlite.exec('COMMIT');
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (txSqlite.inTransaction)
|
|
48
|
+
txSqlite.exec('ROLLBACK');
|
|
49
|
+
throw err;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
if (isolatedTransactions)
|
|
53
|
+
txSqlite.close();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const result = txTail.then(run);
|
|
57
|
+
txTail = result.then(() => undefined, () => undefined);
|
|
58
|
+
return result;
|
|
59
|
+
};
|
|
21
60
|
return { db, sqlite };
|
|
22
61
|
}
|
|
62
|
+
function configureSqlite(sqlite, options = {}) {
|
|
63
|
+
if (options.enableWal)
|
|
64
|
+
sqlite.pragma('journal_mode = WAL');
|
|
65
|
+
sqlite.pragma('foreign_keys = ON');
|
|
66
|
+
sqlite.pragma('busy_timeout = 5000');
|
|
67
|
+
}
|
|
23
68
|
function migrationsDir() {
|
|
24
69
|
// dist/adapters/node/database.js -> dist/db/migrations
|
|
25
70
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/adapters/node/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,QAA4B,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/adapters/node/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,63 @@
|
|
|
1
1
|
import type { EventQueue, QueuedEvent } from '../../ports/event-queue.js';
|
|
2
2
|
import type { EngineDb } from '../../ports/database.js';
|
|
3
|
+
export interface DurableEventQueueOptions {
|
|
4
|
+
/** Poll cadence for due rows. 0 disables the timer (tests drive `poll()` directly). Default 5s. */
|
|
5
|
+
pollIntervalMs?: number;
|
|
6
|
+
/** Delay before the first retry; doubles per attempt. Default 30s. */
|
|
7
|
+
baseBackoffMs?: number;
|
|
8
|
+
/** Retry backoff ceiling. Default 15 min. */
|
|
9
|
+
maxBackoffMs?: number;
|
|
10
|
+
/** How long a claimed row stays invisible before a crashed worker's claim expires. Default 60s. */
|
|
11
|
+
leaseMs?: number;
|
|
12
|
+
/** Max rows claimed per poll pass. Default 25. */
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
/** How often settled rows older than 24h are pruned. Default 1h. */
|
|
15
|
+
cleanupIntervalMs?: number;
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
|
-
*
|
|
5
|
-
* `send`
|
|
6
|
-
*
|
|
7
|
-
*
|
|
18
|
+
* Durable webhook delivery for self-host, replacing the Cloudflare Queue + DLQ.
|
|
19
|
+
* `send` persists a `pending_events` outbox row first, then a background poller
|
|
20
|
+
* claims due rows and fans them out via `deliverEvent` (HMAC signing and
|
|
21
|
+
* retryable-vs-terminal classification unchanged). Success deletes the row;
|
|
22
|
+
* terminal failures settle it as `failed`; retryable failures back off
|
|
23
|
+
* exponentially and survive process restarts — `start()` resumes whatever is due.
|
|
8
24
|
*/
|
|
9
|
-
export declare class
|
|
25
|
+
export declare class DurableEventQueue implements EventQueue {
|
|
10
26
|
private readonly db;
|
|
11
27
|
private readonly onError;
|
|
12
|
-
|
|
28
|
+
private readonly pollIntervalMs;
|
|
29
|
+
private readonly baseBackoffMs;
|
|
30
|
+
private readonly maxBackoffMs;
|
|
31
|
+
private readonly leaseMs;
|
|
32
|
+
private readonly batchSize;
|
|
33
|
+
private readonly cleanupIntervalMs;
|
|
34
|
+
private timer;
|
|
35
|
+
private polling;
|
|
36
|
+
private lastCleanupAt;
|
|
37
|
+
constructor(db: EngineDb, onError?: (err: unknown, ctx: Record<string, unknown>) => void, options?: DurableEventQueueOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Persist the outbox row first (awaited — the event is durable once `send`
|
|
40
|
+
* resolves), then kick an immediate poll so delivery is prompt. The poll path
|
|
41
|
+
* claims rows atomically, so the kick and the interval timer never double-deliver.
|
|
42
|
+
*
|
|
43
|
+
* When the engine send path already inserted the row (`message.outboxId` set,
|
|
44
|
+
* see routes/webhookOutbox.ts), skip the insert — the poller picks the existing
|
|
45
|
+
* row up; inserting again would deliver the event twice.
|
|
46
|
+
*/
|
|
13
47
|
send(message: QueuedEvent): Promise<void>;
|
|
48
|
+
/** Start the interval poller and immediately resume any rows left over from a previous run. */
|
|
49
|
+
start(): void;
|
|
50
|
+
/** Stop the interval poller (server shutdown / test teardown). */
|
|
51
|
+
stop(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Claim and deliver every currently-due row, then prune old settled rows on
|
|
54
|
+
* the cleanup cadence. Serialized per instance: overlapping calls coalesce
|
|
55
|
+
* into the in-flight pass.
|
|
56
|
+
*/
|
|
57
|
+
poll(): Promise<void>;
|
|
58
|
+
private process;
|
|
59
|
+
private maybeCleanup;
|
|
14
60
|
}
|
|
61
|
+
export { DurableEventQueue as InProcessEventQueue };
|
|
62
|
+
export type InProcessEventQueueOptions = DurableEventQueueOptions;
|
|
15
63
|
//# sourceMappingURL=event-queue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"event-queue.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/event-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAoBxD,MAAM,WAAW,wBAAwB;IACvC,mGAAmG;IACnG,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,YAAW,UAAU;IAYhD,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAZ1B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAK;gBAGP,EAAE,EAAE,QAAQ,EACZ,OAAO,GAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAe,EACzF,OAAO,GAAE,wBAA6B;IAUxC;;;;;;;;OAQG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/C,+FAA+F;IAC/F,KAAK,IAAI,IAAI;IAWb,kEAAkE;IAClE,IAAI,IAAI,IAAI;IAKZ;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAsBb,OAAO;YAkCP,YAAY;CAM3B;AAED,OAAO,EAAE,iBAAiB,IAAI,mBAAmB,EAAE,CAAC;AACpD,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,CAAC"}
|
|
@@ -1,27 +1,143 @@
|
|
|
1
1
|
import { deliverEvent } from '../../engine/eventDelivery.js';
|
|
2
|
+
import { enqueueEvent, claimDueEvents, completeEvent, failEvent, failExhaustedDueEvents, rescheduleEvent, cleanupOldEvents, } from '../../engine/eventQueue.js';
|
|
3
|
+
const DEFAULT_POLL_INTERVAL_MS = 5_000;
|
|
4
|
+
const DEFAULT_BASE_BACKOFF_MS = 30_000;
|
|
5
|
+
const DEFAULT_MAX_BACKOFF_MS = 15 * 60_000;
|
|
6
|
+
const DEFAULT_LEASE_MS = 60_000;
|
|
7
|
+
const DEFAULT_BATCH_SIZE = 25;
|
|
8
|
+
const DEFAULT_CLEANUP_INTERVAL_MS = 60 * 60_000;
|
|
2
9
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `send`
|
|
5
|
-
*
|
|
6
|
-
*
|
|
10
|
+
* Durable webhook delivery for self-host, replacing the Cloudflare Queue + DLQ.
|
|
11
|
+
* `send` persists a `pending_events` outbox row first, then a background poller
|
|
12
|
+
* claims due rows and fans them out via `deliverEvent` (HMAC signing and
|
|
13
|
+
* retryable-vs-terminal classification unchanged). Success deletes the row;
|
|
14
|
+
* terminal failures settle it as `failed`; retryable failures back off
|
|
15
|
+
* exponentially and survive process restarts — `start()` resumes whatever is due.
|
|
7
16
|
*/
|
|
8
|
-
export class
|
|
17
|
+
export class DurableEventQueue {
|
|
9
18
|
db;
|
|
10
19
|
onError;
|
|
11
|
-
|
|
20
|
+
pollIntervalMs;
|
|
21
|
+
baseBackoffMs;
|
|
22
|
+
maxBackoffMs;
|
|
23
|
+
leaseMs;
|
|
24
|
+
batchSize;
|
|
25
|
+
cleanupIntervalMs;
|
|
26
|
+
timer;
|
|
27
|
+
polling = false;
|
|
28
|
+
lastCleanupAt = 0;
|
|
29
|
+
constructor(db, onError = () => { }, options = {}) {
|
|
12
30
|
this.db = db;
|
|
13
31
|
this.onError = onError;
|
|
32
|
+
this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
33
|
+
this.baseBackoffMs = options.baseBackoffMs ?? DEFAULT_BASE_BACKOFF_MS;
|
|
34
|
+
this.maxBackoffMs = options.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
35
|
+
this.leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;
|
|
36
|
+
this.batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
37
|
+
this.cleanupIntervalMs = options.cleanupIntervalMs ?? DEFAULT_CLEANUP_INTERVAL_MS;
|
|
14
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Persist the outbox row first (awaited — the event is durable once `send`
|
|
41
|
+
* resolves), then kick an immediate poll so delivery is prompt. The poll path
|
|
42
|
+
* claims rows atomically, so the kick and the interval timer never double-deliver.
|
|
43
|
+
*
|
|
44
|
+
* When the engine send path already inserted the row (`message.outboxId` set,
|
|
45
|
+
* see routes/webhookOutbox.ts), skip the insert — the poller picks the existing
|
|
46
|
+
* row up; inserting again would deliver the event twice.
|
|
47
|
+
*/
|
|
15
48
|
async send(message) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
49
|
+
if (!message.outboxId) {
|
|
50
|
+
await enqueueEvent(this.db, message.workspaceId, message.type, message.data);
|
|
51
|
+
}
|
|
52
|
+
void this.poll();
|
|
53
|
+
}
|
|
54
|
+
/** Start the interval poller and immediately resume any rows left over from a previous run. */
|
|
55
|
+
start() {
|
|
56
|
+
if (this.pollIntervalMs > 0 && !this.timer) {
|
|
57
|
+
this.timer = setInterval(() => {
|
|
58
|
+
void this.poll();
|
|
59
|
+
}, this.pollIntervalMs);
|
|
60
|
+
// Don't keep the Node process alive solely for the outbox poller.
|
|
61
|
+
this.timer.unref?.();
|
|
62
|
+
}
|
|
63
|
+
void this.poll();
|
|
64
|
+
}
|
|
65
|
+
/** Stop the interval poller (server shutdown / test teardown). */
|
|
66
|
+
stop() {
|
|
67
|
+
if (this.timer)
|
|
68
|
+
clearInterval(this.timer);
|
|
69
|
+
this.timer = undefined;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Claim and deliver every currently-due row, then prune old settled rows on
|
|
73
|
+
* the cleanup cadence. Serialized per instance: overlapping calls coalesce
|
|
74
|
+
* into the in-flight pass.
|
|
75
|
+
*/
|
|
76
|
+
async poll() {
|
|
77
|
+
if (this.polling)
|
|
78
|
+
return;
|
|
79
|
+
this.polling = true;
|
|
80
|
+
try {
|
|
81
|
+
for (;;) {
|
|
82
|
+
await failExhaustedDueEvents(this.db);
|
|
83
|
+
const claimed = await claimDueEvents(this.db, {
|
|
84
|
+
limit: this.batchSize,
|
|
85
|
+
leaseMs: this.leaseMs,
|
|
86
|
+
});
|
|
87
|
+
if (claimed.length === 0)
|
|
88
|
+
break;
|
|
89
|
+
await Promise.all(claimed.map((event) => this.process(event)));
|
|
90
|
+
if (claimed.length < this.batchSize)
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
await this.maybeCleanup();
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
this.onError(err, { source: 'node.event_queue', op: 'poll' });
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
this.polling = false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async process(event) {
|
|
103
|
+
try {
|
|
104
|
+
const summary = await deliverEvent(this.db, event.workspaceId, event.eventType, event.payload);
|
|
105
|
+
if (summary.failed > 0) {
|
|
106
|
+
// deliverEvent resolved with failures and no retryables — terminal
|
|
107
|
+
// (non-408/429 4xx). Settle the row; retrying won't change the outcome.
|
|
108
|
+
await failEvent(this.db, event.id, `terminal delivery failure: ${summary.failed} of ${summary.attempted} subscriber(s)`);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
await completeEvent(this.db, event.id);
|
|
20
112
|
}
|
|
21
|
-
|
|
22
|
-
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
// deliverEvent throws only for retryable conditions (coded 503 on
|
|
116
|
+
// retryable webhook failures, or a transient subscription-lookup error).
|
|
117
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
118
|
+
if (event.attempts >= event.maxAttempts) {
|
|
119
|
+
await failEvent(this.db, event.id, `${message} (attempts exhausted)`);
|
|
120
|
+
this.onError(err, {
|
|
121
|
+
source: 'node.event_queue',
|
|
122
|
+
op: 'deliver',
|
|
123
|
+
event_type: event.eventType,
|
|
124
|
+
attempts: event.attempts,
|
|
125
|
+
settled: 'failed',
|
|
126
|
+
});
|
|
23
127
|
}
|
|
24
|
-
|
|
128
|
+
else {
|
|
129
|
+
const backoff = Math.min(this.baseBackoffMs * 2 ** (event.attempts - 1), this.maxBackoffMs);
|
|
130
|
+
await rescheduleEvent(this.db, event.id, message, backoff);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async maybeCleanup() {
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
if (now - this.lastCleanupAt < this.cleanupIntervalMs)
|
|
137
|
+
return;
|
|
138
|
+
this.lastCleanupAt = now;
|
|
139
|
+
await cleanupOldEvents(this.db);
|
|
25
140
|
}
|
|
26
141
|
}
|
|
142
|
+
export { DurableEventQueue as InProcessEventQueue };
|
|
27
143
|
//# sourceMappingURL=event-queue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../../src/adapters/node/event-queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"event-queue.js","sourceRoot":"","sources":["../../../src/adapters/node/event-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,12 +7,13 @@ import { InProcessRealtime } from './realtime.js';
|
|
|
7
7
|
import { InProcessPresence, type InProcessPresenceOptions } from './presence.js';
|
|
8
8
|
import { InProcessRateLimiter } from './rate-limit.js';
|
|
9
9
|
import { InProcessKeyValueStore } from './kv.js';
|
|
10
|
-
import { InProcessEventQueue } from './event-queue.js';
|
|
10
|
+
import { DurableEventQueue, InProcessEventQueue, type DurableEventQueueOptions } from './event-queue.js';
|
|
11
11
|
import { LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX } from './files.js';
|
|
12
|
-
export { InProcessRealtime, InProcessPresence, InProcessRateLimiter, InProcessKeyValueStore, InProcessEventQueue, LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX, getSqliteDb, runMigrations, };
|
|
12
|
+
export { InProcessRealtime, InProcessPresence, InProcessRateLimiter, InProcessKeyValueStore, InProcessEventQueue, DurableEventQueue, LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX, getSqliteDb, runMigrations, };
|
|
13
13
|
export type { EngineSocket, SocketHandle } from './realtime.js';
|
|
14
14
|
export type { SqliteDbHandle } from './database.js';
|
|
15
15
|
export type { InProcessPresenceOptions } from './presence.js';
|
|
16
|
+
export type { DurableEventQueueOptions, InProcessEventQueueOptions } from './event-queue.js';
|
|
16
17
|
export interface NodeRuntimeOptions {
|
|
17
18
|
/** SQLite file path, or ':memory:' for tests. */
|
|
18
19
|
dbPath: string;
|
|
@@ -34,6 +35,8 @@ export interface NodeRuntimeOptions {
|
|
|
34
35
|
config?: EngineConfig;
|
|
35
36
|
/** Presence TTL / sweep tuning (tests use short windows). */
|
|
36
37
|
presence?: InProcessPresenceOptions;
|
|
38
|
+
/** Durable webhook outbox tuning (poll interval, backoff, cleanup cadence). */
|
|
39
|
+
eventQueue?: DurableEventQueueOptions;
|
|
37
40
|
}
|
|
38
41
|
/**
|
|
39
42
|
* The assembled Node runtime: the {@link EngineDeps} to pass to `createEngine`,
|
|
@@ -44,6 +47,8 @@ export interface NodeRuntime {
|
|
|
44
47
|
deps: EngineDeps;
|
|
45
48
|
realtime: InProcessRealtime;
|
|
46
49
|
presence: InProcessPresence;
|
|
50
|
+
/** Durable webhook outbox; already started — exposed for graceful shutdown and tests. */
|
|
51
|
+
webhookQueue: DurableEventQueue;
|
|
47
52
|
/** `fetch`-style handler for the `${FILE_ROUTE_PREFIX}` upload/download routes. */
|
|
48
53
|
fileHandler: (request: Request) => Promise<Response>;
|
|
49
54
|
handle: SqliteDbHandle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAI9D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAI9D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEzF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,aAAa,GACd,CAAC;AACF,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,oDAAoD;IACpD,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC,+EAA+E;IAC/E,UAAU,CAAC,EAAE,wBAAwB,CAAC;CACvC;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,yFAAyF;IACzF,YAAY,EAAE,iBAAiB,CAAC;IAChC,mFAAmF;IACnF,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,EAAE,cAAc,CAAC;IACvB,gDAAgD;IAChD,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAqE1E"}
|
|
@@ -7,9 +7,9 @@ import { InProcessRealtime } from './realtime.js';
|
|
|
7
7
|
import { InProcessPresence } from './presence.js';
|
|
8
8
|
import { InProcessRateLimiter } from './rate-limit.js';
|
|
9
9
|
import { InProcessKeyValueStore } from './kv.js';
|
|
10
|
-
import { InProcessEventQueue } from './event-queue.js';
|
|
10
|
+
import { DurableEventQueue, InProcessEventQueue } from './event-queue.js';
|
|
11
11
|
import { LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX } from './files.js';
|
|
12
|
-
export { InProcessRealtime, InProcessPresence, InProcessRateLimiter, InProcessKeyValueStore, InProcessEventQueue, LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX, getSqliteDb, runMigrations, };
|
|
12
|
+
export { InProcessRealtime, InProcessPresence, InProcessRateLimiter, InProcessKeyValueStore, InProcessEventQueue, DurableEventQueue, LocalFileStorage, createFileRouteHandler, FILE_ROUTE_PREFIX, getSqliteDb, runMigrations, };
|
|
13
13
|
/**
|
|
14
14
|
* Construct the in-process Node + SQLite runtime. Wires the realtime bus to the
|
|
15
15
|
* presence tracker, opens (and optionally migrates) the database, and returns
|
|
@@ -38,7 +38,9 @@ export function createNodeRuntime(options) {
|
|
|
38
38
|
const rateLimiter = new InProcessRateLimiter();
|
|
39
39
|
const kv = new InProcessKeyValueStore();
|
|
40
40
|
const fileStorage = new LocalFileStorage(options.fileDir ?? `${process.cwd()}/relaycast-files`, options.baseUrl, options.fileSecret ?? randomBytes(32).toString('hex'));
|
|
41
|
-
const webhookQueue = new
|
|
41
|
+
const webhookQueue = new DurableEventQueue(db, (err, ctx) => telemetry.captureException(err, ctx), options.eventQueue);
|
|
42
|
+
// Resume any deliveries left over from a previous process (the outbox's point).
|
|
43
|
+
webhookQueue.start();
|
|
42
44
|
const auth = options.auth ?? new SqliteApiKeyAuthProvider();
|
|
43
45
|
const entitlements = options.entitlements ?? new StaticEntitlementsProvider(kv);
|
|
44
46
|
const deps = {
|
|
@@ -59,10 +61,12 @@ export function createNodeRuntime(options) {
|
|
|
59
61
|
deps,
|
|
60
62
|
realtime,
|
|
61
63
|
presence,
|
|
64
|
+
webhookQueue,
|
|
62
65
|
fileHandler: createFileRouteHandler(fileStorage),
|
|
63
66
|
handle,
|
|
64
67
|
close() {
|
|
65
68
|
presence.stop();
|
|
69
|
+
webhookQueue.stop();
|
|
66
70
|
kv.dispose();
|
|
67
71
|
try {
|
|
68
72
|
handle.sqlite.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAiC,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/node/index.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/console.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { getDb } from '../db/index.js';
|
|
2
|
+
import type { AtomicWrite } from '../ports/database.js';
|
|
2
3
|
type Db = ReturnType<typeof getDb>;
|
|
3
4
|
export interface LogMessageInput {
|
|
4
5
|
workspaceId: string;
|
|
@@ -22,6 +23,11 @@ export interface ListMessageLogsOptions {
|
|
|
22
23
|
conversationId?: string;
|
|
23
24
|
deliveryKind?: 'channel' | 'dm';
|
|
24
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the message-log insert without executing it, so send paths can include
|
|
28
|
+
* it in an atomic statement list (see {@link runAtomicWrites}).
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildMessageLogWrite(db: Db, input: LogMessageInput): AtomicWrite;
|
|
25
31
|
export declare function logMessage(db: Db, input: LogMessageInput): Promise<void>;
|
|
26
32
|
export declare function listMessageLogs(db: Db, workspaceId: string, opts?: ListMessageLogsOptions): Promise<{
|
|
27
33
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/engine/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/engine/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,KAAK,EAAE,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AAEnC,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACjC;AAUD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,WAAW,CAmBhF;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9E;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,sBAA2B;;;;;;;;;;;;;;;;KAmDlC;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,UAAU,SAAI;;;;;;;;;;;GA6Bf;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,UAAU,SAAI,EACd,KAAK,SAAK;;;;;;;;KAuCX;AAED,wBAAsB,YAAY,CAChC,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,UAAU,SAAI;;;;;;;;;;;;;;;;;GAyDf"}
|
package/dist/engine/console.js
CHANGED
|
@@ -7,8 +7,12 @@ function clampLimit(limit) {
|
|
|
7
7
|
function getWindowStart(days) {
|
|
8
8
|
return new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Build the message-log insert without executing it, so send paths can include
|
|
12
|
+
* it in an atomic statement list (see {@link runAtomicWrites}).
|
|
13
|
+
*/
|
|
14
|
+
export function buildMessageLogWrite(db, input) {
|
|
15
|
+
return db
|
|
12
16
|
.insert(messageLogs)
|
|
13
17
|
.values({
|
|
14
18
|
id: generateId(),
|
|
@@ -27,6 +31,9 @@ export async function logMessage(db, input) {
|
|
|
27
31
|
})
|
|
28
32
|
.onConflictDoNothing();
|
|
29
33
|
}
|
|
34
|
+
export async function logMessage(db, input) {
|
|
35
|
+
await buildMessageLogWrite(db, input);
|
|
36
|
+
}
|
|
30
37
|
export async function listMessageLogs(db, workspaceId, opts = {}) {
|
|
31
38
|
const conditions = [eq(messageLogs.workspaceId, workspaceId)];
|
|
32
39
|
if (opts.before)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/engine/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/engine/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AtomicWrite, EngineDb } from '../ports/database.js';
|
|
2
|
+
type DeliveryMode = 'immediate' | 'next-tool-call';
|
|
3
|
+
type ChannelDeliveryReason = 'message' | 'mention' | 'thread-reply';
|
|
4
|
+
export interface DeliveryFanoutRecord {
|
|
5
|
+
id: string;
|
|
6
|
+
agentId: string;
|
|
7
|
+
reason: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildChannelDeliveryWrite(db: EngineDb, input: {
|
|
10
|
+
workspaceId: string;
|
|
11
|
+
messageId: string;
|
|
12
|
+
channelId: string;
|
|
13
|
+
senderAgentId: string;
|
|
14
|
+
mode: DeliveryMode;
|
|
15
|
+
reason?: ChannelDeliveryReason;
|
|
16
|
+
mentionHandles?: readonly string[];
|
|
17
|
+
}): AtomicWrite;
|
|
18
|
+
export declare function buildGroupDmDeliveryWrite(db: EngineDb, input: {
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
messageId: string;
|
|
21
|
+
conversationId: string;
|
|
22
|
+
senderAgentId: string;
|
|
23
|
+
mode: DeliveryMode;
|
|
24
|
+
}): AtomicWrite;
|
|
25
|
+
export declare function fetchDeliveryFanoutRecords(db: EngineDb, messageId: string): Promise<DeliveryFanoutRecord[]>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=deliveryWrites.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliveryWrites.d.ts","sourceRoot":"","sources":["../../src/engine/deliveryWrites.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAElE,KAAK,YAAY,GAAG,WAAW,GAAG,gBAAgB,CAAC;AACnD,KAAK,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE;IACL,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GACA,WAAW,CAiCb;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE;IACL,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,YAAY,CAAC;CACpB,GACA,WAAW,CAgCb;AAED,wBAAsB,0BAA0B,CAC9C,EAAE,EAAE,QAAQ,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAejC"}
|