From 0e888d62af1434fef231e11a5c307a5b48a8deb1 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sat, 07 Mar 2026 10:49:07 +0100
Subject: [PATCH] feat: singleton audio, transcript reflection, voice persistence

---
 services/wol.ts |   39 ++++++++++++++++++++++++++++++---------
 1 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/services/wol.ts b/services/wol.ts
index 9929a56..d3b6a4d 100644
--- a/services/wol.ts
+++ b/services/wol.ts
@@ -56,12 +56,31 @@
     }
   }
 
+  const TIMEOUT_MS = 5000;
+
   return new Promise<void>((resolve, reject) => {
+    let settled = false;
+    const settle = (fn: () => void) => {
+      if (settled) return;
+      settled = true;
+      clearTimeout(timer);
+      fn();
+    };
+
+    const timer = setTimeout(() => {
+      settle(() => {
+        try { socket.close(); } catch { /* ignore */ }
+        reject(new Error("WoL timed out — magic packet may not have been sent"));
+      });
+    }, TIMEOUT_MS);
+
     const socket = dgram.createSocket({ type: "udp4" });
 
     socket.once("error", (err: Error) => {
-      try { socket.close(); } catch { /* ignore */ }
-      reject(err);
+      settle(() => {
+        try { socket.close(); } catch { /* ignore */ }
+        reject(err);
+      });
     });
 
     socket.bind(0, () => {
@@ -72,20 +91,22 @@
       }
 
       let pending = broadcastAddresses.length;
-      let failed = false;
 
       for (const addr of broadcastAddresses) {
         socket.send(packet, 0, packet.length, 9, addr, (err?: Error) => {
-          if (err && !failed) {
-            failed = true;
-            try { socket.close(); } catch { /* ignore */ }
-            reject(err);
+          if (err) {
+            settle(() => {
+              try { socket.close(); } catch { /* ignore */ }
+              reject(err);
+            });
             return;
           }
           pending--;
           if (pending === 0) {
-            try { socket.close(); } catch { /* ignore */ }
-            resolve();
+            settle(() => {
+              try { socket.close(); } catch { /* ignore */ }
+              resolve();
+            });
           }
         });
       }

--
Gitblit v1.3.1