@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
JavaScript
/**
* 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