UNPKG

@arturwojnar/hermes-postgresql

Version:

Production-Ready TypeScript Outbox Pattern for PostgreSQL

88 lines (87 loc) 3.29 kB
import { TransactionSql } from 'postgres'; import { Prettify } from 'ts-essentials'; import { Lsn } from '../common/lsn.js'; import { HermesSql } from '../common/types.js'; type BaseOutboxConsumerModel = { id: number; consumerName: string; partitionKey: string; createdAt: Date; }; type InitialOutboxConsumerModel = { status: 'INITIAL'; }; type CreatedOutboxConsumerModel = Prettify<BaseOutboxConsumerModel & { status: 'CREATED'; lastProcessedLsn: string; }>; type SuccessOutboxConsumerModel = Prettify<BaseOutboxConsumerModel & { status: 'SUCCESS_PUBLISH'; lastProcessedLsn: string; lastUpdatedAt: Date; }>; type RedeliverOutboxConsumerModel = Prettify<BaseOutboxConsumerModel & { status: 'FAILED_PUBLISH'; failedNextLsn: string; lastProcessedLsn: string; nextLsnRedeliveryCount: number; lastUpdatedAt: Date; }>; type DeletedOutboxConsumerModel = Prettify<BaseOutboxConsumerModel & { status: 'DELETED'; deletedAt: Date; }>; type OutboxConsumerModel = InitialOutboxConsumerModel | CreatedOutboxConsumerModel | SuccessOutboxConsumerModel | RedeliverOutboxConsumerModel | DeletedOutboxConsumerModel; type OutboxConsumerCreated = { id: number; consumerName: string; partitionKey: string; createdAt: Date; status: 'CREATED'; }; type OutboxConsumerMovedFurther = { status: 'SUCCESS_PUBLISH'; lastProcessedLsn: string; lastUpdatedAt: Date; failedNextLsn: null; nextLsnRedeliveryCount: 0; }; type OutboxConsumerReportedError = { status: 'FAILED_PUBLISH'; failedNextLsn: string; nextLsnRedeliveryCount: number; lastUpdatedAt: Date; }; type OutboxConsumerDeleted = { status: 'DELETED'; deletedAt: Date; }; type OutboxConsumerStatus = OutboxConsumerModel['status']; type Permutations<T, U = T> = [T] extends [never] ? [] : T extends T ? [T, ...Permutations<Exclude<U, T>>] : never; type UpdateParams = OutboxConsumerMovedFurther | OutboxConsumerReportedError | OutboxConsumerDeleted; declare const OutboxConsumerStatuses: Permutations<OutboxConsumerStatus>; declare class OutboxConsumerStore { private readonly _sql; private readonly _consumerName; private readonly _partitionKey; private _consumer; constructor(_sql: HermesSql, _consumerName: string, _partitionKey?: string); load(): Promise<OutboxConsumerModel>; createOrLoad(data: OutboxConsumerCreated): Promise<OutboxConsumerModel>; update(consumerName: string, change: UpdateParams, tx?: TransactionSql): Promise<OutboxConsumerModel>; get consumer(): OutboxConsumerModel | null; get consumerName(): string; get lastProcessedLsn(): `${string}/${string}`; get redeliveryCount(): number; } declare class OutboxConsumerState { private readonly _store; constructor(_store: OutboxConsumerStore); createOrLoad(partitionKey?: string): Promise<OutboxConsumerModel>; moveFurther(lastProcessedLsn: Lsn, tx?: TransactionSql): Promise<void>; reportFailedDelivery(failedNextLsn: Lsn, tx?: TransactionSql): Promise<void>; get data(): OutboxConsumerModel | null; get lastProcessedLsn(): `${string}/${string}`; get redeliveryCount(): number; } export { OutboxConsumerState, OutboxConsumerStatuses, OutboxConsumerStore, type OutboxConsumerStatus };