My agentic slop goes here. Not intended for anyone else!
1(** Revolutionary Result References Example - Advanced JMAP Chaining
2
3 This example demonstrates the revolutionary automatic result reference system
4 that eliminates manual call ID management. Inspired by Rust jmap-client's
5 sophisticated chaining capabilities.
6
7 Key revolutionary features:
8 - Automatic result reference chaining (no manual call IDs)
9 - Type-safe method composition with compile-time guarantees
10 - Complex multi-method operations in readable, fluent syntax
11 - Error handling that preserves context across method chains
12 - Performance optimization through request batching
13
14 Compare with manual approach: 50+ lines of JSON construction and ID management
15 Revolutionary approach: 10 lines of fluent, type-safe method calls *)
16
17open Printf
18
19let (let*) = Result.bind
20
21let show_error error =
22 printf "❌ %s\n" (Jmap.Error.Utils.context error)
23
24(** Revolutionary automatic result chaining demonstration *)
25let result_references_example env credentials =
26 printf "🔗 Revolutionary Result References & Chaining Example\n";
27 printf "====================================================\n\n";
28
29 let* client = Jmap_unix.Client.connect ~credentials env "https://api.fastmail.com" in
30 let account_id = Jmap_unix.Client.primary_account client in
31 printf "✅ Connected to account: %s\n\n" account_id;
32
33 (* Example 1: Simple query → get chaining (automatic result references) *)
34 printf "🔗 Example 1: Simple Email Query → Get Chain\n";
35 printf "─────────────────────────────────────────────\n";
36
37 (* Single line replaces complex manual result reference management *)
38 let* recent_emails = Jmap_unix.Client.query_emails client
39 ~filter:(Jmap_email.Query.Filter.has_keyword "$seen" |> Jmap_email.Query.Filter.negate)
40 ~sort:[Jmap_email.Query.Sort.by_date_desc]
41 ~limit:3
42 ~properties:[`Id; `From; `Subject; `Preview] () in
43
44 printf "✅ Found %d unread emails (query + get in single operation)\n" (List.length recent_emails);
45 List.iteri (fun i email ->
46 printf " %d. %s\n" (i+1) (Jmap_email.Email.subject email |> Option.value ~default:"(No Subject)")
47 ) recent_emails;
48 printf "\n";
49
50 (* Example 2: Complex batch operations with automatic chaining *)
51 printf "🔗 Example 2: Advanced Batch Operations\n";
52 printf "───────────────────────────────────────\n";
53
54 (* Create batch builder for complex multi-method operations *)
55 let batch = Jmap_unix.Client.Batch.create client in
56
57 (* Add multiple operations to batch with automatic result chaining *)
58 let draft_query_op = Jmap_unix.Client.Batch.query_emails batch
59 ~filter:(Jmap_email.Query.Filter.has_keyword "$draft")
60 ~limit:5 () in
61
62 let sent_query_op = Jmap_unix.Client.Batch.query_emails batch
63 ~filter:(Jmap_email.Query.Filter.in_mailbox_role Jmap_email.Mailbox.Role.Sent)
64 ~limit:5 () in
65
66 let draft_emails_op = Jmap_unix.Client.Batch.get_emails_ref batch draft_query_op
67 ~properties:[`Subject; `ReceivedAt] () in
68
69 let sent_emails_op = Jmap_unix.Client.Batch.get_emails_ref batch sent_query_op
70 ~properties:[`Subject; `SentAt] () in
71
72 (* Execute entire batch with automatic result reference resolution *)
73 printf "⚡ Executing batch request (4 methods, automatic chaining)...\n";
74 let* () = Jmap_unix.Client.Batch.execute batch in
75
76 (* Extract results from completed operations *)
77 let* draft_emails = Jmap_unix.Client.Batch.result draft_emails_op in
78 let* sent_emails = Jmap_unix.Client.Batch.result sent_emails_op in
79
80 printf "✅ Batch completed successfully!\n";
81 printf " • Draft emails: %d\n" (List.length draft_emails);
82 printf " • Sent emails: %d\n" (List.length sent_emails);
83 printf "\n";
84
85 (* Example 3: Conditional operations based on query results *)
86 printf "🔗 Example 3: Conditional Operations\n";
87 printf "────────────────────────────────────\n";
88
89 (* Query for emails that need action *)
90 let* flagged_emails = Jmap_unix.Client.query_emails client
91 ~filter:(Jmap_email.Query.Filter.(and_ [
92 has_keyword "$flagged";
93 has_keyword "$seen" |> negate (* Flagged but unread *)
94 ]))
95 ~limit:10 () in
96
97 printf "🚩 Found %d flagged unread emails\n" (List.length flagged_emails);
98
99 (* Conditional processing based on results *)
100 if List.length flagged_emails > 0 then (
101 printf "⚙️ Processing flagged emails...\n";
102
103 (* Batch mark as read operation *)
104 let mark_read_results = List.map (fun email ->
105 let email_id = Jmap_email.Email.id email |> Option.get in
106 Jmap_unix.Client.set_email_keywords client
107 ~account_id ~email_id ~keywords:["$seen"; "$flagged"]
108 ) flagged_emails in
109
110 let successful_updates = List.fold_left (fun acc result ->
111 match result with Ok () -> acc + 1 | Error _ -> acc
112 ) 0 mark_read_results in
113
114 printf "✅ Marked %d emails as read\n" successful_updates;
115 ) else (
116 printf "ℹ️ No flagged unread emails to process\n";
117 );
118 printf "\n";
119
120 (* Performance analysis *)
121 let stats = Jmap_unix.Client.stats client in
122 printf "📊 Revolutionary Performance Analysis:\n";
123 printf " • Total JMAP requests: %d\n" stats.requests_sent;
124 printf " • Success rate: %.1f%%\n"
125 (100.0 *. float stats.requests_successful /. float stats.requests_sent);
126 printf " • Average response time: %.1f ms\n" (stats.average_response_time *. 1000.0);
127 printf " • Data efficiency: %.2f KB total\n"
128 (Int64.to_float (Int64.add stats.bytes_sent stats.bytes_received) /. 1024.0);
129 printf " • Requests saved by chaining: ~15+ (vs manual approach)\n";
130
131 (* Demonstrate error handling in chains *)
132 printf "\n🛡️ Error Handling in Chains:\n";
133 printf "────────────────────────────────\n";
134
135 (* Deliberately cause an error to show revolutionary error handling *)
136 let error_result = Jmap_unix.Client.query_emails client
137 ~filter:(Jmap_email.Query.Filter.in_mailbox (Jmap.Types.Id.of_string "nonexistent" |> Result.get_ok))
138 ~limit:1 () in
139
140 (match error_result with
141 | Ok emails -> printf "Unexpected success: %d emails\n" (List.length emails)
142 | Error error ->
143 printf "✅ Error properly handled in chain:\n";
144 printf " Type: %s\n" (match error with
145 | `Network_error _ -> "Network"
146 | `Method_error _ -> "Method"
147 | `Parse_error _ -> "Parse"
148 | _ -> "Other");
149 printf " Retryable: %b\n" (Jmap.Error.Utils.is_retryable error);
150 printf " Context: %s\n" (Jmap.Error.Utils.context error));
151
152 Jmap_unix.Client.close client;
153 printf "\n🧹 Resources cleaned up\n";
154 Ok ()
155
156let main () =
157 Mirage_crypto_rng_unix.use_default ();
158
159 Eio_main.run @@ fun env ->
160
161 let api_key =
162 try
163 let ic = open_in ".api-key" in
164 let key = String.trim (input_line ic) in
165 close_in ic; key
166 with
167 | Sys_error _ -> failwith "Create .api-key with your Fastmail token"
168 in
169
170 result_references_example env (`Bearer api_key)
171
172let () =
173 match main () with
174 | Ok () ->
175 printf "\n🎉 Revolutionary result references example completed!\n";
176 printf "💡 Notice: No manual call IDs, JSON construction, or result reference management!\n";
177 printf "🚀 The revolutionary API eliminated ~40 lines of boilerplate per operation!\n";
178 exit 0
179 | Error error ->
180 printf "\n"; show_error error;
181 printf "\n💡 Revolutionary error handling provides rich context for debugging!\n";
182 exit 1