Stores.purs 1.84 KB
Newer Older
arturo's avatar
arturo committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
module Gargantext.Utils.Stores
  ( createStore
  , provideStore
  , useStore
  ) where

import Gargantext.Prelude

import Prim.RowList (class RowToList)
import Reactix as R
import Toestand as T
import Toestand.Records as TR

-- StoreFactory: R.Hook (Record Store) → create focus boxes, hydrate box values
-- StoreProvider: R.Hooks (Record Store) → provide context with previous boxes
--    ↓
-- StoreHook: R.Hooks (Record Store) → use context

-- | From state values to focused boxes
createStore :: forall boxes l state.
     RowToList state l
  => TR.UseFocusedFields l boxes () (T.Box (Record state))
  => Record state
  -> R.Hooks (Record boxes)
createStore = T.useBox >=> flip T.useFocusedFields {}

-- | Set <Store.Provider> bearing Stores as a Context
-- |
-- | (!) do not use store binds in this specific component (eg. `useStores`)
provideStore :: forall boxes l state.
     RowToList state l
  => TR.UseFocusedFields l boxes () (T.Box (Record state))
  => String
  -> Record state
  -> R.Context (Record boxes)
  -> Array R.Element
  -> R.Element
provideStore name state context
  = R.createElement (R.hooksComponent name cpt) {}
    where
      cpt _ children = do
        store <- createStore state
        pure $ R.provideContext context store $ children

-- | (?) As we use "React Provide API", we just want to rely on its Global
-- |     Reference (and not as Mutable State thanks to "Consumer API")
-- |     Hence the "unsafeCoerce" used on every provided context, avoiding
-- |     unwanted computing at each import
-- |
-- |     It also implies that every call to the proxy reference (made thanks to
arturo's avatar
arturo committed
51
-- |     below `<Store.Provider>` are made AFTER first mount of this very,
arturo's avatar
arturo committed
52 53 54 55 56
-- |     component, otherwise, every call will return the empty `unit`)
useStore :: forall boxes.
     R.Context (Record boxes)
  -> R.Hooks (Record boxes)
useStore = R.useContext