Files
dealplustech/dealplustech-astro/node_modules/@libsql/hrana-client/lib-esm/ws/cursor.js
Kunthawat b2e427791b feat: Add complete PDPA compliance pages
- Admin dashboard (/admin/consent-logs) with password auth
- Consent API (/api/consent) with SQLite + IP hashing
- Privacy Policy (Thai) - PDPA Section 36 compliant
- Terms & Conditions (Thai) - 9 standard clauses
- .env.example template with Umami placeholder

All pages preserve current design system.
2026-03-10 21:28:23 +07:00

81 lines
2.4 KiB
JavaScript

import { ClientError, ClosedError } from "../errors.js";
import { Cursor } from "../cursor.js";
import { Queue } from "../queue.js";
const fetchChunkSize = 1000;
const fetchQueueSize = 10;
export class WsCursor extends Cursor {
#client;
#stream;
#cursorId;
#entryQueue;
#fetchQueue;
#closed;
#done;
/** @private */
constructor(client, stream, cursorId) {
super();
this.#client = client;
this.#stream = stream;
this.#cursorId = cursorId;
this.#entryQueue = new Queue();
this.#fetchQueue = new Queue();
this.#closed = undefined;
this.#done = false;
}
/** Fetch the next entry from the cursor. */
async next() {
for (;;) {
if (this.#closed !== undefined) {
throw new ClosedError("Cursor is closed", this.#closed);
}
while (!this.#done && this.#fetchQueue.length < fetchQueueSize) {
this.#fetchQueue.push(this.#fetch());
}
const entry = this.#entryQueue.shift();
if (this.#done || entry !== undefined) {
return entry;
}
// we assume that `Cursor.next()` is never called concurrently
await this.#fetchQueue.shift().then((response) => {
if (response === undefined) {
return;
}
for (const entry of response.entries) {
this.#entryQueue.push(entry);
}
this.#done ||= response.done;
});
}
}
#fetch() {
return this.#stream._sendCursorRequest(this, {
type: "fetch_cursor",
cursorId: this.#cursorId,
maxCount: fetchChunkSize,
}).then((resp) => resp, (error) => {
this._setClosed(error);
return undefined;
});
}
/** @private */
_setClosed(error) {
if (this.#closed !== undefined) {
return;
}
this.#closed = error;
this.#stream._sendCursorRequest(this, {
type: "close_cursor",
cursorId: this.#cursorId,
}).catch(() => undefined);
this.#stream._cursorClosed(this);
}
/** Close the cursor. */
close() {
this._setClosed(new ClientError("Cursor was manually closed"));
}
/** True if the cursor is closed. */
get closed() {
return this.#closed !== undefined;
}
}