import { createSignal } from './signal.js' export type MessageSource = 'user' | 'teammate' | 'system' | 'tick' | 'task' export type Message = { id: string source: MessageSource content: string from?: string color?: string timestamp: string } type Waiter = { fn: (msg: Message) => boolean resolve: (msg: Message) => void } export class Mailbox { private queue: Message[] = [] private waiters: Waiter[] = [] private changed = createSignal() private _revision = 0 get length(): number { return this.queue.length } get revision(): number { return this._revision } send(msg: Message): void { this._revision++ const idx = this.waiters.findIndex(w => w.fn(msg)) if (idx !== -1) { const waiter = this.waiters.splice(idx, 1)[0] if (waiter) { waiter.resolve(msg) this.notify() return } } this.queue.push(msg) this.notify() } poll(fn: (msg: Message) => boolean = () => true): Message | undefined { const idx = this.queue.findIndex(fn) if (idx === -1) return undefined return this.queue.splice(idx, 1)[0] } receive(fn: (msg: Message) => boolean = () => true): Promise { const idx = this.queue.findIndex(fn) if (idx !== -1) { const msg = this.queue.splice(idx, 1)[0] if (msg) { this.notify() return Promise.resolve(msg) } } return new Promise(resolve => { this.waiters.push({ fn, resolve }) }) } subscribe = this.changed.subscribe private notify(): void { this.changed.emit() } }