2020-10-30 20:34:04 +00:00
|
|
|
// Copyright 2020 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2020-10-01 00:43:24 +00:00
|
|
|
import { v4 as getGuid } from 'uuid';
|
|
|
|
|
|
|
|
type TimeoutType = {
|
|
|
|
timestamp: number;
|
|
|
|
uuid: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
const timeoutStore: Map<string, () => void> = new Map();
|
|
|
|
const allTimeouts: Set<TimeoutType> = new Set();
|
|
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
if (!allTimeouts.size) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
|
|
|
allTimeouts.forEach((timeout: TimeoutType) => {
|
|
|
|
const { timestamp, uuid } = timeout;
|
|
|
|
|
|
|
|
if (now >= timestamp) {
|
|
|
|
if (timeoutStore.has(uuid)) {
|
|
|
|
const callback = timeoutStore.get(uuid);
|
|
|
|
if (callback) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
timeoutStore.delete(uuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
allTimeouts.delete(timeout);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
export function onTimeout(
|
|
|
|
timestamp: number,
|
|
|
|
callback: () => void,
|
|
|
|
id?: string
|
|
|
|
): string {
|
|
|
|
if (id && timeoutStore.has(id)) {
|
|
|
|
throw new ReferenceError(`onTimeout: ${id} already exists`);
|
|
|
|
}
|
|
|
|
|
|
|
|
let uuid = id || getGuid();
|
|
|
|
while (timeoutStore.has(uuid)) {
|
|
|
|
uuid = getGuid();
|
|
|
|
}
|
|
|
|
|
|
|
|
timeoutStore.set(uuid, callback);
|
|
|
|
allTimeouts.add({
|
|
|
|
timestamp,
|
|
|
|
uuid,
|
|
|
|
});
|
|
|
|
|
|
|
|
return uuid;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function removeTimeout(uuid: string): void {
|
2021-04-09 16:19:38 +00:00
|
|
|
if (!timeoutStore.has(uuid)) {
|
|
|
|
return;
|
2020-10-01 00:43:24 +00:00
|
|
|
}
|
|
|
|
|
2021-04-09 16:19:38 +00:00
|
|
|
timeoutStore.delete(uuid);
|
|
|
|
|
2020-10-01 00:43:24 +00:00
|
|
|
allTimeouts.forEach((timeout: TimeoutType) => {
|
|
|
|
if (uuid === timeout.uuid) {
|
|
|
|
allTimeouts.delete(timeout);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|