/** * DynamoDBOutboxStore — OutboxStore adapter backed by AWS DynamoDB. * * The outbox pattern requires a transactional guarantee: when a command * mutates entity state, the semantic event must be persisted atomically * with that state change. DynamoDB provides this via TransactWriteItems, * which groups up to 100 actions (Put / Update / Delete / ConditionCheck) * into a single ACID transaction. * * Concurrency model for `claim`: dispatchers scan the table for pending * entries and atomically update each to "claimed" via a conditional * UpdateItem with `ConditionExpression: status = 'pending'`. The first * worker to win the condition race claims the entry; the rest get a * `ConditionalCheckFailedException` and move on. This provides safe * concurrent dispatch without explicit row locks. * * Stream integration: the companion `manifest_outbox_table` is configured * with DynamoDB Streams. A Lambda or Kinesis consumer can process the * stream for at-least-once delivery to downstream sinks (SNS, SQS, EventBridge). * The `claim`/`markDelivered`/`markFailed` methods are the pull-based * alternative; stream consumers implement their own tracking. * * Item shape: * { * pk: "OUTBOX#", // partition key * sk: "META", // sort key (single-table friendly) * entry_id: string, * enqueued_at: number, // ms since epoch * event: object, // EmittedEvent payload * status: "pending" | "delivered" | "failed", * attempts: number, * last_error: string | null, * claimed_at: number | null, * delivered_at: number | null, * failed_at: number | null, * subject_entity: string | null, // optional projection * subject_id: string | null, * } * * DO NOT import this file in browser code — it requires the AWS SDK. */ import type { OutboxEntry, OutboxStore } from '../outbox-store'; export interface DynamoDBOutboxStoreOptions { /** * An initialized DynamoDB DocumentClient. The store does NOT own the * client's lifecycle. The caller is responsible for configuration * (region, endpoint, credentials). */ client: any; /** Table name. Default: `manifest_outbox_table`. */ tableName?: string; /** Partition key attribute name. Default: `pk`. */ partitionKey?: string; /** Sort key attribute name. Default: `sk`. */ sortKey?: string; /** * When true, project `event.subject.entity` and `event.subject.id` into * separate attributes. Useful for query patterns that filter by subject. * Default: false. */ projectSubject?: boolean; } export declare class DynamoDBOutboxStore implements OutboxStore { private client; private tableName; private partitionKey; private sortKey; private projectSubject; constructor(opts: DynamoDBOutboxStoreOptions); private buildKey; /** * Enqueue entries. The DynamoDB adapter batches up to 100 items per * TransactWriteItems call. The `tx` parameter is accepted for contract * compatibility with other outbox stores (e.g. Postgres), but DynamoDB * transactions are scoped to a single client invocation and cannot be * shared across separate API calls. Therefore, the transactional * guarantee is always within a single `enqueue` call: either all * entries in the batch are persisted, or none are. * * If you need to atomically enqueue entries together with entity state * mutations, use the `TransactWriteItems` API directly and group the * outbox PutItems with the entity PutItems in a single call. */ enqueue(entries: OutboxEntry[], _tx?: unknown): Promise; /** * Claim up to `batchSize` pending entries. Scans the table for * 'pending' entries and atomically transitions each to 'claimed' * via a conditional UpdateItem. The first worker to win the * condition race claims the entry. * * Note: Scan is used here for simplicity. For high-volume outboxes, * maintain a GSI on `status` to enable efficient Query. */ claim(batchSize: number): Promise; /** Mark entries delivered. */ markDelivered(entryIds: string[]): Promise; /** Mark entries failed with a reason. */ markFailed(entryIds: string[], error: string): Promise; } //# sourceMappingURL=dynamodb.d.ts.map