Mercurial > code > home > repos > light9
view light9/web/rdfdbclient.coffee @ 1635:0eb5f70bdde2
unawesome some overlapping css
Ignore-this: 25b7173f67f9031387adc37300778f49
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Sat, 10 Jun 2017 03:17:20 +0000 |
parents | d5a0c77dfc5b |
children | 77eaccba654e |
line wrap: on
line source
log = console.log # for mocha if require? `window = {}` `N3 = require('./lib/N3.js-pull61/N3.js')` module.exports = window toJsonPatch = (jsPatch, cb) -> out = {patch: {adds: '', deletes: ''}} writeDels = (cb) -> writer = N3.Writer({ format: 'N-Quads' }) writer.addTriples(jsPatch.delQuads) writer.end((err, result) -> out.patch.deletes = result cb()) writeAdds = (cb) -> writer = N3.Writer({ format: 'N-Quads' }) writer.addTriples(jsPatch.addQuads) writer.end((err, result) -> out.patch.adds = result cb()) async.parallel([writeDels, writeAdds], (err) -> cb(JSON.stringify(out)) ) parseJsonPatch = (jsonPatch, cb) -> # note response cb doesn't have an error arg. input = JSON.parse(jsonPatch) patch = {delQuads: [], addQuads: []} parseAdds = (cb) => parser = N3.Parser() parser.parse input.patch.adds, (error, quad, prefixes) => if (quad) patch.addQuads.push(quad) else cb() parseDels = (cb) => parser = N3.Parser() parser.parse input.patch.deletes, (error, quad, prefixes) => if (quad) patch.delQuads.push(quad) else cb() async.parallel([parseAdds, parseDels], ((err) => cb(patch))) class window.RdfDbClient # Send and receive patches from rdfdb constructor: (@patchSenderUrl, @clearGraph, @applyPatch, @setStatus) -> @_patchesToSend = [] @_lastPingMs = -1 @_patchesReceived = 0 @_patchesSent = 0 @_reconnectionTimeout = null @_newConnection() _updateStatus: -> ws = (if not @ws? then 'no' else switch @ws.readyState when @ws.CONNECTING then 'connecting' when @ws.OPEN then 'open' when @ws.CLOSING then 'closing' when @ws.CLOSED then 'close' ) ping = if @_lastPingMs > 0 then @_lastPingMs else '...' @setStatus("#{ws}; #{@_patchesReceived} recv; #{@_patchesSent} sent; #{@_patchesToSend.length} pending; #{ping}ms") sendPatch: (patch) -> console.log('queue patch to server ', patchSizeSummary(patch)) @_patchesToSend.push(patch) @_updateStatus() @_continueSending() _newConnection: -> wsOrWss = window.location.protocol.replace('http', 'ws') fullUrl = wsOrWss + '//' + window.location.host + @patchSenderUrl @ws.close() if @ws? @ws = new WebSocket(fullUrl) @ws.onopen = => log('connected to', fullUrl) @_updateStatus() @clearGraph() @_pingLoop() @ws.onerror = (e) => log('ws error ' + e) @ws.onclose() @ws.onclose = => log('ws close') @_updateStatus() clearTimeout(@_reconnectionTimeout) if @_reconnectionTimeout? @_reconnectionTimeout = setTimeout(@_newConnection.bind(@), 1000) @ws.onmessage = @_onMessage.bind(@) _pingLoop: () -> if @ws.readyState == @ws.OPEN @ws.send('PING') @_lastPingMs = -Date.now() clearTimeout(@_pingLoopTimeout) if @_pingLoopTimeout? @_pingLoopTimeout = setTimeout(@_pingLoop.bind(@), 10000) _onMessage: (evt) -> msg = evt.data if msg == 'PONG' @_lastPingMs = Date.now() + @_lastPingMs @_updateStatus() return parseJsonPatch(msg, @applyPatch.bind(@)) @_patchesReceived++ @_updateStatus() _continueSending: -> if @ws.readyState != @ws.OPEN setTimeout(@_continueSending.bind(@), 500) return # we could call this less often and coalesce patches together to optimize # the dragging cases. sendOne = (patch, cb) => toJsonPatch(patch, (json) => log('send patch to server, ' + json.length + ' bytes') @ws.send(json) @_patchesSent++ @_updateStatus() cb(null) ) async.eachSeries(@_patchesToSend, sendOne, () => @_patchesToSend = [] @_updateStatus() )