Skip to content

Instantly share code, notes, and snippets.

@evilsoft
Created May 15, 2018 02:14
Show Gist options
  • Save evilsoft/38c0bc8ba12508923276cbaf4f19cd31 to your computer and use it in GitHub Desktop.
Save evilsoft/38c0bc8ba12508923276cbaf4f19cd31 to your computer and use it in GitHub Desktop.
const Async = require('crocks/Async')
const assign = require('crocks/helpers/assign')
const compose = require('crocks/helpers/compose')
const isNil = require('crocks/predicates/isNil')
const maybeToAsync = require('crocks/Async/maybeToAsync')
const not = require('crocks/logic/not')
const objOf = require('crocks/helpers/objOf')
const prop = require('crocks/Maybe/prop')
const safeAfter = require('crocks/Maybe/safeAfter')
const tap = require('crocks/helpers/tap')
const { fromPromise } = Async
// mergeData :: (String, Object) -> a -> Object
const mergeData = (label, data) =>
compose(assign(data), objOf(label))
// Using safeAfter will work on the value of the
// "target" or Codomain of a function. so here
// we check to see if the result is undefined,
// null or NaN. If not return a Just, otherwise
// Nothing.
// getElemSafe :: String -> Maybe Node
const getElemSafe = safeAfter(
not(isNil),
document.getElementById
)
// fromPromise wraps a Promise returning function and will
// convert it into an Async returning function. This allows
// them to be lazily composed with other Asyncs
// getUserMedia :: MediaConstraints -> Async Error Stream
const getUserMedia =
fromPromise(navigator.getUserMedia, navigator)
// connectStream :: Object -> Async Error Object
const connectStream = data =>
getUserMedia(data.constraints)
.map(mergeData('stream', data))
// addStreamToVideo :: Object -> ()
const addStreamToVideo = ({ video, stream }) => {
video.srcObject = stream
}
// addVideo :: Object -> Maybe Object
const addVideo = data =>
prop('elemId', data)
.chain(getElemSafe)
.map(mergeData('video', data))
const flow = data =>
// Start with an Async, loaded with the head of your
// computation.
Async.of(data)
// Any other Sum type (Maybe, Result, Either) can be
// transformed into an Async and chained in. Functions
// like tryCatch (which returns a Result if no errors are thrown)
// come in very handy
.chain(maybeToAsync('video elem not found', addVideo))
// Any function that captures disjunction or an async call
// should be chained in to apply those effects.
.chain(connectStream)
// for working with references (objects, etc) you can tap
// and this will signal that something side-effecty is going on
// will throw away any return from a tapped function and return
// the parameters, which were just mutated (in a side-effect)
.map(tap(addStreamToVideo))
flow({
elemId: 'local_video',
constraints: { video: true }
}).fork(handleErr, handleSucc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment