@trap_stevo/liveql
Version:
Supercharge your database workflow with a visually clean, ultra-intuitive SQL layer. Chain elegant queries, trigger instant real-time events, and manage schemas effortlessly — all without ORM overhead while blending raw SQL power with modern developer erg
79 lines (78 loc) • 3.06 kB
JavaScript
;
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const EventEmitter = require("events");
var _client = /*#__PURE__*/new WeakMap();
var _pollers = /*#__PURE__*/new WeakMap();
class RealTimeDispatcher extends EventEmitter {
constructor(client) {
super();
_classPrivateFieldInitSpec(this, _client, void 0);
_classPrivateFieldInitSpec(this, _pollers, new Map());
_classPrivateFieldSet(_client, this, client);
if (typeof client.on === "function") {
client.on("notification", msg => {
try {
const payload = JSON.parse(msg.payload);
this.emit(msg.channel, payload);
} catch {
this.emit(msg.channel, msg.payload);
}
});
}
}
listen(channel) {
if (typeof _classPrivateFieldGet(_client, this).query === "function") {
return _classPrivateFieldGet(_client, this).query(`LISTEN ${channel}`);
}
}
unlisten(channel) {
if (typeof _classPrivateFieldGet(_client, this).query === "function") {
return _classPrivateFieldGet(_client, this).query(`UNLISTEN ${channel}`);
}
}
emit(table, eventType, data) {
super.emit(`${table}__${eventType}`, data);
}
onEvent(table, eventType, handler) {
this.on(`${table}__${eventType}`, handler);
}
startPolling(table, eventType, interval, fetchFn, {
idColumn = "id",
updatedAtColumn = "updated_at"
} = {}) {
const pollKey = `${table}__${eventType}`;
if (_classPrivateFieldGet(_pollers, this).has(pollKey)) return;
let lastId = 0;
let lastUpdated = null;
const poller = setInterval(async () => {
try {
const rows = await fetchFn({
lastId,
lastUpdated
});
if (rows && rows.length) {
lastId = Math.max(...rows.map(r => r[idColumn] || 0));
if (updatedAtColumn && rows[0][updatedAtColumn]) {
lastUpdated = rows[0][updatedAtColumn];
}
this.emit(table, eventType, rows);
}
} catch (err) {
console.error(`[RealTimeDispatcher] Polling error for ${pollKey}:`, err);
}
}, interval);
_classPrivateFieldGet(_pollers, this).set(pollKey, poller);
}
stopPolling(table, eventType) {
const pollKey = `${table}__${eventType}`;
if (_classPrivateFieldGet(_pollers, this).has(pollKey)) {
clearInterval(_classPrivateFieldGet(_pollers, this).get(pollKey));
_classPrivateFieldGet(_pollers, this).delete(pollKey);
}
}
}
module.exports = RealTimeDispatcher;