a few methods of redux middleware for holochain UI apps
Clone or download

README.md

hc-redux-middleware

To install: npm install --save @holochain/hc-redux-middleware

Usage

Configure the store to use the middleware

import { createStore, combineReducers, applyMiddleware } from 'redux'

import { connect } from '@holochain/hc-web-client'
import { holochainMiddleware } from '@holochain/hc-redux-middleware'

// this url should use the same port set up the holochain container
const url = 'ws:localhost:3000'
const hcWc = connect(url)

const middleware = [holochainMiddleware(hcWc)]

...

let store = createStore(reducer, applyMiddleware(...middleware))

Lets look an example action to see how the middleware works

{
  type: 'CALL_HOLOCHAIN_FUNC',
  payload: { ... }
  meta: { 
  	holochainAction: true, 
  	callString: 'happ/zome/capability/func' 
  }
}

The first thing to notice is the meta.holochainAction = True. This is how the middleware detects which actions it should use to make calls to holochain. The call string instructs the holochain web client as to what function it should call. This can follow the happ/zome/capability/func format or may also call a container function directly such as info/instances

The payload will be passed directly to the call to the holochain function and must have fields that match the holochain function signature.

Action creators

To abstract away from manually creating these actions this module also provides helpers for doing that. For a particular holochain function call it will create an action creator that you can call later with parameters

import { createHolochainAsyncAction } from '@holochain/hc-redux-middleware'

const someFuncActionCreator = createHolochainAsyncAction('someApp', 'someZome', 'someCapability', 'someFunc')

// later on when you want to create dispatch an action to call the function with some params
const action = someFuncActionCreator.create(params)
dispatch(action) // this returns a promise that resolves with the response or fails with the error

This will autocomplete the type field using the format someApp/someZome/someCapability/someFunc. You can also use the autogenerated holochainAction.success().type and holochainAction.failure().type

Response Actions

When a successful call to holochain is completed the middleware will dispatch an action containing the response. These actions have a type that is the same as the call but with _SUCCESS or _FAILURE appended.

{
  type: 'CALL_HOLOCHAIN_FUNC_SUCCESS',
  payload: { ... } // this contains the function call result
}

{
  type: 'someApp/someZome/someCapability/someFunc_FAILURE',
  payload: { ... } // this contains details of the error
}

These can then be handler by the reducer to update the state

Typescript support

We love typescript and so the action creators ship with typescript definitions and type support out of the box! The typed actions are based off the typesafe actions model. Holochain action creators can be made using generics to match the function parameters and return type of the zome function

import { createHolochainAsyncAction } from '@holochain/hc-redux-middleware'

export const someFuncActionCreator = createHolochainAsyncAction<ParamType, ResponseType>('someApp', 'someZome', 'someCapability', 'someFunc')

// The params must match the ParamType or this will error
const action = someFuncActionCreator.create(params)

This is even more useful in the reducer.

import { getType } from 'typesafe-actions'

export function reducer (state = initialState, action: AnyAction) {
  switch (action.type) {
    case getType(someFuncActionCreator.success):
      // The type checker now knows that action.payload has type
      // set in the definition using the generic
      // You literally cant go wrong!

    ...
  }

See [https://github.com/piotrwitek/typesafe-actions] for all the details of using typesafe actions