on master help sign in
Fix Knot compiler type errors in response handlers

Atomic blocks could not properly type-check when yielding response records. Restructure VerifyAuth, Poll, SendMessage, AckMessages, and LookupPresence handlers to yield simple values from atomic blocks and construct response records outside with let bindings. This allows the compiler to properly infer and unify record types at respond call sites.

commita9574e59e12a30d49104267d8ee9179ae3be0978 authoriko <mail@iko.soy> dateMon 23 Mar 2026, 14:23 (7 months ago) parent10935f1
1 file changed+30−28
server.knot+30−28
server.knot+30−28
@@ -143,7 +143,7 @@ serve = \req -> case req of
143143 t <- now
144144 token <- genToken
145145 let expiry = t + 3600000
146− result <- atomic do
146+ sigValid <- atomic do
147147 challenges <- *challenges
148148 sessions <- *sessions
149149 presence <- *presence
@@ -173,18 +173,18 @@ serve = \req -> case req of
173173 yield p)
174174 [{pubkey: pubkey, server: serverHost, expiresAt: expiry}]
175175 else presence
176− if sigValid
177− then yield {token: token, expiresAt: expiry}
178− else yield {token: "", expiresAt: 0}
179− respond result
176+ yield sigValid
177+ if sigValid
178+ then respond {token: token, expiresAt: expiry}
179+ else respond {token: "", expiresAt: 0}
180180
181181 Poll {authorization, respond} -> do
182182 t <- now
183− result <- atomic do
183+ evts <- atomic do
184184 sessions <- *sessions
185185 let session = lookupSession sessions (extractToken authorization) t
186186 case session of
187− Nothing {} -> yield {events: [], cursor: "unauthorized"}
187+ Nothing {} -> yield []
188188 Just {value: s} -> do
189189 messages <- *messages
190190 let pending = do
@@ -196,13 +196,13 @@ serve = \req -> case req of
196196 timestamp: m.timestamp}}
197197 if count pending == 0
198198 then retry
199− else yield {events: pending, cursor: ""}
200− respond result
199+ else yield pending
200+ respond {events: evts, cursor: ""}
201201
202202 SendMessage {to, encryptedBlob, timestamp, authorization, respond} -> do
203203 t <- now
204204 msgId <- genToken
205− result <- atomic do
205+ status <- atomic do
206206 sessions <- *sessions
207207 messages <- *messages
208208 let session = lookupSession sessions (extractToken authorization) t
@@ -218,15 +218,15 @@ serve = \req -> case req of
218218 where s.pubkey == to
219219 where s.expiresAt > t
220220 yield s) > 0
221− case session of
222− Nothing {} -> yield {status: "unauthorized", messageId: ""}
223− _ -> yield {status: (if online then "delivered" else "queued"),
224− messageId: msgId}
225− respond result
221+ let status = case session of
222+ Nothing {} -> "unauthorized"
223+ _ -> if online then "delivered" else "queued"
224+ yield status
225+ respond {status: status, messageId: (if status == "unauthorized" then "" else msgId)}
226226
227227 AckMessages {messageIds, authorization, respond} -> do
228228 t <- now
229− result <- atomic do
229+ ok <- atomic do
230230 sessions <- *sessions
231231 messages <- *messages
232232 let session = lookupSession sessions (extractToken authorization) t
@@ -238,14 +238,15 @@ serve = \req -> case req of
238238 where m.messageId == mid
239239 where m.toKey == s.pubkey
240240 yield m)
241− case session of
242− Nothing {} -> yield {ok: (False {})}
243− _ -> yield {ok: (True {})}
244− respond result
241+ let ok = case session of
242+ Nothing {} -> False {}
243+ _ -> True {}
244+ yield ok
245+ respond {ok: ok}
245246
246247 LookupPresence {pubkey, authorization, respond} -> do
247248 t <- now
248− result <- atomic do
249+ foundServer <- atomic do
249250 sessions <- *sessions
250251 presence <- *presence
251252 let session = lookupSession sessions (extractToken authorization) t
@@ -254,21 +255,22 @@ serve = \req -> case req of
254255 where p.pubkey == pubkey
255256 where p.expiresAt > t
256257 yield p
257− case session of
258− Nothing {} -> yield {online: (False {}), server: ""}
258+ let foundServer = case session of
259+ Nothing {} -> ""
259260 Just {value: _} ->
260261 if count valid == 0
261− then yield {online: (False {}), server: ""}
262+ then ""
262263 else case single (do
263264 p <- valid
264265 where p.server == serverHost
265266 yield p) of
266− Just {value: p} -> yield {online: (True {}), server: p.server}
267+ Just {value: p} -> p.server
267268 Nothing {} ->
268269 case single valid of
269− Just {value: p} -> yield {online: (True {}), server: p.server}
270− Nothing {} -> yield {online: (True {}), server: ""}
271− respond result
270+ Just {value: p} -> p.server
271+ Nothing {} -> ""
272+ yield foundServer
273+ respond {online: not (foundServer == ""), server: foundServer}
272274
273275 RecvGossip {events, hopsRemaining, authorization, respond} -> do
274276 t <- now