@cypress/core-desktop-gui
Version:
Desktop GUI for managing Cypress projects.
114 lines (92 loc) • 3.05 kB
text/coffeescript
@App.module "Utilities", (Utilities, App, Backbone, Marionette, $, _) ->
msgs = {}
addMsg = (id, event, fn) ->
msgs[id] = {
event: event
fn: fn
}
removeMsgsByEvent = (event) ->
msgs = _(msgs).omit (msg) ->
msg.event is event
removeMsgById = (id) ->
msgs = _(msgs).omit(""+id)
createIpc = ->
console.warn("Missing 'ipc'. Polyfilling in development mode.")
responses = []
## return a mock ipc interface useful in development + testing
return {
on: ->
off: ->
send: (resp, id, event) ->
## if we have a pending response then just
## invoke it asynchronously
if response = _.find(responses, {event: event})
responses = _.without(responses, response)
Promise.delay(1).then =>
@handle(event, response.err, response.data)
response.resolve()
handle: (event, err, data) ->
new Promise (resolve, reject) ->
## create our own handle function to callback the registered events
##
## grab the first msg by its event
msg = _.chain(msgs).where({event: event}).first().value()
if msg
msg.fn(err, data)
resolve()
else
responses.push({
event: event
err: err
data: data
resolve: resolve
})
}
ipc = window.ipc ?= createIpc()
ipc.on "response", (event, obj = {}) ->
{id, __error, data} = obj
## standard node callback implementation
if msg = msgs[id]
msg.fn(__error, data)
App.ipc = (args...) ->
return msgs if args.length is 0
## our ipc interface can either be a standard
## node callback or a promise interface
## we support both because oftentimes we want
## to our async request to be resolved with a
## singular value, and other times we want it
## to be called multiple times akin to a stream
## generate an id
id = Math.random()
## first arg is the event
event = args[0]
## get the last argument
lastArg = args.pop()
## enable the last arg to be a function
## which changes this interface from being
## a promise to just calling the callback
## function directly
if lastArg and _.isFunction(lastArg)
fn = ->
addMsg id, event, lastArg
else
## push it back onto the array
args.push(lastArg)
fn = ->
## return a promise interface and at the
## same time store this callback function
## by id in msgs
new Promise (resolve, reject) ->
addMsg id, event, (err, data) ->
## cleanup messages using promise interface
## automatically
removeMsgById(id)
if err
reject(err)
else
resolve(data)
## pass in request, id, and remaining args
ipc.send.apply ipc, ["request", id].concat(args)
return fn()
App.ipc.off = (event) ->
removeMsgsByEvent(event)