@cerebral/fluent
TypeScript icon, indicating that this package has built-in type declarations

1.0.3 • Public • Published

@cerebral/fluent

Install

npm install @cerebral/fluent

Description

This addon gives you full typesafety using TypeScript. It exposes a chainable API and types to be used with defining your modules, sequences, actions and connecting to components.

Currently only React is supported.

To enable type safe mutations, the model of this addon is based on Mobx.

action

import { sequence, Context } from './myFluent'
import * as actions from './actions'

export const doThis = sequence((s) => s.action(actions.someAction))

branch

import { sequence } from './myFluent'
import * as actions from './actions'

export const doThis = Sequence((s) =>
  s.branch(actions.someBranchAction).paths({
    pathA: (s) => s,
    pathB: (s) => s
  })
)

computed

import { Module, ComputedValue, Computed } from '@cerebral/fluent'
import * as sequences from './sequences'

type State = {
  items: string[]
  currentItemIndex: number
  currentItem: ComputedValue<string>
}

const state: State = {
  items: [],
  currentItemIndex: 0,
  currentItem: Computed((state) => state.items[state.currentItemIndex])
}

export const module = Module({
  state
})

Computed also exposes the root state:

Computed((state, root) => {})

connect

import * as React from 'react'
import { connect } from './myFluent'

type Props = {
  externalProp: string
}

export const App = connect<Props>()
  .with(({ state, signals, props }) => ({
    foo: state.foo,
    onClick: signals.thisHappened
  }))
  .to(function App({ foo, onClick, externalProp }) {
    return <div />
  })
  // Alternatively
  .toClass(
    (props) =>
      class App extends React.Component<typeof props> {
        render() {
          const { foo, onClick, externalProp } = this.props

          return <div />
        }
      }
  )

controller

import { Controller } from '@cerebral/fluent'
import { module as app } from './app'
import { State, Signals } from './fluent'

const controller = Controller<State, Signals>(app)

The State and Signals type are not required, but will enable auto suggestions on:

controller.state
controller.signals

dictionary

import { Dictionary } from '@cerebral/fluent'

export type State = {
  items: Dictionary<string>
}

const state: State = {
  foo: Dictionary({
    foo: 'bar',
    bar: 'baz'
  })
}

export const module = Module({
  state,
  signals
})

debounce

import { sequence } from './myFluent'
import * as actions from './actions'

export const doThis = sequence((s) => s.debounce(100))

equals

import { sequence } from './myFluent'

export const doThis = sequence((s) =>
  s.equals(({ state }) => state.user.role).paths({
    admin: (s) => s,
    user: (s) => s,
    otherwise: (s) => s
  })
)

factories

import {
  IContext,
  IBranchContext,
  ConnectFacory,
  SequenceFactory,
  SequenceWithPropsFactory
} from '@cerebral/fluent'
import { State, Signals, Providers } from './app'

export type Context<Props> = IContext<Props> & Providers

export type BranchContext<Paths, Props> = IBranchContext<Paths, Props> &
  Providers

export const connect = ConnectFactory<State, Signals>()

export const sequence = SequenceFactory<SignalContext>()

export const sequenceWithProps = SequenceWithPropsFactory<SignalContext>()

IContext

import { IContext } from '@cerebral/fluent'
import { HttpProvider } from '@cerebral/http'

export type State = {
  foo: string
}

export interface Providers {
  http: HttpProvider
  state: State
}

export type Context<Props> = IContext<Props> & Providers

IBranchContext

import { IBranchContext } from '@cerebral/fluent'
import { HttpProvider } from '@cerebral/http'

export type State = {
  foo: string
}

export interface Providers {
  http: HttpProvider
  state: State
}

export type BranchContext<Paths, Props> = IBranchContext<Paths, Props> &
  Providers

module

import { Module } from '@cerebral/fluent'
import * as signals from './sequences'

export type ModuleSignals = {
  [key in keyof typeof signals]: typeof signals[key]
}

export type ModuleState = {
  foo: string
}

const state: ModuleState = {
  foo: 'bar'
}

export const module = Module({
  state,
  signals
})

paths

import { sequence } from './myFluent'
import * as actions from './actions'

export const doThis = sequence((s) =>
  s.branch(actions.doThis).paths({
    success: (s) => s,
    error: (s) => s
  })
)

sequence

import { sequence } from  './fluent'

// Sequence without expected input and output props
export const doThis = sequence(s => s)

// Sequence with expected output props
export const composeThis = sequence<{ foo: string, bar: string }>(s

sequenceWithProps

import { sequenceWithProps } from  './fluent'

// Sequence with expected input props
export const doThis = sequenceWithProps<{ foo: string }>(s => s)

// Sequence with expected input and output props
export const composeThis = sequence<{ foo: string }, { foo: string, bar: string }>(s

wait

import { Sequence } from '@cerebral/fluent'

export const doThis = Sequence((s) => s.wait(1000))

when

import { Sequence } from '@cerebral/fluent'

export const doThis = Sequence((s) =>
  s.when(({ state }) => state.isAwesome).paths({
    true: (s) => s,
    false: (s) => s
  })
)

ComputedValue

import { ComputedValue } from '@cerebral/fluent'

type State = {
  someComputedString: ComputedValue<string>
}

Dictionary

import { Dictionary } from '@cerebral/fluent'

type Item = {
  title: string
}

export type State = {
  items: Dictionary<Item>
}

Readme

Keywords

none

Package Sidebar

Install

npm i @cerebral/fluent

Weekly Downloads

9

Version

1.0.3

License

MIT

Unpacked Size

267 kB

Total Files

68

Last publish

Collaborators

  • fweinb
  • cerebral.js
  • christianalfoni
  • guria
  • gbucher
  • henri-hulski