/**
 * Thrown by the ingest afterWrite hook when a concurrent worker has already
 * inserted slack_event_log for the same event_id. The throw propagates out of
 * writeEntry's SAVEPOINT, rolling back the duplicate memory write so exactly
 * one memory row exists per Slack event_id even under two-worker races.
 *
 * Caller maps to `{status: 'skipped_duplicate'}` at the public API boundary.
 */
export class DuplicateEventError extends Error {
    eventId;
    constructor(eventId) {
        super(`duplicate slack event_id: ${eventId}`);
        this.name = 'DuplicateEventError';
        this.eventId = eventId;
    }
}
export function hasSeenEvent(db, eventId) {
    const row = db.prepare(`SELECT 1 FROM slack_event_log WHERE event_id = ?`).get(eventId);
    return !!row;
}
export function markEventSeen(db, eventId, memoryId) {
    db.prepare(`INSERT OR IGNORE INTO slack_event_log (event_id, ingested_at, memory_id) VALUES (?, ?, ?)`)
        .run(eventId, new Date().toISOString(), memoryId);
}
export function lookupMemoryByEvent(db, eventId) {
    const row = db.prepare(`SELECT memory_id FROM slack_event_log WHERE event_id = ?`).get(eventId);
    return row?.memory_id ?? null;
}
//# sourceMappingURL=idempotency.js.map