summaryrefslogtreecommitdiffhomepage
path: root/packages/message-queue/src/pure.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-28 22:23:25 +0900
committerAdam Malczewski <[email protected]>2026-06-28 22:23:25 +0900
commit1ea99dd6e2cdcdd6e4f581f3908719d8fa3fc780 (patch)
tree92c4393b4cf3fa903160d2a56327e67132803f25 /packages/message-queue/src/pure.ts
parent1444bc1286823231006eebde6b5206a8dd97c977 (diff)
parent01928fe70d22cb7b0a8d20f38b359c8a0048c34b (diff)
downloaddispatch-1ea99dd6e2cdcdd6e4f581f3908719d8fa3fc780.tar.gz
dispatch-1ea99dd6e2cdcdd6e4f581f3908719d8fa3fc780.zip
Merge branch 'feature/cancel-queued-message' into predev
Diffstat (limited to 'packages/message-queue/src/pure.ts')
-rw-r--r--packages/message-queue/src/pure.ts36
1 files changed, 36 insertions, 0 deletions
diff --git a/packages/message-queue/src/pure.ts b/packages/message-queue/src/pure.ts
index 981e005..ffb9dc2 100644
--- a/packages/message-queue/src/pure.ts
+++ b/packages/message-queue/src/pure.ts
@@ -75,6 +75,42 @@ export function drain(state: MessageQueueState, conversationId: string): QueuedM
}
/**
+ * Cancel: remove a SINGLE queued message by id from a conversation's queue so
+ * it never runs (never delivered as steering, never carried into a new turn).
+ * Returns the post-cancel queue snapshot (a fresh array copy). Idempotent — if
+ * no message with `messageId` exists in the conversation's queue (already
+ * drained/delivered, never existed, unknown conversation) the queue is
+ * unchanged and the returned snapshot simply does not contain it; the caller
+ * distinguishes "removed" from "not found" via the `cancelWithFlag` helper
+ * (this returns the snapshot only, like the other pure ops).
+ *
+ * The cancelled message is dropped entirely — it is NOT returned (the caller
+ * does not need it; the surface re-renders from the snapshot). Mutates `state`
+ * in place (splices the message out of the conversation's array).
+ */
+export function cancel(
+ state: MessageQueueState,
+ conversationId: string,
+ messageId: string,
+): QueuedMessage[] {
+ const existing = state.get(conversationId);
+ if (existing === undefined || existing.length === 0) {
+ return getQueue(state, conversationId);
+ }
+ const idx = existing.findIndex((m) => m.id === messageId);
+ if (idx === -1) {
+ return getQueue(state, conversationId);
+ }
+ existing.splice(idx, 1);
+ // If the queue is now empty, drop the key so `getQueue` stays a clean empty
+ // array (mirrors `drain` deleting the key on empty).
+ if (existing.length === 0) {
+ state.delete(conversationId);
+ }
+ return getQueue(state, conversationId);
+}
+
+/**
* Combine drained messages' texts into a single steering string, joined by a
* blank line (`\n\n`). Pure — the session-orchestrator builds the final
* ChatMessage from this.