@arturwojnar/hermes-postgresql
Version:
Production-Ready TypeScript Outbox Pattern for PostgreSQL
88 lines (87 loc) • 3.29 kB
TypeScript
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 };