diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 00e49ba..0d4a290 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "fable": { - "version": "4.9.0", + "version": "4.7.0", "commands": [ "fable" ] diff --git a/src/ElmishStore.Example/ElmishStore.Example.fsproj b/src/ElmishStore.Example/ElmishStore.Example.fsproj index 7efec8c..886fe66 100644 --- a/src/ElmishStore.Example/ElmishStore.Example.fsproj +++ b/src/ElmishStore.Example/ElmishStore.Example.fsproj @@ -31,6 +31,7 @@ + diff --git a/src/ElmishStore/ElmishStore.fsproj b/src/ElmishStore/ElmishStore.fsproj index 19c0958..27fa7e4 100644 --- a/src/ElmishStore/ElmishStore.fsproj +++ b/src/ElmishStore/ElmishStore.fsproj @@ -1,35 +1,41 @@ - + - - Elmish.Store - A library that merges Elmish and React, providing an external store with efficient, selective component rendering capabilities. - fsharp;fable;react;elmish - Łukasz Krzywizna - SelectView Data Solutions - 0.1.0 - net8.0 - readme.md - https://github.com/SelectViewData/elmish-store - git - MIT - - - - - - - - - - - - - - - - - - - - + + Elmish.Store + A library that merges Elmish and React, providing an external store with efficient, selective component rendering capabilities. + fsharp;fable;react;elmish + Łukasz Krzywizna + SelectView Data Solutions + 0.2.1 + net6.0 + readme.md + https://github.com/SelectViewData/elmish-store + git + MIT + + + fable-javascript + library + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ElmishStore/Extensions.fs b/src/ElmishStore/Extensions.fs new file mode 100644 index 0000000..e24c5b5 --- /dev/null +++ b/src/ElmishStore/Extensions.fs @@ -0,0 +1,23 @@ +namespace ElmishStore + +open Fable.Core +open Feliz +open ElmishStore + +[] +type React = + + /// Provides a current snapshot of the store's state selected by the selector function. + /// NOTE: Selector returning value needs to be referentially stable. + static member inline useElmishStore(store, selector: 'model -> 'a) = + Hooks.useElmishStore store selector + + /// Provides a current snapshot of the store's state selected by the selector function. + /// The result of the selector function is memoized and compared with isEqual function. + static member inline useElmishStoreMemoized(store, selector: 'model -> 'a, isEqual) = + Hooks.useElmishStoreMemoizedWithCustomEquality store selector isEqual + + /// Provides a current snapshot of the store's state selected by the selector function. + /// The result of the selector function is memoized and compared with structural equality. + static member inline useElmishStoreMemoized(store, selector: 'model -> 'a) = + Hooks.useElmishStoreMemoized store selector \ No newline at end of file diff --git a/src/ElmishStore/Hooks.fs b/src/ElmishStore/Hooks.fs index f904da6..fa4aab5 100644 --- a/src/ElmishStore/Hooks.fs +++ b/src/ElmishStore/Hooks.fs @@ -1,49 +1,47 @@ -namespace ElmishStore +module ElmishStore.Hooks open Fable.Core open Feliz open ElmishStore -[] -type React = - /// Provides a current snapshot of the store's state selected by the selector function. - /// NOTE: Selector returning value needs to be referentially stable. - [] - static member useElmishStore(store, selector: 'model -> 'a) = +/// Provides a current snapshot of the store's state selected by the selector function. +/// NOTE: Selector returning value needs to be referentially stable. +[] +let useElmishStore store (selector: 'model -> 'a) = ReactBindings.useSyncExternalStore ( - store.Subscribe, - React.useCallback ( - (fun () -> store.GetModel() |> selector), - [| box store; box selector |] - ) + store.Subscribe, + React.useCallback ( + (fun () -> store.GetModel() |> selector), + [| box store; box selector |] + ) ) - /// Provides a current snapshot of the store's state selected by the selector function. - /// The result of the selector function is memoized and compared with isEqual function. - [] - static member useElmishStoreMemoized(store, selector: 'model -> 'a, isEqual) = +/// Provides a current snapshot of the store's state selected by the selector function. +/// The result of the selector function is memoized and compared with isEqual function. +[] +let useElmishStoreMemoizedWithCustomEquality store (selector: 'model -> 'a) isEqual = ReactBindings.useSyncExternalStoreWithSelector ( - store.Subscribe, - React.useCallback( - (fun () -> store.GetModel()), - [| box store; box selector |] - ), - selector, - isEqual + store.Subscribe, + React.useCallback( + (fun () -> store.GetModel()), + [| box store; box selector |] + ), + selector, + isEqual ) - /// Provides a current snapshot of the store's state selected by the selector function. - /// The result of the selector function is memoized and compared with structural equality. - [] - static member useElmishStoreMemoized(store, selector: 'model -> 'a) = +/// Provides a current snapshot of the store's state selected by the selector function. +/// The result of the selector function is memoized and compared with structural equality. +[] +let useElmishStoreMemoized store (selector: 'model -> 'a) = ReactBindings.useSyncExternalStoreWithSelector ( - store.Subscribe, - React.useCallback( - (fun () -> store.GetModel()), - [| box store; box selector |] - ), - selector, - (=) + store.Subscribe, + React.useCallback( + (fun () -> store.GetModel()), + [| box store; box selector |] + ), + selector, + (=) ) diff --git a/src/ElmishStore/UseSyncExternalStore.fs b/src/ElmishStore/UseSyncExternalStore.fs index 2322eec..d375758 100644 --- a/src/ElmishStore/UseSyncExternalStore.fs +++ b/src/ElmishStore/UseSyncExternalStore.fs @@ -27,7 +27,6 @@ type internal ReactBindings = ) : 'a = jsNative - [] static member inline useSyncExternalStoreWithSelector ( subscribe: UseSyncExternalStoreSubscribe,