Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
    • Help
    • Submit feedback
    • Contribute to GitLab
  • Sign in
H
Hello Gargan
  • Project
    • Project
    • Details
    • Activity
    • Releases
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 0
    • Issues 0
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
    • Charts
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • arturo
  • Hello Gargan
  • Wiki
    • 2—components
  • 2.3—Store structure

2.3—Store structure

Last edited by arturo Jun 14, 2021
Page history

As said previously, these files are very similar from existing abstractions such as Vuex, Redux, Flux, etc. Basically the overall structure can be comprehend as a global Record RootStore containing every existing stores of the project. Individual stores module are structured with implicit implementation:

  • determined filepath — filename representation: (note: automation still on work in progress) for example by creating a Hello.Stores.Foo.Bar store module, we create a rootStore { "foo/bar": store | rootStore }, ie. a new Row within the RootStore type
  • determined variable and type names: each module has to export a certain amount of attended variables
  • Store & State types: refering to both Record: a "boxed" Toestand representation, and its vanilla values
  • state variable: thunk hydrating default values of the store module
module Hello.Stores.Public.Authentication
  -- mandatory exports
  ( state
  , State
  , Store
  -- custom exports
  , login
  , LoginData
  ) where

import Prelude

import Data.Either (Either)
import Effect.Aff (Aff, Error, Milliseconds(..), attempt, delay)
import Effect.Class (liftEffect)
import Toestand as T

type Store =
  ( onPending :: T.Box (Boolean)
  )

type State =
  ( onPending :: Boolean
  )

state :: Unit -> Record State
state = \_ ->
  { onPending: false
  }

type LoginData =
  ( email :: String
  , password :: String
  )

-- Below is an example of "actions" (from the predictable state container
-- jargon). They are asynchroneous computations made on the current store

login :: Record Store -> Record LoginData -> Aff (Either Error Unit)
login { onPending } _  = do

  liftEffect $ T.write_ true onPending

  result <- attempt $ simulateAPIRequest

  liftEffect $ T.write_ false onPending

  pure $ result

simulateAPIRequest :: Aff Unit
simulateAPIRequest = delay $ Milliseconds 2000.0

Actions and Mutations

In the above module, we have an example of logic written within the store. It is a common thing with predictable state container library to provide abstracted behaviors of such kinds:

  • "mutations": ~ synchronous computations, mostly individual setters for each stored field
    • as we rely on Toestand, the most valuable solution for this kind of computations is to stick with Toestand API
    • so every setter calls can be executed anywhere in the code, just by reusing T.write, T.modify, etc.
  • "actions": ~ asynchronous computations, two differents types
    • scoped: as illustrated with the login method just above, take the Record Store as an argument and return an Aff *
    • unscoped: take the Record RootStore in first argument, Record Store of the module in second, return an Aff *

Heads up. These definitions regarding "actions" are pragmatic and opinionated. There is no strict implementation to follow here, we just think that this would be the best abstraction possible.


« 2.2 — Page and Layout structure             3.1 — SASS files »
Clone repository
  • 1—Application structure
  • 2—Components
    • 2.1—Component structure
    • 2.2—Page and Layout structure
    • 2.3—Store structure
  • 3—SASS-usage
    • 3.1—SASS files
    • 3.2—CSS integration model
  • 4—UI library
  • 5—Form validation
  • 6—Component Cookbook
  • 7—Miscellaneous
  • 8—Milestones
  • Home
More Pages

New Wiki Page

Tip: You can specify the full path for the new file. We will automatically create any missing directories.