@@ -313,8 +313,6 @@ route Api = AuthApi | ClientApi | FederationApi
313-- for clarity per the file header.
313-- for clarity per the file header.
315-- True when every element matches.
315-- True when every element matches.
316−all : [a] -> (a -> Bool) -> Bool
317−all = \xs pred -> not (any (\x -> not pred x) xs)
318findFirst : [a] -> (a -> Bool) -> Maybe a
316findFirst : [a] -> (a -> Bool) -> Maybe a
319findFirst = \xs pred -> headOf (filter pred xs)
317findFirst = \xs pred -> headOf (filter pred xs)
320-- Run `action` only when `cond` is True; otherwise no-op.
318-- Run `action` only when `cond` is True; otherwise no-op.
@@ -330,13 +328,15 @@ clamp = \lo hi x -> max lo (min hi x)
331-- First element of a list, or Nothing for an empty list.
329-- First element of a list, or Nothing for an empty list.
332headOf : [a] -> Maybe a
330headOf : [a] -> Maybe a
333−headOf = \items -> fold (\_ x -> Just {value: x}) (Nothing {}) (take 1 items)
331+headOf = \items -> case items of
332+ Cons x _ -> Just {value: x}
335-- Cap to maxN by dropping the smallest-key entries (LRU-style). Always sorts.
335-- Cap to maxN by dropping the smallest-key entries (LRU-style). Always sorts.
336-- For session/challenge/rate caps, `getKey` is typically `expiresAt` or
336-- For session/challenge/rate caps, `getKey` is typically `expiresAt` or
337-- `windowStart` so the oldest entries are evicted first.
337-- `windowStart` so the oldest entries are evicted first.
338capList : [a] -> Int -> (a -> b) -> [a]
338capList : [a] -> Int -> (a -> b) -> [a]
339−capList = \items maxN getKey -> dropRelation (max 0 (count items - maxN)) (sortBy getKey items)
339+capList = \items maxN getKey -> drop (max 0 (count items - maxN)) (sortBy getKey items)
341-- Cap pred-matching entries to maxN-1 (caller adds one more). Splits the list
341-- Cap pred-matching entries to maxN-1 (caller adds one more). Splits the list
342-- into "doesn't match" (untouched) and "matches" (capped + LRU-evicted) so a
342-- into "doesn't match" (untouched) and "matches" (capped + LRU-evicted) so a
@@ -348,20 +348,20 @@ capPerKey = \items pred maxN getKey -> union (filter (\x -> not pred x) items) (
348-- Sequence an IO action over each item, in order. Recurses through the list
348-- Sequence an IO action over each item, in order. Recurses through the list
349-- one element at a time; this is the closest equivalent of `mapM_` here.
349-- one element at a time; this is the closest equivalent of `mapM_` here.
350forEach : [a] -> (a -> IO {} {}) -> IO {} {}
350forEach : [a] -> (a -> IO {} {}) -> IO {} {}
351−forEach = \items action -> case single (take 1 items) of
351+forEach = \items action -> case items of
352− Nothing {} -> yield {}
352+ [] -> yield {}
353− Just {value: x} -> do
353+ Cons x rest -> do
355− forEach (dropRelation 1 items) action
355+ forEach rest action
357-- Like forEach, but collects each action's result into a list.
357-- Like forEach, but collects each action's result into a list.
358mapEach : [a] -> (a -> IO {} b) -> IO {} [b]
358mapEach : [a] -> (a -> IO {} b) -> IO {} [b]
359−mapEach = \items action -> case headOf items of
359+mapEach = \items action -> case items of
360− Nothing {} -> yield []
360+ [] -> yield []
361− Just {value: x} -> do
361+ Cons x rest -> do
362 r <- action x
362 r <- action x
363− rest <- mapEach (dropRelation 1 items) action
363+ rs <- mapEach rest action
364− yield (union [r] rest)
364+ yield (union [r] rs)
366-- Hex tokens: one random hex char per recursive call. `n` is the desired
366-- Hex tokens: one random hex char per recursive call. `n` is the desired
367-- length in characters (so n=48 yields 24 random bytes of entropy).
367-- length in characters (so n=48 yields 24 random bytes of entropy).