UNPKG

@ydbjs/topic

Version:

YDB Topics client for publish-subscribe messaging. Provides at-least-once delivery, exactly-once publishing, FIFO guarantees, and scalable message processing for unstructured data.

69 lines 2.42 kB
/** * Sequence Number Manager for TopicWriter * * Handles two modes: * 1. Auto mode: Automatically generates sequential seqNo starting from lastSeqNo + 1 * 2. Manual mode: User provides all seqNo values, validates they are strictly increasing */ export class SeqNoManager { #mode = null; #nextSeqNo = 1n; #lastSeqNo = 0n; #highestUserSeqNo = 0n; constructor(initialSeqNo = 0n) { this.#nextSeqNo = initialSeqNo + 1n; this.#lastSeqNo = initialSeqNo; } /** * Initialize with server's last seqNo from STREAM_INIT_RESPONSE */ initialize(serverLastSeqNo) { this.#lastSeqNo = serverLastSeqNo; this.#nextSeqNo = serverLastSeqNo + 1n; } /** * Get next sequence number for a message * @param userSeqNo Optional user-provided seqNo * @returns Final seqNo to use for the message */ getNext(userSeqNo) { // Determine mode on first call if (this.#mode === null) { this.#mode = userSeqNo !== undefined ? 'manual' : 'auto'; } if (this.#mode === 'auto') { if (userSeqNo !== undefined) { throw new Error('Cannot mix auto and manual seqNo modes. Once auto mode is started, all messages must use auto seqNo.'); } let seqNo = this.#nextSeqNo; this.#nextSeqNo++; this.#lastSeqNo = seqNo; // Update lastSeqNo when we write return seqNo; } else { // Manual mode if (userSeqNo === undefined) { throw new Error('Cannot mix manual and auto seqNo modes. Once manual mode is started, all messages must provide seqNo.'); } // Validate strictly increasing if (userSeqNo <= this.#highestUserSeqNo) { throw new Error(`SeqNo must be strictly increasing. Provided: ${userSeqNo}, highest seen: ${this.#highestUserSeqNo}`); } this.#highestUserSeqNo = userSeqNo; this.#lastSeqNo = userSeqNo; // Update lastSeqNo when we write return userSeqNo; } } /** * Get current state */ getState() { return { mode: this.#mode, nextSeqNo: this.#nextSeqNo, lastSeqNo: this.#lastSeqNo, highestUserSeqNo: this.#highestUserSeqNo, }; } } //# sourceMappingURL=seqno-manager.js.map