reducts

0.0.1 • Public • Published

Reduct

Redux enhancer for composable process modeling.

Status

The concept is maturing, therefore I only document our ideal API which may not reflect the current implementation—or lack thereof.

Motivation

Modelling a long running business process with Redux is too difficult. It is easy to reason about state changes in Redux because they are synchronous, however asynchronous changes are left unsolved.

Conventional wisdom suggests extending the store with thunks. In this solution we dispatch function closures that may themselves dispatch more closures, possibly without end. These are uncoordinated state transitions.

Without coordinated state transitions it is hard to maintain the promise of predictabiliy in Redux. To restore predictablity we might introduce more middleware to ochestrate specific transitions. But, as the size and scope of our middleware increases it hides more knowledge of the underlying process in a layer of indirection.

These solutions have low interoperability, they are not easiliy composed, and they require we adopt our own flavor of Redux.

Reduct provides tools for modelling state tranistions. With inspiration from business process modeling Reduct seeks to make reasoning about dependent asynchronous events as predictable as Redux makes synhcronous events.

Example

Using Reduct should produce an inteligent self documenting implementation.

duct(
  'When a request fails',
  duct.matches({ type: 'REQUEST_FAILED' }).distinct().foward('match'),
  'Display an error',
  duct.dispatches({ type: 'ALERT', payload: duct.receive('match') }).foward('alert'),
  'Stall any further requests until',
  duct.captures({ type: /REQUEST_/ }),
  'Until the user dismisses the alert',
  duct.matches({ type: 'DISMISS', id: duct.receive('alert.id') }),
  'Then dispatch pending requests',
  duct.releases()
)

This will produce stateful middleware to use with Redux.

Ideally we imagine this to be a fully serializable instruction set.

someDuct.toJSON() === {
  type: 'DUCT',
  duct: [
    'When matching request failures',
    { type: 'DUCT_MATCH',
      match: {
        type: 'REQUEST_FAILED'
      },
      distinct: true,
      forward: 'match'
    },
    'Display an error',
    { type: 'DUCT_DISPATCH',
      action: {
        type: 'ALERT',
        payload: {
          type: 'DUCT_RECEIVE',
          receive: 'match'
        }
      },
      foward: 'alert',
    },
    'Stall any further requests until',
    { type: 'DUCT_CAPTURE',
      action: {
        type: {
          type: 'DUCT_REGEX',
          regex: 'REQUEST_'
        }
      }
    },
    'Until the user dismisses the alert',
    { type: 'DUCT_MATCH',
      action: {
        type: 'DISMISS',
        id: {
          type: 'DUCT_RECEIVE',
          receive: 'alert.id'
        }
      }
    },
    'Then dispatch pending requests',
    { type: 'DUCT_RELEASE'
    }
  ]
}

Having such a set would allow for user specific behavior to be delivered from the server.

Package Sidebar

Install

npm i reducts

Weekly Downloads

7

Version

0.0.1

License

MIT

Last publish

Collaborators

  • evanrs