feat(relay): in-memory queue with consume-once semantics
This commit is contained in:
55
tools/relay/queue.ts
Normal file
55
tools/relay/queue.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
export type Role = "pm" | "dev-a" | "dev-b";
|
||||
export type MessageKind = "status" | "question" | "directive" | "free";
|
||||
|
||||
export interface RelayMessage {
|
||||
id: string;
|
||||
from: Role;
|
||||
to: Role;
|
||||
kind: MessageKind;
|
||||
body: string;
|
||||
ts: string;
|
||||
}
|
||||
|
||||
const KNOWN_ROLES = new Set<string>(["pm", "dev-a", "dev-b"]);
|
||||
|
||||
export function isRole(s: string): s is Role {
|
||||
return KNOWN_ROLES.has(s);
|
||||
}
|
||||
|
||||
export class RelayQueue {
|
||||
private readonly queues = new Map<Role, RelayMessage[]>([
|
||||
["pm", []],
|
||||
["dev-a", []],
|
||||
["dev-b", []],
|
||||
]);
|
||||
|
||||
post(from: Role, to: Role, kind: MessageKind, body: string): RelayMessage {
|
||||
const msg: RelayMessage = {
|
||||
id: randomUUID(),
|
||||
from,
|
||||
to,
|
||||
kind,
|
||||
body,
|
||||
ts: new Date().toISOString(),
|
||||
};
|
||||
this.queues.get(to)!.push(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
read(forRole: Role): RelayMessage[] {
|
||||
const inbox = this.queues.get(forRole)!;
|
||||
const messages = [...inbox];
|
||||
inbox.length = 0;
|
||||
return messages;
|
||||
}
|
||||
|
||||
pending(forRole: Role): { count: number; kinds: MessageKind[] } {
|
||||
const inbox = this.queues.get(forRole)!;
|
||||
return {
|
||||
count: inbox.length,
|
||||
kinds: inbox.map((m) => m.kind),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user