@afokapu/atdd-bun 0.10.9 → 0.10.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/integrity.json +2 -2
- package/package.json +1 -1
- package/src/board.ts +9 -3
package/integrity.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.10.
|
|
2
|
+
"version": "0.10.10",
|
|
3
3
|
"files": {
|
|
4
4
|
"HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
|
|
5
5
|
"PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
|
|
@@ -1193,7 +1193,7 @@
|
|
|
1193
1193
|
"relationships.yaml": "1cb713364aff54fb6e299e0737fe75a5d7b2e1dbd0a79b16b793aa1d269207b5",
|
|
1194
1194
|
"src/agent.ts": "65e4579adb5a54977f557f8c783aba0e2a2a1d5cf3cea9f017b67ffe598b2f65",
|
|
1195
1195
|
"src/board-ui.ts": "16a843705552f8f18e0e328e90e4a2a9148d771ca69f2708fe4a91302947dfad",
|
|
1196
|
-
"src/board.ts": "
|
|
1196
|
+
"src/board.ts": "a3a8efe923858b9b5cf5ca3682dacfceb5557f8303d818687eb1325a15fa1782",
|
|
1197
1197
|
"src/ci.ts": "67e54d2cbfc44a9e42837d5e750af526d6255c539d3c452a4d5fca3226c0d9ac",
|
|
1198
1198
|
"src/cli.ts": "e45f2666334503a91eb65b1b5ee4dd8acab6b99f62d333e2ee2b65963db6358b",
|
|
1199
1199
|
"src/delivery.ts": "5688356e26bf5aa49ad940d1bcd42e41b9f3dc1c21dc833b328fcb38a3f04fb8",
|
package/package.json
CHANGED
package/src/board.ts
CHANGED
|
@@ -97,8 +97,8 @@ export async function post(url: string, topic: string, header: Header, body: str
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/** Every message on the topics after `since` (a message id, or "all"). */
|
|
100
|
-
export async function read(url: string, topics: string[], since = "all"): Promise<Message[]> {
|
|
101
|
-
const res = await fetch(`${url}/${topics.join(",")}/json?poll=1&since=${since}
|
|
100
|
+
export async function read(url: string, topics: string[], since = "all", signal?: AbortSignal): Promise<Message[]> {
|
|
101
|
+
const res = await fetch(`${url}/${topics.join(",")}/json?poll=1&since=${since}`, { signal });
|
|
102
102
|
if (!res.ok) throw new Error(`reading ${topics.join(", ")} failed: ${res.status} ${await res.text()}`);
|
|
103
103
|
return (await res.text()).split("\n").filter(Boolean).map(line => JSON.parse(line)).filter(m => m.event === "message")
|
|
104
104
|
.map(m => ({ id: m.id, time: m.time, topic: m.topic, raw: m.message, ...parseEnvelope(m.message) }));
|
|
@@ -108,11 +108,17 @@ export async function read(url: string, topics: string[], since = "all"): Promis
|
|
|
108
108
|
* It polls rather than streams: a live stream can drop a message published while it connects. ntfy reads `since` (a
|
|
109
109
|
* message id) as that message's time on every topic, so one cursor serves several topics. Returns null after
|
|
110
110
|
* `timeoutSeconds`, so an agent's tool call stays bounded. */
|
|
111
|
+
/** The longest one poll may take. ntfy answers a poll at once, so only a stalled request ever reaches it. */
|
|
112
|
+
const POLL_LIMIT_MS = 10_000;
|
|
113
|
+
|
|
111
114
|
export async function waitFor(url: string, topics: string[], agent: string, since = "all", timeoutSeconds = 0, skip: string[] = [], intervalMs = 500, seen: (id: string) => void = () => {}): Promise<Message | null> {
|
|
112
115
|
const deadline = timeoutSeconds > 0 ? Date.now() + timeoutSeconds * 1000 : Infinity;
|
|
113
116
|
for (;;) {
|
|
114
117
|
let messages: Message[] = [];
|
|
115
|
-
|
|
118
|
+
// Each poll is bounded: a request that never answers (a half-open connection after the board restarts or the
|
|
119
|
+
// machine sleeps) would otherwise hold the wait past its deadline and deliver nothing. It counts as unavailable.
|
|
120
|
+
const bound = AbortSignal.timeout(Math.max(1, Math.min(POLL_LIMIT_MS, deadline - Date.now())));
|
|
121
|
+
try { messages = await read(url, topics, since, bound); } catch { /* the board is briefly unavailable: keep waiting */ }
|
|
116
122
|
for (const message of messages) { since = message.id; seen(since); if (addressedTo(message, agent) && !skip.includes(message.header.kind ?? "")) return message; }
|
|
117
123
|
if (Date.now() >= deadline) return null;
|
|
118
124
|
await Bun.sleep(intervalMs);
|