Changeset - 49f80544a3fb
[Not reviewed]
default
0 1 0
Drew Perttula - 9 years ago 2016-06-05 09:20:02
drewp@bigasterisk.com
untested unsubscribe handle support
Ignore-this: dab69fabac0055146be720ac474b615f
1 file changed with 9 insertions and 2 deletions:
0 comments (0 inline, 0 general)
light9/web/graph.coffee
Show inline comments
 
log = console.log
 

	
 
# Patch is {addQuads: <quads>, delQuads: <quads>}
 
# <quads> is [{subject: s, ...}, ...]
 

	
 
patchSizeSummary = (patch) ->
 
  '-' + patch.delQuads.length + ' +' + patch.addQuads.length
 

	
 
# partial port of autodepgraphapi.py
 
class GraphWatchers
 
  constructor: ->
 
    @handlersSp = {} # {s: {p: [handlers]}}
 
  subscribe: (s, p, o, onChange) -> # return subscription handle
 
    if o? then throw Error('not implemented')
 
    if not @handlersSp[s]
 
      @handlersSp[s] = {}
 
    if not @handlersSp[s][p]
 
      @handlersSp[s][p] = []
 
    @handlersSp[s][p].push(onChange)
 
    handle = {s: s, p: p, func: onChange}
 
    return handle
 
    
 
  unsubscribe: (subscription) ->
 
    throw Error('not implemented')
 
    spList = @handlersSp[subscription.s][subscription.p]
 
    i = spList.indexOf(subscription.func)
 
    if i == -1
 
      throw new Error('subscription not found')
 
    spList.splice(i, 1)
 

	
 
  matchingHandlers: (quad) ->
 
    matches = []
 
    for subjDict in [@handlersSp[quad.subject] || {}, @handlersSp[null] || {}]
 
      for subjPredMatches in [subjDict[quad.predicate] || [], subjDict[null] || []]
 
        matches = matches.concat(subjPredMatches)
 
    return matches
 
    
 
  graphChanged: (patch) ->
 
    for quad in patch.delQuads
 
      for cb in @matchingHandlers(quad)
 
        # currently calls multiple times, which is ok, but we might
 
        # group things into fewer patches
 
        cb({delQuads: [quad], addQuads: []})
 
    for quad in patch.addQuads
 
      for cb in @matchingHandlers(quad)
 
        cb({delQuads: [], addQuads: [quad]})
 

	
 

	
 
toJsonPatch = (jsPatch, cb) ->
 
  out = {patch: {adds: '', deletes: ''}}
 

	
 
  writeDels = (cb) ->
 
    writer = N3.Writer({ format: 'N-Quads' })
 
@@ -246,52 +252,53 @@ class window.SyncedGraph
 
    for quad in patch.delQuads
 
      @graph.removeTriple(quad)
 
    for quad in patch.addQuads
 
      @graph.addTriple(quad)
 
    log('applied patch locally', patchSizeSummary(patch))
 
    @_watchers.graphChanged(patch)
 

	
 
  getObjectPatch: (s, p, newObject, g) ->
 
    # send a patch which removes existing values for (s,p,*,c) and
 
    # adds (s,p,newObject,c). Values in other graphs are not affected.
 
    existing = @graph.findByIRI(s, p, null, g)
 
    return {
 
      delQuads: existing,
 
      addQuads: [{subject: s, predicate: p, object: newObject, graph: g}]
 
    }
 

	
 
  patchObject: (s, p, newObject, g) ->
 
    @applyAndSendPatch(@getObjectPatch(s, p, newObject, g))
 
  
 

	
 
  subscribe: (s, p, o, onChange) -> # return subscription handle
 
    # onChange is called with a patch that's limited to the quads
 
    # that match your request.
 
    # We call you immediately on existing triples.
 
    @_watchers.subscribe(s, p, o, onChange)
 
    handle = @_watchers.subscribe(s, p, o, onChange)
 
    immediatePatch = {delQuads: [], addQuads: @graph.findByIRI(s, p, o)}
 
    if immediatePatch.addQuads.length
 
      onChange(immediatePatch)
 
    return handle
 

	
 
  unsubscribe: (subscription) ->
 
    @_watchers.unsubscribe(subscription)
 

	
 
  _singleValue: (s, p) ->
 
    quads = @graph.findByIRI(s, p)
 
    switch quads.length
 
      when 0
 
        throw new Error("no value for "+s+" "+p)
 
      when 1
 
        obj = quads[0].object
 
        return N3.Util.getLiteralValue(obj)
 
      else
 
        throw new Error("too many values: " + JSON.stringify(quads))
 

	
 
  floatValue: (s, p) ->
 
    parseFloat(@_singleValue(s, p))
 
    
 
  stringValue: (s, p) ->
 
    @_singleValue(s, p)
 
    
 
  uriValue: (s, p) ->
 

	
 
  objects: (s, p) ->
0 comments (0 inline, 0 general)