Commands and handlers that can be used anywhere Javascript runs. This module is meant to be used with effects-as-data.
When using in Node: require('effects-as-data')
When using in the browser (or in an old version of node): require('effects-as-data/es5')
- call
- echo
- either
- guid
- httpGet
- httpPost
- httpPut
- httpDelete
- jsonParse
- logInfo
- logError
- now
- randomNumber
- retry
- getState
- setState
- setImmediate
Creates a call
cmd. yield
a call
cmd to call another effects-as-data function. call
is used to compose effects-as-data functions in a testible manner.
Parameters
fn
Function an effects-as-data generator function.payload
any? the payload for the effects-as-data function.options
Object? options forcall
(optional, default{}
)
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should call an effects-as-data function', testExample(() => {
return args('123')
.yieldCmd(cmds.call(getUser, '123'))
.returns({ id: '123', username: 'foo' })
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * getUser (id) {
return yield cmds.httpGet(`https://example.com/api/v1/users/${id}`)
}
function * example (id) {
return yield cmds.call(getUser, id)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, '123').then(user => {
user.id === '123' // true
user.username === 'foo' // true, if a user with an id of '123' has the `username` 'foo'.
})
Returns Object an cmd of type call
.
Creates an echo
cmd. yield
an echo
cmd for the handler to return payload
. This is used as a placeholder when multiple are being yield
-ed and some of the cmds need to be yield
-ed conditionally.
Parameters
payload
any the value to be returns from the handler.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return its argument', testExample(() => {
const value = 'foo'
return args()
.yieldCmd(cmds.echo(value))
.returns(value)
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (value) {
return yield cmds.echo(value)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, 'foo').then(result => {
result === 'foo' // true
})
Returns Object an cmd of type echo
.
Creates an either
cmd. yield
an either
cmd to return the result of the cmd OR the default value if the result is falsy.
Parameters
command
Object an effects-as-data command.defaultValue
any? the fallback value if the command returns a falsy value.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('successful call', testExample(() => {
const httpGetCmd = cmds.httpGet(`https://swapi.co/api/people/${25}`)
return args(25)
.yieldCmd(cmds.either(httpGetCmd, { name: 'default' }))
.returns({ name: 'Foo Bar'})
}))
it('default value', testExample(() => {
const httpGetCmd = cmds.httpGet(`https://swapi.co/api/people/${25}`)
return args(25)
.yieldCmd(cmds.either(httpGetCmd, { name: 'default' }))
.returns({ name: 'default' })
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (id) {
const httpGet = cmds.httpGet(`https://swapi.co/api/people/${id}`)
return yield cmds.either(httpGet, { name: 'default' })
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, 1).then(result => {
result.name === "Luke Skywalker" // true
})
// 10000 will cause a 404 from the API
call({}, handlers, example, 10000).then(result => {
result.name === "default" // true
})
Returns Object an cmd of type either
.
Creates a guid
cmd. yield
a guid
cmd to get a shiny new guid.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return a guid', testExample(() => {
return args()
.yieldCmd(cmds.guid())
.returns('83feb66e-cf36-40a3-ad23-a150f0b7ed4d')
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
return yield cmds.guid()
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(result => {
result === '15270902-2798-4c34-aaa8-9a55726b58af' // true, if the guid handler returned '15270902-2798-4c34-aaa8-9a55726b58af'
})
Returns Object an cmd of type guid
.
Creates a httpGet
cmd. yield
an httpGet
cmd to do an http GET request.
Parameters
url
string the url to GET.headers
Object? request headers. (optional, default{}
)options
Object? options forfetch
. (optional, default{}
)
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return a result from GET', testExample(() => {
return args('http://www.example.com')
.yieldCmd(cmds.httpGet('http://www.example.com'))
.returns('html body')
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (url) {
return yield cmds.httpGet(url)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
const url = 'https://www.example.com/api/v1/something'
call({}, handlers, example, url).then(result => {
result // HTML body of example.com
})
Returns Object an cmd of type httpGet
.
Creates a httpPost
cmd. yield
an httpPost
cmd to do an http POST request.
Parameters
url
string the url to POST.payload
Object? the payload to POST.headers
Object? request headers. (optional, default{}
)options
Object? options forfetch
. (optional, default{}
)
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should POST payload to url', testExample(() => {
const url = 'http://www.example.com/api/v1/user'
const payload = { foo: 'bar' }
return args(payload)
.yieldCmd(cmds.httpPost(url, payload))
.returns() // assuming the api 204's
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (payload) {
return yield cmds.httpPost('http://www.example.com/api/v1/user', payload)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, { foo: 'bar' }).then(result => {
result // Response payload
})
Returns Object an cmd of type httpPost
.
Creates a httpPut
cmd. yield
an httpPut
cmd to do an http PUT request.
Parameters
url
string the url to PUT.payload
Object? the payload to PUT.headers
Object? request headers. (optional, default{}
)options
Object? options forfetch
. (optional, default{}
)
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should PUT payload to url', testExample(() => {
const url = 'http://www.example.com/api/v1/user/1'
const payload = { name: 'John Doe' }
return args(payload)
.yieldCmd(cmds.httpPut(url, payload))
.returns() // assuming the api 204's
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (payload) {
return yield cmds.httpPut('http://www.example.com/api/v1/user', payload)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, { name: 'John Doe' }).then(result => {
result // Response payload
})
Returns Object an cmd of type httpPut
.
Creates a httpDelete
cmd. yield
an httpDelete
cmd to do an http DELETE request.
Parameters
url
string the url to DELETE.headers
Object? request headers. (optional, default{}
)options
Object? options forfetch
. (optional, default{}
)
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return a result from DELETE', testExample(() => {
return args(32)
.yieldCmd(cmds.httpDelete('http://www.example.com/api/v1/user/32'))
.returns() // assuming the api 204's
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (id) {
return yield cmds.httpDelete(`http://www.example.com/api/v1/user/${id}`)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, '123').then(result => {
result // Response payload
})
Returns Object an cmd of type httpDelete
.
Creates a jsonParse
cmd. yield
a jsonParse
cmd to parse a JSON string. Why not just use JSON.parse()
inline? Although a successful parsing operation is deterministic, a failed parsing operation is not.
Parameters
payload
string the JSON string to parse.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should parse a JSON string', testExample(() => {
const jsonString = '{"foo": "bar"}'
return args(jsonString)
.yieldCmd(cmds.jsonParse(jsonString))
.returns({ foo: 'bar' })
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (json) {
return yield cmds.jsonParse(json)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, '{"foo": "bar"}').then(result => {
result.foo === 'bar' // true
})
Returns Object an cmd of type jsonParse
.
Creates a logInfo
cmd. yield
a logInfo
cmd to log to the console using console.info
.
Parameters
payload
string? the payload to log.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should log a message', testExample(() => {
return args('foo')
.yieldCmd(cmds.logInfo('foo'))
.returns()
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (message) {
return yield cmds.logInfo(message)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, 'bar').then(result => {
// "bar" should have been `console.info`ed
})
Returns Object an cmd of type logInfo
.
Creates a logError
cmd. yield
a logError
cmd to log to the console using console.error
.
Parameters
payload
string? the payload to log.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should log a message', testExample(() => {
return args('oops!')
.yieldCmd(cmds.logError('oops!'))
.returns()
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (message) {
return yield cmds.logError(message)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example, 'oops!').then(result => {
// "oops!" should have been `console.error`ed
})
Returns Object an cmd of type logError
.
Create an now
cmd. yield
a now
cmd to get the current timestamp from Date.now()
.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return the current timestamp', testExample(() => {
return args()
.yieldCmd(cmds.now())
.returns(123456)
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
return yield cmds.now()
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(timestamp => {
timestamp === 1490030160103 // true, if the now handler (which wraps Date.now()) returned 1490030160103
})
Returns Object an cmd of type now
.
Create an randomNumber
cmd. yield
a randomNumber
to get a random number using Math.random()
.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return the current timestamp', testExample(() => {
return args()
.yieldCmd(cmds.randomNumber())
.returns(0.123)
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
return yield cmds.randomNumber()
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(n => {
n === 0.345 // true, if the randomNumber handler (which wraps Math.random()) returned 0.345
})
Returns Object an cmd of type randomNumber
.
Create an retry
cmd. yield
a retry
to try a command at the given intervals finally falling back to a default value if all tries fail.
Parameters
command
Object an effects-as-data command.intervals
Array an array of times in milliseconds to retry the command on if the last try faileddefaultValue
any? the fallback value if the command returns a falsy value after all retries.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should retry 3 times then return the default value', testExample(() => {
const intervals = [100, 500, 1000]
const defaultValue = []
const httpGetCmd = cmds.httpGet('https://swapi.co/api/people')
return args()
.yieldCmd(cmds.retry(httpGetCmd, intervals, defaultValue))
.returns(defaultValue)
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
const httpGetCmd = cmds.httpGet('https://swapi.co/api/people')
return yield cmds.retry(httpGetCmd, [100, 500, 1000], [])
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(results => {
results // a list of people from the swapi.co api. If all retried failed, then []
})
Returns Object an cmd of type retry
.
Creates a getState
cmd. yield
a getState
to get application state.
Parameters
path
string a dot notation path on the state to the property.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should return user from application state', testExample(() => {
return args()
.yieldCmd(cmds.getState('user.name'))
.returns('John Doe')
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
return yield cmds.getState('user.name')
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(result => {
result === 'Jane Doe' // if user.name on the state equals 'Jane Doe'
})
Returns Object an cmd of type getState
.
Creates a setState
cmd. yield
a setState
to set application state.
Parameters
path
string a dot notation path on the state to the property.payload
any? A value that will be set on the state.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should set a user on the application state', testExample(() => {
const user = { user: '123' }
return args()
.yieldCmd(cmds.setState('user', user))
.returns()
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example (user) {
return yield cmds.setState('user', user)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
const user = { id: '123', username: 'foo' }
call({}, handlers, example, user).then(result => {
// the state should now have a user property on it equalling `user`
})
Returns Object an cmd of type setState
.
Create an setImmediate
cmd. yield
a setImmediate
to send the command to the end of the call queue.
Parameters
command
Object an effects-as-data command.
Examples
// Test It
const { testFn, args } = require('effects-as-data/test')
const { cmds } = require('effects-as-data-universal')
const testExample = testFn(example)
describe('example()', () => {
it('should use setImmediate', testExample(() => {
const echoCmd = cmds.echo('hello world')
return args()
.yieldCmd(cmds.setImmediate(echoCmd))
.returns()
}))
})
// Write It
const { cmds } = require('effects-as-data-universal')
function * example () {
const echoCmd = cmds.echo('hello world')
return yield cmds.setImmediate(echoCmd)
}
// Run It
const { handlers } = require('effects-as-data-universal')
const { call } = require('effects-as-data')
call({}, handlers, example).then(result => {
result === undefined // true. the echo command will be handled in the next tick
})
Returns Object an cmd of type setImmediate
.