@tanstack/db
Version:
A reactive client store for building super fast apps on sync
90 lines (89 loc) • 2.38 kB
JavaScript
const _CleanupQueue = class _CleanupQueue {
constructor() {
this.tasks = /* @__PURE__ */ new Map();
this.timeoutId = null;
this.microtaskScheduled = false;
}
static getInstance() {
if (!_CleanupQueue.instance) {
_CleanupQueue.instance = new _CleanupQueue();
}
return _CleanupQueue.instance;
}
/**
* Queues a cleanup task and defers timeout selection to a microtask so
* multiple synchronous registrations can share one root timer.
*/
schedule(key, gcTime, callback) {
const executeAt = Date.now() + gcTime;
this.tasks.set(key, { executeAt, callback });
if (!this.microtaskScheduled) {
this.microtaskScheduled = true;
Promise.resolve().then(() => {
this.microtaskScheduled = false;
this.updateTimeout();
});
}
}
cancel(key) {
this.tasks.delete(key);
}
/**
* Keeps only one active timeout: whichever task is due next.
*/
updateTimeout() {
if (this.timeoutId !== null) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
if (this.tasks.size === 0) {
return;
}
let earliestTime = Infinity;
for (const task of this.tasks.values()) {
if (task.executeAt < earliestTime) {
earliestTime = task.executeAt;
}
}
const delay = Math.max(0, earliestTime - Date.now());
this.timeoutId = setTimeout(() => this.process(), delay);
}
/**
* Runs every task whose deadline has passed, then schedules the next wakeup
* if there is still pending work.
*/
process() {
this.timeoutId = null;
const now = Date.now();
for (const [key, task] of this.tasks.entries()) {
if (now >= task.executeAt) {
this.tasks.delete(key);
try {
task.callback();
} catch (error) {
console.error("Error in CleanupQueue task:", error);
}
}
}
if (this.tasks.size > 0) {
this.updateTimeout();
}
}
/**
* Resets the singleton instance for tests.
*/
static resetInstance() {
if (_CleanupQueue.instance) {
if (_CleanupQueue.instance.timeoutId !== null) {
clearTimeout(_CleanupQueue.instance.timeoutId);
}
_CleanupQueue.instance = null;
}
}
};
_CleanupQueue.instance = null;
let CleanupQueue = _CleanupQueue;
export {
CleanupQueue
};
//# sourceMappingURL=cleanup-queue.js.map