Commit07f34c70Recorded21 Mar 2026Repositorysigil-jmap

Add jmap-email-count for lightweight email counting

Message

Sends Email/query with calculateTotal and limit 0 to get just the total match count without fetching any email data.

Changed
 src/sigil/jmap.sgl       |  1 +
 src/sigil/jmap/email.sgl | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)
Diff
src/sigil/jmap.sglmodified
@@ -64,6 +64,7 @@
64
65
;; Email (from sigil jmap email)
66
jmap-email-query
+67
jmap-email-count
68
jmap-email-get
69
jmap-email-get-many
70
jmap-email-update!
src/sigil/jmap/email.sglmodified
@@ -11,6 +11,7 @@
11
12
(export
13
jmap-email-query
+14
jmap-email-count
15
jmap-email-get
16
jmap-email-get-many
17
jmap-email-update!
@@ -101,6 +102,30 @@
102
(array->list (or (dict-ref get-result list: #f) #[]))
103
'()))))
104
+105
;;; Count emails matching a filter without fetching content.
+106
;;;
+107
;;; Sends an `Email/query` with `calculateTotal` and `limit: 0`
+108
;;; to get just the total count. Much cheaper than a full query.
+109
;;;
+110
;;; ```scheme
+111
;;; (jmap-email-count client filter: #{ inMailbox: inbox-id })
+112
;;; ; => 347
+113
;;; ```
+114
(define (jmap-email-count client (keys: (mailbox #f) (filter #f)))
+115
(: jmap-client? (mailbox: (maybe string?)) (filter: (maybe dict?)) -> integer?)
+116
(let* ((account-id (jmap-client-account-id client))
+117
(query-filter (or filter
+118
(if mailbox
+119
(dict inMailbox: mailbox)
+120
#{})))
+121
(result (jmap-result-ref client
+122
(jmap-call "Email/query"
+123
(dict accountId: account-id
+124
filter: query-filter
+125
calculateTotal: #t
+126
limit: 0)))))
+127
(or (dict-ref result total: #f) 0)))
+128
129
;;; Get a single email by ID with full body content.
130
;;;
131
;;; Returns the email dict with body values, or `#f` if not found.