source dump of claude code
at main 73 lines 1.6 kB view raw
1import { createSignal } from './signal.js' 2 3export type MessageSource = 'user' | 'teammate' | 'system' | 'tick' | 'task' 4 5export type Message = { 6 id: string 7 source: MessageSource 8 content: string 9 from?: string 10 color?: string 11 timestamp: string 12} 13 14type Waiter = { 15 fn: (msg: Message) => boolean 16 resolve: (msg: Message) => void 17} 18 19export class Mailbox { 20 private queue: Message[] = [] 21 private waiters: Waiter[] = [] 22 private changed = createSignal() 23 private _revision = 0 24 25 get length(): number { 26 return this.queue.length 27 } 28 29 get revision(): number { 30 return this._revision 31 } 32 33 send(msg: Message): void { 34 this._revision++ 35 const idx = this.waiters.findIndex(w => w.fn(msg)) 36 if (idx !== -1) { 37 const waiter = this.waiters.splice(idx, 1)[0] 38 if (waiter) { 39 waiter.resolve(msg) 40 this.notify() 41 return 42 } 43 } 44 this.queue.push(msg) 45 this.notify() 46 } 47 48 poll(fn: (msg: Message) => boolean = () => true): Message | undefined { 49 const idx = this.queue.findIndex(fn) 50 if (idx === -1) return undefined 51 return this.queue.splice(idx, 1)[0] 52 } 53 54 receive(fn: (msg: Message) => boolean = () => true): Promise<Message> { 55 const idx = this.queue.findIndex(fn) 56 if (idx !== -1) { 57 const msg = this.queue.splice(idx, 1)[0] 58 if (msg) { 59 this.notify() 60 return Promise.resolve(msg) 61 } 62 } 63 return new Promise<Message>(resolve => { 64 this.waiters.push({ fn, resolve }) 65 }) 66 } 67 68 subscribe = this.changed.subscribe 69 70 private notify(): void { 71 this.changed.emit() 72 } 73}