noflo
Version:
Flow-Based Programming environment for JavaScript
177 lines (168 loc) • 4.27 kB
text/coffeescript
# NoFlo - Flow-Based Programming for JavaScript
# (c) 2014-2017 Flowhub UG
# NoFlo may be freely distributed under the MIT license
#
# High-level wrappers for FBP substreams processing.
#
# Wraps an object to be used in Substreams
class IP
constructor: () ->
sendTo: (port) ->
port.send
getValue: ->
return
toObject: ->
return
exports.IP = IP
# Substream contains groups and data packets as a tree structure
class Substream
constructor: () ->
= []
push: (value) ->
.push value
sendTo: (port) ->
port.beginGroup
for ip in
if ip instanceof Substream or ip instanceof IP
ip.sendTo port
else
port.send ip
port.endGroup
getKey: ->
return
getValue: ->
switch .length
when 0
return null
when 1
if typeof [0].getValue is 'function'
if [0] instanceof Substream
obj = {}
obj[[0].key] = [0].getValue()
return obj
else
return [0].getValue()
else
return [0]
else
res = []
hasKeys = false
for ip in
val = if typeof ip.getValue is 'function' then ip.getValue() else ip
if ip instanceof Substream
obj = {}
obj[ip.key] = ip.getValue()
res.push obj
else
res.push val
return res
toObject: ->
obj = {}
obj[] =
return obj
exports.Substream = Substream
# StreamSender sends FBP substreams atomically.
# Supports buffering for preordered output.
class StreamSender
constructor: (, = false) ->
= []
= false
resetCurrent: ->
= 0
= null
= []
beginGroup: (group) ->
++
stream = new Substream group
.push stream
= stream
return @
endGroup: ->
-- if > 0
value = .pop()
if is 0
.push value
else
parent = [.length - 1]
parent.push value
= parent
return @
send: (data) ->
if is 0
.push new IP data
else
.push new IP data
return @
done: ->
if
= true
else
return @
disconnect: ->
.push null # disconnect packet
return @
flush: ->
# Flush the buffers
res = false
if .length > 0
for ip in
if ip is null
.disconnect() if .isConnected()
else
ip.sendTo
res = true
= []
return res
isAttached: ->
return .isAttached()
exports.StreamSender = StreamSender
# StreamReceiver wraps an inport and reads entire
# substreams as single objects.
class StreamReceiver
constructor: (, = false, = null) ->
= []
.process = (event, payload, index) =>
switch event
when 'connect'
'connect', index if typeof is 'function'
when 'begingroup'
++
stream = new Substream payload
if is 1
= stream
= null
else
=
= stream
when 'endgroup'
-- if > 0
if is 0
if
.push
'readable', index
else
'data', , index if typeof is 'function'
else
.push
=
when 'data'
if is 0
.push new IP payload
else
.push new IP payload
when 'disconnect'
'disconnect', index if typeof is 'function'
resetCurrent: ->
= 0
= null
= null
= null
read: ->
return undefined if .length is 0
return .shift()
exports.StreamReceiver = StreamReceiver