Skip to content

Latest commit

 

History

History
112 lines (74 loc) · 4.51 KB

client.md

File metadata and controls

112 lines (74 loc) · 4.51 KB

Client API

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'

New methods

Method Signature
debounce Number -> String -> a -> IO Async Action
send String -> a -> Async Action
throttle Number -> String -> a -> IO Async Action

debounce

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.

See also send, throttle.

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

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.

See also debounce, throttle.

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

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.

See also debounce, send.

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')
])