sox : { k: v } -> Socket
Instantiates a socket.io client configured by the following options:
Name | Type | Default | Description |
---|---|---|---|
query |
Function |
noop |
function to retrieve extra query params |
uri |
String |
'' |
the socket.io service URI |
Note: The query
function will be run before each socket connection, including reconnects, to update the handshake querystring. It should return a plain object of query params.
Returns a socket.io client instance with a few new helpful methods added.
const query = () =>
({ token: getAuthToken() })
const uri = window.env.SERVICE_URI
const socket = require('@articulate/sox')({ query, uri })
The instance will also have a socket.session
property, a unique id that persists through socket reconnects. Useful for managing resource locks between different browser sessions or tabs.
socket.session //=> ex: 'cjb5fg7bw00003h67ghy84kzx'
Method | Signature |
---|---|
debounce |
Number -> String -> a -> IO Async Action |
send |
String -> a -> Async Action |
throttle |
Number -> String -> a -> IO Async Action |
debounce :: Number -> String -> a -> IO Async Action
Similar to send
, but first accepts a wait
in ms. Debounces the sending of actions over the socket, and only resolves once after the debounce completes. Useful for debouncing user input.
Returns an IO
that resolves with an Async
, so you will need both redux-io
and redux-future
.
Note: If you also need to redraw after each keystroke (very common use case), then you should juxt
to create a pair of actions: one synchronous to render the new state, and one debounced to send the action over the socket. If you do, don't forget to use redux-functor
, since you are dispatching an array of actions.
const { action } = require('@articulate/ducks')
const juxt = require('ramda/src/juxt')
const socket = require('../lib/socket')
exports.putTitle = juxt([
action('PUT_TITLE'),
socket.debounce(500, 'PUT_TITLE')
])
send :: String -> a -> Async Action
An action-creator that accepts a type
and payload
, and then sends an FSA-compliant action over the socket. Resolves with a response action, and inflates the payload of error-type actions into a real Error
.
Returns an Async
, so you'll need appropriate middleware, such as redux-future
.
const always = require('ramda/src/always')
const socket = require('../lib/sox')
exports.getSelf = always(socket.send('GET_SELF', null))
exports.getUser = socket.send('GET_USER')
throttle :: Number -> String -> a -> IO Async Action
Similar to send
, but first accepts a wait
in ms. Throttles the sending of actions over the socket, and only resolves at most once every wait
ms. Useful for throttling user input for real-time collaboration.
Returns an IO
that resolves with an Async
, so you will need both redux-io
and redux-future
.
Note: If you also need to redraw after each keystroke (very common use case), then you should juxt
to create a pair of actions: one synchronous to render the new state, and one throttled to send the action over the socket. If you do, don't forget to use redux-functor
, since you are dispatching an array of actions.
const { action } = require('@articulate/ducks')
const juxt = require('ramda/src/juxt')
const socket = require('../lib/socket')
exports.putTitle = juxt([
action('PUT_TITLE'),
socket.throttle(500, 'PUT_TITLE')
])