···66type result_reference = {
77 result_of : string;
88 name : string;
99- path : string;
99+ path : Json_pointer.Jmap.t;
1010}
11111212let result_reference ~result_of ~name ~path =
1313 { result_of; name; path }
14141515+let result_reference_of_strings ~result_of ~name ~path =
1616+ { result_of; name; path = Json_pointer.Jmap.of_string path }
1717+1518let result_reference_make result_of name path =
1619 { result_of; name; path }
1720···2023 Jsont.Object.map ~kind result_reference_make
2124 |> Jsont.Object.mem "resultOf" Jsont.string ~enc:(fun r -> r.result_of)
2225 |> Jsont.Object.mem "name" Jsont.string ~enc:(fun r -> r.name)
2323- |> Jsont.Object.mem "path" Jsont.string ~enc:(fun r -> r.path)
2626+ |> Jsont.Object.mem "path" Json_pointer.Jmap.jsont ~enc:(fun r -> r.path)
2427 |> Jsont.Object.finish
2828+2929+(* Result reference resolution *)
3030+3131+let find_response ref ~responses =
3232+ List.find_map (fun (call_id, name, json) ->
3333+ if call_id = ref.result_of && name = ref.name
3434+ then Some json
3535+ else None
3636+ ) responses
3737+3838+let resolve ref ~responses codec =
3939+ match find_response ref ~responses with
4040+ | None ->
4141+ Jsont.Error.msgf Jsont.Meta.none
4242+ "Result reference: no response found for resultOf=%s name=%s"
4343+ ref.result_of ref.name
4444+ | Some json ->
4545+ let extraction_codec = Json_pointer.Jmap.path ref.path codec in
4646+ match Jsont.Json.decode' extraction_codec json with
4747+ | Ok v -> v
4848+ | Error e -> raise (Jsont.Error e)
4949+5050+let resolve_ids ref ~responses =
5151+ resolve ref ~responses (Jsont.list Jsont.string)
25522653type t = {
2754 name : string;
+45-3
proto/invocation.mli
···991010(** A reference to a result from a previous method call.
11111212- Used for back-referencing values within a single request. *)
1212+ Used for back-referencing values within a single request.
1313+ The path is a JMAP extended JSON Pointer (RFC 8620 Section 3.7)
1414+ which may contain [*] wildcards for array mapping. *)
1315type result_reference = {
1416 result_of : string;
1517 (** The method call id to reference. *)
1618 name : string;
1719 (** The method name that was called. *)
1818- path : string;
1919- (** A JSON Pointer to the value within the result. *)
2020+ path : Json_pointer.Jmap.t;
2121+ (** A JMAP extended JSON Pointer to the value within the result.
2222+ May contain [*] wildcards for mapping through arrays. *)
2023}
21242225val result_reference :
2326 result_of:string ->
2427 name:string ->
2828+ path:Json_pointer.Jmap.t ->
2929+ result_reference
3030+3131+val result_reference_of_strings :
3232+ result_of:string ->
3333+ name:string ->
2534 path:string ->
2635 result_reference
3636+(** [result_reference_of_strings] creates a result reference, parsing
3737+ the path string into a JMAP pointer.
3838+ @raise Jsont.Error if the path is not a valid JMAP pointer. *)
27392840val result_reference_jsont : result_reference Jsont.t
4141+4242+(** {2 Typed Extraction}
4343+4444+ These functions extract typed values from method responses using
4545+ the result reference's path. *)
4646+4747+val resolve_ids :
4848+ result_reference ->
4949+ responses:(string * string * Jsont.json) list ->
5050+ string list
5151+(** [resolve_ids ref ~responses] resolves the result reference against
5252+ the list of previous responses and extracts a list of string IDs.
5353+5454+ [responses] is a list of [(method_call_id, method_name, result_json)]
5555+ tuples from previously executed method calls.
5656+5757+ This is the most common pattern in JMAP where result references are
5858+ used to pass IDs between method calls.
5959+6060+ @raise Jsont.Error if resolution fails or the result is not a string list. *)
6161+6262+val resolve :
6363+ result_reference ->
6464+ responses:(string * string * Jsont.json) list ->
6565+ 'a Jsont.t ->
6666+ 'a
6767+(** [resolve ref ~responses codec] resolves the result reference and
6868+ decodes the extracted value with [codec].
6969+7070+ @raise Jsont.Error if resolution fails or decoding fails. *)
29713072(** {1 Invocations} *)
3173