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(items: Iterable) { 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(iterator: AsyncIterable) { const collected = [] as T[]; for await (const item of iterator) collected.push(item); return collected; } export type Channel = ReturnType>; export function channel() { 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((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)); }