| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- 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<Message> {
- 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<Message>(resolve => {
- this.waiters.push({ fn, resolve })
- })
- }
- subscribe = this.changed.subscribe
- private notify(): void {
- this.changed.emit()
- }
- }
|