noflo-lift
Version:
Lift Packets for Processing in NoFlo
80 lines (56 loc) • 2.01 kB
text/coffeescript
noflo = require("noflo")
_ = require("underscore")
_s = require("underscore.string")
{ CacheStorage } = require("nohoarder")
class Assembler extends noflo.Component
description: _s.clean "given a data structure, a pattern, and a
sub-structure, replace a subset of the data structure as specified by
the pattern with the sub-structure"
constructor: ->
@cache = new CacheStorage
@patterns = []
@inPorts =
in: new noflo.Port
pattern: new noflo.Port
replacement: new noflo.Port
@outPorts =
out: new noflo.Port
@inPorts.pattern.on "connect", =>
@patterns = []
@inPorts.pattern.on "data", (pattern) =>
@patterns.push new RegExp pattern
@inPorts.replacement.on "connect", =>
@cache.connect()
@inPorts.replacement.on "begingroup", (group) =>
@cache.beginGroup(group)
@inPorts.replacement.on "data", (data) =>
@cache.send(data)
@inPorts.replacement.on "endgroup", (group) =>
@cache.endGroup(group)
@inPorts.replacement.on "disconnect", =>
@cache.disconnect()
@inPorts.in.on "connect", =>
# Whether the group pattern has matched before, regardless whether
# it's matching now or not
@hasMatched = false
@groups = []
@inPorts.in.on "begingroup", (group) =>
@outPorts.out.beginGroup(group) unless @matchPattern()
@groups.push(group)
if @matchPattern() and not @hasMatched
@hasMatched = true
@cache.flushCache(@outPorts.out)
@cache.reset()
@inPorts.in.on "data", (data) =>
@outPorts.out.send(data) unless @matchPattern()
@inPorts.in.on "endgroup", (group) =>
@groups.pop()
@outPorts.out.endGroup() unless @matchPattern()
@inPorts.in.on "disconnect", =>
@outPorts.out.disconnect()
matchPattern: ->
groups = @groups.slice(0, @patterns.length)
for p, i in @patterns
return false unless groups[i]?.match(p)?
return true
exports.getComponent = -> new Assembler