From d9d81da1a64e2b3c593ba4d661bdf30f1b28a6e8 Mon Sep 17 00:00:00 2001 From: Antonio Nuno Monteiro Date: Tue, 12 Dec 2023 05:27:12 -0800 Subject: [PATCH] feat: improve Js.Dict API (#974) * feat: improve Js.Dict API * chore: add changelog entry --- Changes.md | 2 ++ jscomp/runtime/js_dict.ml | 19 ++++++++----------- jscomp/runtime/js_dict.mli | 8 +++----- jscomp/runtime/js_json.mli | 2 +- jscomp/test/js_dict_test.ml | 2 +- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Changes.md b/Changes.md index 3ab3c85935..13f9fac9bc 100644 --- a/Changes.md +++ b/Changes.md @@ -103,6 +103,8 @@ Unreleased ([#972](https://github.com/melange-re/melange/pull/972)) - BREAKING(runtime): Add labeled arguments to the callbacks in `Js.Global` ([#973](https://github.com/melange-re/melange/pull/973)) +- BREAKING(runtime): Add a label to `Js.Dict.map`'s function argument pipe-last + ([#974](https://github.com/melange-re/melange/pull/974)) 2.2.0 2023-12-05 --------------- diff --git a/jscomp/runtime/js_dict.ml b/jscomp/runtime/js_dict.ml index d998e9f801..da5174125f 100644 --- a/jscomp/runtime/js_dict.ml +++ b/jscomp/runtime/js_dict.ml @@ -35,9 +35,8 @@ external unsafeGet : 'a t -> key -> 'a = "" [@@mel.get_index] (** [unsafeGet dict key] returns the value associated with [key] in [dict] -This function will return an invalid value ([undefined]) if [key] does not exist in [dict]. It -will not throw an error. -*) + This function will return an invalid value ([undefined]) if [key] does not + exist in [dict]. It will not throw an error. *) let ( .!() ) = unsafeGet @@ -53,8 +52,8 @@ external set : 'a t -> key -> 'a -> unit = "" [@@mel.set_index] (** [set dict key value] sets the value of [key] in [dict] to [value] *) -external keys : 'a t -> key array = "Object.keys" - +external keys : 'a t -> key array = "keys" +[@@mel.scope "Object"] (** [keys dict] returns an array of all the keys in [dict] *) external empty : unit -> 'a t = "" @@ -67,24 +66,22 @@ let unsafeDeleteKey : (string t -> string -> unit[@u]) = } |}] -external unsafeCreate : int -> 'a array = "Array" [@@mel.new] +external unsafeCreateArray : int -> 'a array = "Array" [@@mel.new] -(* external entries : 'a t -> (key * 'a) array = "Object.entries" (* ES2017 *) *) let entries dict = let keys = keys dict in let l = Js_array.length keys in - let values = unsafeCreate l in + let values = unsafeCreateArray l in for i = 0 to l - 1 do let key = Js_array.unsafe_get keys i in Js_array.unsafe_set values i (key, dict.!(key)) done; values -(* external values : 'a t -> 'a array = "Object.values" (* ES2017 *) *) let values dict = let keys = keys dict in let l = Js_array.length keys in - let values = unsafeCreate l in + let values = unsafeCreateArray l in for i = 0 to l - 1 do Js_array.unsafe_set values i dict.!(Js_array.unsafe_get keys i) done; @@ -109,7 +106,7 @@ let fromArray entries = done; dict -let map f source = +let map ~f source = let target = empty () in let keys = keys source in let l = Js_array.length keys in diff --git a/jscomp/runtime/js_dict.mli b/jscomp/runtime/js_dict.mli index 94f09598bc..2a089ff613 100644 --- a/jscomp/runtime/js_dict.mli +++ b/jscomp/runtime/js_dict.mli @@ -51,8 +51,8 @@ external set : 'a t -> key -> 'a -> unit = "" [@@mel.set_index] (** [set dict key value] sets the [key]/[value] in [dict] *) -external keys : 'a t -> string array = "Object.keys" - +external keys : 'a t -> string array = "keys" +[@@mel.scope "Object"] (** [keys dict] returns all the keys in the dictionary [dict]*) external empty : unit -> 'a t = "" @@ -64,11 +64,9 @@ module Js := Js_internal val unsafeDeleteKey : (string t -> string -> unit[@u]) (** Experimental internal function *) -(* external entries : 'a t -> (key * 'a) array = "Object.entries" *) val entries : 'a t -> (key * 'a) array (** [entries dict] returns the key value pairs in [dict] (ES2017) *) -(* external values : 'a t -> 'a array = "Object.values" *) val values : 'a t -> 'a array (** [values dict] returns the values in [dict] (ES2017) *) @@ -80,6 +78,6 @@ val fromArray : (key * 'a) array -> 'a t (** [fromArray entries] creates a new dictionary containing each [(key, value)] pair in [entries] *) -val map : (('a -> 'b)[@u]) -> 'a t -> 'b t +val map : f:(('a -> 'b)[@u]) -> 'a t -> 'b t (** [map f dict] maps [dict] to a new dictionary with the same keys, using [f] to map each value *) diff --git a/jscomp/runtime/js_json.mli b/jscomp/runtime/js_json.mli index adbb4dd5eb..b81d706199 100644 --- a/jscomp/runtime/js_json.mli +++ b/jscomp/runtime/js_json.mli @@ -104,7 +104,7 @@ external object_ : t Js_dict.t -> t = "%identity" (** [object_ dict] makes a JSON object of the [Js.Dict.t] [dict] *) external array : t array -> t = "%identity" -(** [array_ a] makes a JSON array of the [Js.Json.t array] [a] *) +(** [array a] makes a JSON array of the [Js.Json.t array] [a] *) (** The functions below are specialized for specific array type which happened to be already JSON object in the Melange runtime. Therefore diff --git a/jscomp/test/js_dict_test.ml b/jscomp/test/js_dict_test.ml index 70c8df1ce1..5f9a277ab5 100644 --- a/jscomp/test/js_dict_test.ml +++ b/jscomp/test/js_dict_test.ml @@ -31,6 +31,6 @@ let suites = Mt.[ Eq([|("x", 23); ("y", 46)|], fromArray [|("x", 23); ("y", 46)|] |> entries)); "map", (fun _ -> Eq( [%obj { foo = "43"; bar = "86" }] |> Obj.magic, - map (fun [@u] i -> string_of_int i) (obj ()))) + map ~f:(fun [@u] i -> string_of_int i) (obj ()))) ] ;; Mt.from_pair_suites __MODULE__ suites