├── .ocamlformat ├── CHANGES.md ├── .gitignore ├── bsconfig.json ├── README.md ├── package.json ├── LICENSE └── src ├── swr.ml ├── swr.mli ├── swr_options.ml └── swr_raw.ml /.ocamlformat: -------------------------------------------------------------------------------- 1 | field-space = tight-decl 2 | break-separators = after 3 | break-cases = fit 4 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # 0.3.0 2 | - Fixed and added fetcher parameter to non-bound `mutate` 3 | 4 | # 0.2.7 5 | - Added `revalidateOnMount` option (#1, @jibingeo) 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .vscode 3 | .merlin 4 | .bsb.lock 5 | npm-debug.log 6 | /lib/bs/ 7 | /lib/ocaml/ 8 | /node_modules/ 9 | debug.log 10 | *.cmi 11 | *.cmj 12 | *.cmt 13 | *.bs.js 14 | -------------------------------------------------------------------------------- /bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@roddynpm/bs-swr", 3 | "version": "0.1.0", 4 | "sources": { 5 | "dir" : "src", 6 | "subdirs" : true 7 | }, 8 | "package-specs": { 9 | "module": "commonjs", 10 | "in-source": true 11 | }, 12 | "suffix": ".bs.js", 13 | "bs-dependencies": [ 14 | 15 | ], 16 | "warnings": { 17 | "error" : "+101" 18 | }, 19 | "namespace": false, 20 | "refmt": 3 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bs-swr 2 | BuckleScript bindings to [SWR](https://github.com/zeit/swr). 3 | 4 | ## Installation 5 | Add 6 | ``` 7 | "@roddynpm/bs-swr": "^0.2.5", 8 | "swr": "^0.2.0", 9 | ``` 10 | as dependencies to `package.json` and `@roddynpm/bs-swr` to `bsconfig.json`. 11 | 12 | ## Example 13 | ```reason 14 | [@react.component] 15 | let make = () => { 16 | let config = Swr.Options.make(~dedupingInterval=6000, ()); 17 | let Swr.{data} = Swr.useSWR(~config, "key", _ => load_data()); 18 | 19 | switch (data) { 20 | | Some(data) => render(data) 21 | | None => render_loading() 22 | }; 23 | }; 24 | ``` 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@roddynpm/bs-swr", 3 | "version": "0.3.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/roddyyaga/bs-swr.git" 7 | }, 8 | "scripts": { 9 | "prepare": "npm run clean && bsb -make-world", 10 | "build": "bsb -make-world", 11 | "start": "bsb -make-world -w", 12 | "clean": "bsb -clean-world" 13 | }, 14 | "keywords": [ 15 | "BuckleScript", 16 | "ReasonML", 17 | "OCaml" 18 | ], 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/roddyyaga/bs-swr/issues" 22 | }, 23 | "homepage": "https://github.com/roddyyaga/bs-swr#readme", 24 | "devDependencies": { 25 | "bs-platform": "^7.0.0" 26 | }, 27 | "dependencies": { 28 | "swr": ">=0.2.1" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Roddy MacSween 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/swr.ml: -------------------------------------------------------------------------------- 1 | module Options = Swr_options 2 | module Raw = Swr_raw 3 | 4 | type 'data bound_mutate = 5 | ?data:'data -> ?shouldRevalidate:bool -> unit -> 'data option Js.Promise.t 6 | 7 | type 'data responseInterface = { 8 | data: 'data option; 9 | error: Js.Promise.error; 10 | revalidate: unit -> bool Js.Promise.t; 11 | mutate: 'data bound_mutate; 12 | isValidating: bool; 13 | } 14 | 15 | let wrap_raw_response_intf = function[@warning "-45"] 16 | | Raw.{ data; error; revalidate; mutate; isValidating } -> 17 | let wrapped_mutate ?data ?shouldRevalidate () = 18 | mutate data shouldRevalidate 19 | in 20 | { data; error; revalidate; isValidating; mutate = wrapped_mutate } 21 | 22 | let useSWR ?config x f = 23 | match config with 24 | | None -> Raw.useSWR1 [| x |] f |> wrap_raw_response_intf 25 | | Some config -> 26 | let raw_config = Options.to_configInterface config in 27 | Raw.useSWR1_config [| x |] f raw_config |> wrap_raw_response_intf 28 | 29 | let useSWR_string x f = Raw.useSWR_string x f |> wrap_raw_response_intf 30 | 31 | let mutate ?f key = 32 | match f with 33 | | Some f -> Raw.mutate2_one_item_array_fetcher [| key |] f 34 | | None -> Raw.mutate1_one_item_array [| key |] 35 | -------------------------------------------------------------------------------- /src/swr.mli: -------------------------------------------------------------------------------- 1 | module Options : sig 2 | type t = Swr_options.t = { 3 | errorRetryInterval: int option; 4 | errorRetryCount: int option; 5 | loadingTimeout: int option; 6 | focusThrottleInterval: int option; 7 | dedupingInterval: int option; 8 | refreshInterval: int option; 9 | refreshWhenHidden: bool option; 10 | refreshWhenOffline: bool option; 11 | revalidateOnFocus: bool option; 12 | revalidateOnMount: bool option; 13 | revalidateOnReconnect: bool option; 14 | shouldRetryOnError: bool option; 15 | suspense: bool option; 16 | } 17 | 18 | val make : 19 | ?suspense:bool -> 20 | ?revalidateOnFocus:bool -> 21 | ?revalidateOnReconnect:bool -> 22 | ?revalidateOnMount:bool -> 23 | ?refreshInterval:int -> 24 | ?refreshWhenHidden:bool -> 25 | ?refreshWhenOffline:bool -> 26 | ?shouldRetryOnError:bool -> 27 | ?dedupingInterval:int -> 28 | ?focusThrottleInterval:int -> 29 | ?loadingTimeout:int -> 30 | ?errorRetryInterval:int -> 31 | ?errorRetryCount:int -> 32 | unit -> 33 | t 34 | 35 | val default : t 36 | 37 | val to_configInterface : 38 | ?initialData:'a -> 39 | ?onLoadingSlow:('b -> ('b, 'a) Swr_raw.configInterface -> unit) -> 40 | ?onSuccess:('a -> 'b -> ('b, 'a) Swr_raw.configInterface -> unit) -> 41 | ?onError: 42 | (Js.Promise.error -> 'b -> ('b, 'a) Swr_raw.configInterface -> unit) -> 43 | ?onErrorRetry: 44 | (Js.Promise.error -> 45 | 'b -> 46 | ('b, 'a) Swr_raw.configInterface -> 47 | Swr_raw.revalidateType -> 48 | Swr_raw.revalidateOptionInterface -> 49 | unit) -> 50 | ?compare:('a option -> 'a option -> bool) -> 51 | t -> 52 | ('b, 'a) Swr_raw.configInterface 53 | end 54 | 55 | type 'data bound_mutate = 56 | ?data:'data -> ?shouldRevalidate:bool -> unit -> 'data option Js.Promise.t 57 | 58 | type 'data responseInterface = { 59 | data: 'data option; 60 | error: Js.Promise.error; 61 | revalidate: unit -> bool Js.Promise.t; 62 | mutate: 'data bound_mutate; 63 | isValidating: bool; 64 | } 65 | 66 | val useSWR : 67 | ?config:Options.t -> 68 | 'key -> 69 | ('key -> 'data Js.Promise.t) -> 70 | 'data responseInterface 71 | 72 | val useSWR_string : 73 | string -> (string -> 'data Js.Promise.t) -> 'data responseInterface 74 | 75 | val mutate : 76 | ?f:('key -> 'data Js.Promise.t) -> 'key -> 'data option Js.Promise.t 77 | -------------------------------------------------------------------------------- /src/swr_options.ml: -------------------------------------------------------------------------------- 1 | type t = { 2 | errorRetryInterval: int option; 3 | errorRetryCount: int option; 4 | loadingTimeout: int option; 5 | focusThrottleInterval: int option; 6 | dedupingInterval: int option; 7 | refreshInterval: int option; 8 | refreshWhenHidden: bool option; 9 | refreshWhenOffline: bool option; 10 | revalidateOnFocus: bool option; 11 | revalidateOnMount: bool option; 12 | revalidateOnReconnect: bool option; 13 | shouldRetryOnError: bool option; 14 | suspense: bool option; 15 | } 16 | 17 | let make ?(suspense = false) ?(revalidateOnFocus = true) 18 | ?(revalidateOnReconnect = true) ?(revalidateOnMount = false) 19 | ?(refreshInterval = 0) ?(refreshWhenHidden = false) 20 | ?(refreshWhenOffline = false) ?(shouldRetryOnError = true) 21 | ?(dedupingInterval = 2000) ?(focusThrottleInterval = 5000) 22 | ?(loadingTimeout = 3000) ?(errorRetryInterval = 5000) 23 | ?errorRetryCount () = 24 | { 25 | errorRetryInterval = Some errorRetryInterval; 26 | errorRetryCount; 27 | loadingTimeout = Some loadingTimeout; 28 | focusThrottleInterval = Some focusThrottleInterval; 29 | dedupingInterval = Some dedupingInterval; 30 | refreshInterval = Some refreshInterval; 31 | refreshWhenHidden = Some refreshWhenHidden; 32 | refreshWhenOffline = Some refreshWhenOffline; 33 | revalidateOnFocus = Some revalidateOnFocus; 34 | revalidateOnMount= Some revalidateOnMount; 35 | revalidateOnReconnect = Some revalidateOnReconnect; 36 | shouldRetryOnError = Some shouldRetryOnError; 37 | suspense = Some suspense; 38 | } 39 | 40 | let default = make () 41 | 42 | let to_configInterface ?initialData ?onLoadingSlow ?onSuccess ?onError 43 | ?onErrorRetry ?compare 44 | { 45 | errorRetryInterval; 46 | errorRetryCount; 47 | loadingTimeout; 48 | focusThrottleInterval; 49 | dedupingInterval; 50 | refreshInterval; 51 | refreshWhenHidden; 52 | refreshWhenOffline; 53 | revalidateOnFocus; 54 | revalidateOnMount; 55 | revalidateOnReconnect; 56 | shouldRetryOnError; 57 | suspense; 58 | } = 59 | Swr_raw.configInterface ?errorRetryInterval ?errorRetryCount ?loadingTimeout 60 | ?focusThrottleInterval ?dedupingInterval ?refreshInterval ?refreshWhenHidden 61 | ?refreshWhenOffline ?revalidateOnFocus ?revalidateOnReconnect ?revalidateOnMount 62 | ?shouldRetryOnError ?suspense ?initialData ?onLoadingSlow ?onSuccess 63 | ?onError ?onErrorRetry ?compare () 64 | -------------------------------------------------------------------------------- /src/swr_raw.ml: -------------------------------------------------------------------------------- 1 | type 'data bound_mutate = 2 | 'data option -> bool option -> 'data option Js.Promise.t 3 | 4 | type 'data responseInterface = { 5 | data: 'data option; 6 | error: Js.Promise.error; 7 | revalidate: unit -> bool Js.Promise.t; 8 | mutate: 'data bound_mutate; 9 | isValidating: bool; 10 | } 11 | 12 | type revalidateOptionInterface = { retryCount: int option; dedupe: bool option } 13 | 14 | type revalidateType = revalidateOptionInterface -> bool Js.Promise.t 15 | 16 | external fast_deep_equal : 'a -> 'a -> bool = "default" 17 | [@@bs.val] [@@bs.module "fast-deep-equal/es6"] 18 | 19 | type ('key, 'data) configInterface = { 20 | (* Global options *) 21 | errorRetryInterval: int; [@bs.optional] 22 | errorRetryCount: int; [@bs.optional] 23 | loadingTimeout: int; [@bs.optional] 24 | focusThrottleInterval: int; [@bs.optional] 25 | dedupingInterval: int; [@bs.optional] 26 | refreshInterval: int; [@bs.optional] 27 | refreshWhenHidden: bool; [@bs.optional] 28 | refreshWhenOffline: bool; [@bs.optional] 29 | revalidateOnFocus: bool; [@bs.optional] 30 | revalidateOnMount: bool; [@bs.optional] 31 | revalidateOnReconnect: bool; [@bs.optional] 32 | shouldRetryOnError: bool; [@bs.optional] 33 | suspense: bool; [@bs.optional] 34 | initialData: 'data; [@bs.optional] 35 | onLoadingSlow: 'key -> ('key, 'data) configInterface -> unit; [@bs.optional] 36 | onSuccess: 'data -> 'key -> ('key, 'data) configInterface -> unit; 37 | [@bs.optional] 38 | onError: Js.Promise.error -> 'key -> ('key, 'data) configInterface -> unit; 39 | [@bs.optional] 40 | onErrorRetry: 41 | Js.Promise.error -> 42 | 'key -> 43 | ('key, 'data) configInterface -> 44 | revalidateType -> 45 | revalidateOptionInterface -> 46 | unit; 47 | [@bs.optional] 48 | compare: 'data option -> 'data option -> bool; [@bs.optional] 49 | } 50 | [@@bs.deriving abstract] 51 | 52 | external useSWR_string : 53 | string -> (string -> 'data Js.Promise.t) -> 'data responseInterface 54 | = "default" 55 | [@@bs.val] [@@bs.module "swr"] 56 | 57 | external useSWR_string_config : 58 | string -> 59 | (string -> 'data Js.Promise.t) -> 60 | (string, 'data) configInterface -> 61 | 'data responseInterface = "default" 62 | [@@bs.val] [@@bs.module "swr"] 63 | 64 | (* array must be of length 1 *) 65 | external useSWR1 : 66 | 'param array -> ('param -> 'data Js.Promise.t) -> 'data responseInterface 67 | = "default" 68 | [@@bs.val] [@@bs.module "swr"] 69 | 70 | (* array must be of length 1 *) 71 | external useSWR1_config : 72 | 'param array -> 73 | ('param -> 'data Js.Promise.t) -> 74 | ('param array, 'data) configInterface -> 75 | 'data responseInterface = "default" 76 | [@@bs.val] [@@bs.module "swr"] 77 | 78 | external useSWR2 : 79 | 'a * 'b -> ('a -> 'b -> 'data Js.Promise.t) -> 'data responseInterface 80 | = "default" 81 | [@@bs.val] [@@bs.module "swr"] 82 | 83 | external useSWR2_config : 84 | 'a * 'b -> 85 | ('a -> 'b -> 'data Js.Promise.t) -> 86 | ('a * 'b, 'data) configInterface -> 87 | 'data responseInterface = "default" 88 | [@@bs.val] [@@bs.module "swr"] 89 | 90 | external mutate1_one_item_array : 'param array -> 'data option Js.Promise.t 91 | = "mutate" 92 | [@@bs.val] [@@bs.module "swr"] 93 | 94 | external mutate2_one_item_array_fetcher : 95 | 'param array -> ('param -> 'data Js.Promise.t) -> 'data option Js.Promise.t 96 | = "mutate" 97 | [@@bs.val] [@@bs.module "swr"] 98 | 99 | external mutate2_shouldRevalidate : 'key -> bool -> 'data option Js.Promise.t 100 | = "mutate" 101 | [@@bs.val] [@@bs.module "swr"] 102 | --------------------------------------------------------------------------------