Skip to content
Draft
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: 2 additions & 0 deletions Partas.Solid.FablePlugin/Partas.Solid.FablePlugin.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<WarningsAsErrors>3239;0025</WarningsAsErrors>
<PackageId>Partas.Solid.FablePlugin</PackageId>
<Title>Partas.Solid.FablePlugin</Title>
Expand All @@ -27,6 +28,7 @@

<ItemGroup>
<PackageReference Include="Fable.AST" Version="5.0.0-beta.2" />
<PackageReference Update="FSharp.Core" Version="8.0.400" />
</ItemGroup>

</Project>
27 changes: 27 additions & 0 deletions Partas.Solid.TanStack.Store/Partas.Solid.TanStack.Store.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<FablePackageType>library</FablePackageType>
<TargetFramework>net6.0</TargetFramework>
<PackageId>Partas.Solid.TanStack.Store</PackageId>
<Title>Partas.Solid.TanStack.Store</Title>
<RootNamespace>Partas.Solid.TanStack.Store</RootNamespace>
<Authors>Shayan Habibi, Vladimir Schur and Contributors</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>Partas;Solid;TanStack;Store;Fable</PackageTags>
</PropertyGroup>

<ItemGroup>
<Compile Include="Spec.fs" />
<Compile Include="Store.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Fable.Core" Version="5.0.0-beta.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Partas.Solid\Partas.Solid.fsproj" />
</ItemGroup>

</Project>
5 changes: 5 additions & 0 deletions Partas.Solid.TanStack.Store/Spec.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Partas.Solid.TanStack.Store

module Spec =
[<Literal>]
let PackageName = "@tanstack/solid-store"
59 changes: 59 additions & 0 deletions Partas.Solid.TanStack.Store/Store.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace Partas.Solid.TanStack.Store

open Fable.Core
open Fable.Core.JS
open Partas.Solid
open System

[<AutoOpen>]
module Bindings =

/// Store options - use anonymous record with !! operator:
/// new Store(0, !!{| updateFn = fun prev updater -> ... |})
[<Interface>]
type StoreOptions<'T> =
abstract member updateFn: ('T -> ('T -> 'T) -> 'T) option with get
abstract member onUpdate: (unit -> unit) option with get

[<Import("Store", Spec.PackageName)>]
type Store<'T>(initialValue: 'T, ?options: StoreOptions<'T>) =
member _.state: 'T = jsNative
member _.setState(updater: 'T -> 'T) : unit = jsNative
member _.setState(newState: 'T) : unit = jsNative
member _.subscribe(callback: unit -> unit) : (unit -> unit) = jsNative

[<ImportMember(Spec.PackageName)>]
let batch (fn: unit -> unit) : unit = jsNative

[<Interface>]
type DerivedFnProps<'T> =
abstract member prevVal: 'T option with get
abstract member prevDepVals: obj[] option with get
abstract member currDepVals: obj[] with get

[<Pojo>]
type DerivedOptions<'T>(fn: DerivedFnProps<'T> -> 'T, deps: obj[]) =
member val fn = fn with get, set
member val deps = deps with get, set
member val onSubscribe: (Action<'T> * Derived<'T> -> (unit -> unit)) option = None with get, set
member val onUpdate: (unit -> unit) option = None with get, set

and [<Import("Derived", Spec.PackageName)>] Derived<'T>(options: DerivedOptions<'T>) =
member _.state: 'T = jsNative
member _.mount() : (unit -> unit) = jsNative

[<Pojo>]
type EffectOptions(fn: unit -> unit, deps: obj[]) =
member val fn = fn with get, set
member val deps = deps with get, set
member val eager = false with get, set

[<Import("Effect", Spec.PackageName)>]
type Effect(options: EffectOptions) =
member _.mount() : (unit -> unit) = jsNative

[<ImportMember(Spec.PackageName)>]
let useStore (store: Store<'T>) (selector: 'T -> 'U) : Accessor<'U> = jsNative

[<ImportMember(Spec.PackageName)>]
let useStoreFull (store: Store<'T>) : Accessor<'T> = jsNative
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,37 @@
<Content Include="SolidCases\SolidComponentAsTagValues\SolidComponentAsTagValues.expected" />
<Compile Include="SolidCases\ValueUnrollerDecisionTree\ValueUnrollerDecisionTree.fs" />
<Content Include="SolidCases\ValueUnrollerDecisionTree\ValueUnrollerDecisionTree.expected" />
<Compile Include="TanStackStoreCases\BasicStore\BasicStore.fs" />
<Content Include="TanStackStoreCases\BasicStore\BasicStore.expected" />
<Compile Include="TanStackStoreCases\UseStoreFull\UseStoreFull.fs" />
<Content Include="TanStackStoreCases\UseStoreFull\UseStoreFull.expected" />
<Compile Include="TanStackStoreCases\RecordState\RecordState.fs" />
<Content Include="TanStackStoreCases\RecordState\RecordState.expected" />
<Compile Include="TanStackStoreCases\DerivedStore\DerivedStore.fs" />
<Content Include="TanStackStoreCases\DerivedStore\DerivedStore.expected" />
<Compile Include="TanStackStoreCases\EffectStore\EffectStore.fs" />
<Content Include="TanStackStoreCases\EffectStore\EffectStore.expected" />
<Compile Include="TanStackStoreCases\Subscribe\Subscribe.fs" />
<Content Include="TanStackStoreCases\Subscribe\Subscribe.expected" />
<Compile Include="TanStackStoreCases\StoreOptions\StoreOptions.fs" />
<Content Include="TanStackStoreCases\StoreOptions\StoreOptions.expected" />
<Compile Include="TanStackStoreCases\BatchUpdates\BatchUpdates.fs" />
<Content Include="TanStackStoreCases\BatchUpdates\BatchUpdates.expected" />
<Compile Include="TanStackStoreCases\DerivedPrevVal\DerivedPrevVal.fs" />
<Content Include="TanStackStoreCases\DerivedPrevVal\DerivedPrevVal.expected" />
<Compile Include="TanStackStoreCases\DerivedDepVals\DerivedDepVals.fs" />
<Content Include="TanStackStoreCases\DerivedDepVals\DerivedDepVals.expected" />
<Compile Include="TanStackStoreCases\EffectEager\EffectEager.fs" />
<Content Include="TanStackStoreCases\EffectEager\EffectEager.expected" />
<Compile Include="TanStackStoreCases\MountUnmount\MountUnmount.fs" />
<Content Include="TanStackStoreCases\MountUnmount\MountUnmount.expected" />
<!-- <Content Include="Spec\Components.fs" />-->
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Partas.Solid.FablePlugin\Partas.Solid.FablePlugin.fsproj" />
<ProjectReference Include="..\..\Partas.Solid\Partas.Solid.fsproj" />
<ProjectReference Include="..\..\Partas.Solid.TanStack.Store\Partas.Solid.TanStack.Store.fsproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

import { useStore, Store } from "@tanstack/solid-store";
import { int32ToString } from "../../fable_modules/fable-library-js.5.0.0-alpha.14/Util.js";

export const store = new Store(0);

export function Component() {
const count = useStore(store, (state) => (state | 0));
return <div on:click={(_arg) => {
store.setState((s) => ((s + 1) | 0));
}}>
{int32ToString(count())}
</div>;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module BasicStore

open Partas.Solid
open Partas.Solid.TanStack.Store

let store = new Store<int> (0)

[<SolidComponent>]
let Component () =
let count = useStore store (fun state -> state)

div().on ("click", fun _ -> store.setState (fun s -> s + 1)) { string (count ()) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import { batch, Store } from "@tanstack/solid-store";

export const store = new Store(0);

export function performBatchUpdate() {
batch(() => {
store.setState((_arg) => 1);
store.setState((_arg_1) => 2);
store.setState((s) => ((s + 1) | 0));
});
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module BatchUpdates

open Partas.Solid.TanStack.Store

let store = new Store<int> (0)

let performBatchUpdate () =
batch (fun () ->
store.setState (fun _ -> 1)
store.setState (fun _ -> 2)
store.setState (fun s -> s + 1))
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import { Derived, Store } from "@tanstack/solid-store";
import { map, defaultArg } from "../../fable_modules/fable-library-js.5.0.0-alpha.14/Option.js";
import { item } from "../../fable_modules/fable-library-js.5.0.0-alpha.14/Array.js";

export const count = new Store(1);

export const sumWithPrev = new Derived({
fn: (props) => ((defaultArg(map((arr) => (item(0, arr) | 0), props.prevDepVals), 0) + item(0, props.currDepVals)) | 0),
deps: [count],
});

export const unmount = sumWithPrev.mount();

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module DerivedDepVals

open Partas.Solid.TanStack.Store

let count = new Store<int> (1)

let sumWithPrev =
new Derived<int> (
DerivedOptions (
(fun props ->
let prevDep =
props.prevDepVals
|> Option.map (fun arr -> unbox<int> arr[0])
|> Option.defaultValue 0

let currDep = unbox<int> props.currDepVals[0]

prevDep
+ currDep),
[| count |]
)
)

let unmount = sumWithPrev.mount ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

import { Derived, Store } from "@tanstack/solid-store";
import { defaultArg } from "../../fable_modules/fable-library-js.5.0.0-alpha.14/Option.js";

export const count = new Store(1);

export const runningTotal = new Derived({
fn: (props) => {
const prev = defaultArg(props.prevVal, 0) | 0;
return (count.state + prev) | 0;
},
deps: [count],
});

export const unmount = runningTotal.mount();

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module DerivedPrevVal

open Partas.Solid.TanStack.Store

let count = new Store<int> (1)

let runningTotal =
new Derived<int> (
DerivedOptions (
(fun props ->
let prev =
props.prevVal
|> Option.defaultValue 0

count.state
+ prev),
[| count |]
)
)

let unmount = runningTotal.mount ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

import { useStore, Derived, Store } from "@tanstack/solid-store";

export const countStore = new Store(5);

export const doubledOptions = {
fn: (props) => ((countStore.state * 2) | 0),
deps: [countStore],
};

export const doubled = new Derived(doubledOptions);

export function Component() {
const count = useStore(countStore, (s) => (s | 0));
return <div>
<span>
{`Count: ${count()}`}
</span>
<span>
{`Doubled: ${doubled.state}`}
</span>
<button on:click={(_arg) => {
countStore.setState((s_1) => ((s_1 + 1) | 0));
}}>
Increment
</button>
</div>;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module DerivedStore

open Partas.Solid
open Partas.Solid.TanStack.Store

let countStore = new Store<int> (5)

let doubledOptions =
DerivedOptions (
(fun props ->
let current = countStore.state

current
* 2),
[| countStore |]
)

let doubled = new Derived<int> (doubledOptions)

[<SolidComponent>]
let Component () =
let count = useStore countStore (fun s -> s)

div () {
span () { $"Count: {count ()}" }
span () { $"Doubled: {doubled.state}" }
button().on ("click", fun _ -> countStore.setState (fun s -> s + 1)) { "Increment" }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

import { Effect, Store } from "@tanstack/solid-store";
import { some } from "../../fable_modules/fable-library-js.5.0.0-alpha.14/Option.js";

export const store = new Store(0);

export const eagerEffect = (() => {
const opts = {
fn: () => {
console.log(some("Immediate effect:"), store.state);
},
deps: [store],
};
opts.eager = true;
return new Effect(opts);
})();

export const unmount = eagerEffect.mount();

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module EffectEager

open Partas.Solid.TanStack.Store
open Fable.Core.JS

let store = new Store<int> (0)

let eagerEffect =
let opts =
EffectOptions ((fun () -> console.log ("Immediate effect:", store.state)), [| store |])

opts.eager <- true
new Effect (opts)

let unmount = eagerEffect.mount ()
Loading