import cfg from "../config.js" import { readFileSync } from "fs" import path from "path" import { fileURLToPath } from "url" const __dirname = path.join(path.dirname(fileURLToPath(import.meta.url)), "..") export const pathJoin = (...paths) => path.join(__dirname, ...paths) export const now = () => ~~(new Date().getTime() / 1000) export const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)) export const schedule = { always: (sec, func, ...args) => setInterval(() => func(...args), sec * 1000), once: (sec, func, ...args) => setTimeout(() => func(...args), sec * 1000), } const fileCacheTime = 60 * 60 const fileCache = {} export function readFileCached(fn) { let file = fileCache[fn] const dt = now() if (!file || file.dt < dt - fileCacheTime) { file = { dt, content: readFileSync(fn, { encoding: "utf-8" }), } fileCache[fn] = file } return file.content } // const rgxDomain = /^(.*)?\.([a-z\d\-]+\.[a-z\d\-]+)$/ // only root domains const rgxDomain = new RegExp(`^(?:(.+)\.)?(${cfg.domains.join("|").replace(/\./g, "\\.")})$`) export function parseHost(host) { if (!host) return [null, null] host = host.toLowerCase().replace(/^https?:\/\//, "") const [_, sub, domain] = host.match(rgxDomain) || [null, null, host] return [sub, domain] } const queue = [] export function enqueue(func, ...args) { return new Promise(async (resolve, reject) => { if (queue.length > cfg.queue_max) return resolve(response("Too many requests in queue, please try again", false)) queue.push({ func, args, resolve, reject }) await runqueue() }) } let queueRunning = false async function runqueue() { if (queueRunning) return queueRunning = true let cur, cnt = cfg.queue_throttle_start while (cur = queue.shift()) { try { cur.resolve(await cur.func(...cur.args)) } catch (err) { cur.reject(err) } if (cnt === 0) { await sleep(cfg.queue_throttle_enf_ms) } else { if (cnt <= cfg.queue_throttle_mid) await sleep(cfg.queue_throttle_mid_ms) cnt-- } } queueRunning = false } export function response(message, success = true) { return { success, message } }