Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"fable": {
"version": "4.9.0",
"version": "4.7.0",
"commands": [
"fable"
]
Expand Down
1 change: 1 addition & 0 deletions src/ElmishStore.Example/ElmishStore.Example.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fable.Elmish.Debugger" Version="4.0.0" />
<PackageReference Include="Feliz" Version="2.8.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ElmishStore\ElmishStore.fsproj" />
Expand Down
72 changes: 39 additions & 33 deletions src/ElmishStore/ElmishStore.fsproj
Original file line number Diff line number Diff line change
@@ -1,35 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageId>Elmish.Store</PackageId>
<Description>A library that merges Elmish and React, providing an external store with efficient, selective component rendering capabilities.</Description>
<PackageTags>fsharp;fable;react;elmish</PackageTags>
<Authors>Łukasz Krzywizna</Authors>
<Company>SelectView Data Solutions</Company>
<Version>0.1.0</Version>
<TargetFramework>net8.0</TargetFramework>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SelectViewData/elmish-store</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<PropertyGroup>
<NpmDependencies>
<NpmPackage Name="use-sync-external-store" Version="&gt;= 1.0.0 &lt; 2.0.0" ResolutionStrategy="Max" />
</NpmDependencies>
</PropertyGroup>
<ItemGroup>
<Compile Include="UseSyncExternalStore.fs" />
<Compile Include="ElmishStore.fs" />
<Compile Include="Hooks.fs" />
</ItemGroup>
<ItemGroup>
<Content Include="*.fsproj; *.fs" Exclude="**\*.fs.js" PackagePath="fable\" />
<Content Include="..\..\readme.md" Pack="true" PackagePath="\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fable.Elmish" Version="4.1.0" />
<PackageReference Include="Feliz" Version="2.7.0" />
<PackageReference Include="Feliz.CompilerPlugins" Version="2.2.0" />
</ItemGroup>
<PropertyGroup>
<PackageId>Elmish.Store</PackageId>
<Description>A library that merges Elmish and React, providing an external store with efficient, selective component rendering capabilities.</Description>
<PackageTags>fsharp;fable;react;elmish</PackageTags>
<Authors>Łukasz Krzywizna</Authors>
<Company>SelectView Data Solutions</Company>
<Version>0.2.1</Version>
<TargetFramework>net6.0</TargetFramework>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SelectViewData/elmish-store</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<PropertyGroup>
<PackageTags>fable-javascript</PackageTags>
<FablePackageType>library</FablePackageType>
</PropertyGroup>
<PropertyGroup>
<NpmDependencies>
<NpmPackage Name="use-sync-external-store" Version="&gt;= 1.0.0 &lt; 2.0.0" ResolutionStrategy="Max" />
</NpmDependencies>
</PropertyGroup>
<ItemGroup>
<Compile Include="UseSyncExternalStore.fs" />
<Compile Include="ElmishStore.fs" />
<Compile Include="Hooks.fs" />
<Compile Include="Extensions.fs" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\readme.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="6" />
<PackageReference Include="Fable.Package.SDK" Version="1.0.0" />
<PackageReference Include="Fable.Elmish" Version="4.1.0" />
<PackageReference Include="Feliz" Version="2.7.0" />
<PackageReference Include="Feliz.CompilerPlugins" Version="2.2.0" />
</ItemGroup>
</Project>
23 changes: 23 additions & 0 deletions src/ElmishStore/Extensions.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace ElmishStore

open Fable.Core
open Feliz
open ElmishStore

[<Erase>]
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
66 changes: 32 additions & 34 deletions src/ElmishStore/Hooks.fs
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
namespace ElmishStore
module ElmishStore.Hooks

open Fable.Core
open Feliz
open ElmishStore

[<Erase>]
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.
[<Hook>]
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.
[<Hook>]
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.
[<Hook>]
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.
[<Hook>]
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.
[<Hook>]
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.
[<Hook>]
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,
(=)
)

1 change: 0 additions & 1 deletion src/ElmishStore/UseSyncExternalStore.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type internal ReactBindings =
) : 'a =
jsNative

[<Hook>]
static member inline useSyncExternalStoreWithSelector
(
subscribe: UseSyncExternalStoreSubscribe,
Expand Down