ruche-manager/src/lib/utils.ts
2024-04-29 10:36:03 +02:00

49 lines
1.4 KiB
TypeScript

import { basename } from "https://deno.land/std@0.223.0/path/basename.ts";
export function log_from(meta: ImportMeta) {
const url = new URL(meta.url);
const file = basename(url.pathname);
return (...args: unknown[]) => console.log(`[${file}]`, ...args);
}
export function last<T>(items: Iterable<T>) {
let result = null as T | null;
for (const item of items) result = item;
return result;
}
export function days_to_ms(days: number) {
const ms_per_day = 24 * 60 * 60 * 1000;
return days * ms_per_day;
}
export async function collect<T>(iterator: AsyncIterable<T>) {
const collected = [] as T[];
for await (const item of iterator) collected.push(item);
return collected;
}
export type Channel<T = void> = ReturnType<typeof channel<T>>;
export function channel<T = void>() {
const queue = [] as T[];
let resolve_next = null as null | ((value: T) => void);
async function receive() {
if (resolve_next !== null) throw new Error("Receiving twice concurently.");
if (queue.length > 0) return queue.splice(0, 1)[0];
const result = await new Promise<T>((resolver) => resolve_next = resolver);
resolve_next = null;
return result;
}
function send(item: T) {
if (resolve_next === null) queue.push(item);
else resolve_next(item);
}
return { send, receive };
}
export async function wait(ms: number) {
await new Promise((resolver) => setTimeout(resolver, ms));
}