Permalink
Browse files

checkpoint while this is working. i need to move things around again.

  • Loading branch information...
1 parent 8d9329e commit da279ff4ded5d0d95d1299b10ea3b38207c47726 @robey committed Apr 11, 2013
View
@@ -1,12 +1,17 @@
+event_sequence = require("./fauna/event_sequence")
+exports.EventSequence = event_sequence.EventSequence
+
+fauna_client = require("./fauna/fauna_client")
+exports.FaunaClient = fauna_client.FaunaClient
+
+rest = require("./fauna/rest")
+exports.Rest = rest.Rest
+exports.RestError = rest.RestError
schema = require("./fauna/schema")
exports.Class = schema.Class
exports.Schema = schema.Schema
-fauna_client = require("./fauna/fauna_client")
-exports.EventSequence = fauna_client.EventSequence
-exports.FaunaClient = fauna_client.FaunaClient
-
# useful for debugging
util = require 'util'
exports.dump = (x) -> util.inspect(x, false, null, true)
@@ -18,17 +23,6 @@ exports.dump = (x) -> util.inspect(x, false, null, true)
Q = require 'q'
util = require 'util'
-rest = require("./rest")
-Rest = rest.Rest
-RestError = rest.RestError
-
-schema = require("./schema")
-Class = schema.Class
-Schema = schema.Schema
-Data = schema.Data
-Reference = schema.Reference
-EventSet = schema.EventSet
-
dump = (x) -> util.inspect(x, false, null, true)
@@ -284,13 +278,5 @@ class Fauna
@delete("instances/#{ref}")
-exports.Rest = Rest
-exports.RestError = RestError
exports.Fauna = Fauna
exports.FaunaError = FaunaError
-
-exports.Class = Class
-exports.Schema = Schema
-exports.Reference = Reference
-exports.Data = Data
-exports.EventSet = EventSet
@@ -0,0 +1,68 @@
+topoSort = (graph) ->
+ ###
+ given a graph of { id: [id] } where each key maps to a list of the keys
+ dependent on it, return a sorted array of ids in dependency order.
+ ###
+ rv = []
+ # make a copy of 'graph' so we don't destroy it. it's mutable in JS.
+ work = {}
+ for k, v of graph then work[k] = v
+ recursing = {}
+ visit = (id) ->
+ if recursing[id]? then throw new Error("Dependency graph has a cycle")
+ recursing[id] = true
+ for d in work[id] then if work[d]? then visit(d)
+ delete work[id]
+ delete recursing[id]
+ rv.push id
+ while Object.keys(work).length > 0
+ visit(Object.keys(work)[0])
+ rv
+
+
+class EventSequence
+ constructor: (@schema, data) ->
+ @events = []
+ if data?
+ @before = data.resource.before
+ if not @before? then @before = 0
+ @after = data.resource.after
+ @unpack(data)
+ else
+ @before = 0
+ @after = 0
+
+ # unpack a response of { resource:{}, references:{} }
+ unpack: (data) ->
+ # first, sort the attached 'references' by dependency.
+ dependencies = {}
+ for refid, struct of data.references
+ dependencies[refid] = []
+ for k, v of struct.references
+ dependencies[refid].push.apply(dependencies[refid], if v instanceof Array then v else [v])
+ # then, inflate each reference.
+ references = {}
+ for refid in topoSort(dependencies)
+ struct = data.references[refid]
+ newrefs = {}
+ for k, v of struct.references
+ v = if v instanceof Array then v.map((x) -> references[x]) else references[v]
+ newrefs[k] = v
+ struct.references = newrefs
+ references[refid] = @schema.inflate(struct)
+ # finally, fill in the references in the event set.
+ @events = data.resource.events
+ for event in @events
+ refid = event.resource
+ if refid? and references[refid]? then event.resource = references[refid]
+
+ # return only the objects with a "create" event and no corresponding "delete" event.
+ # objects are ordered newest to oldest.
+ toArray: ->
+ rv = []
+ for event in @events then if event.action == "create" then rv.push(event.resource)
+ for event in @events then if event.action == "delete"
+ rv = (x for x in rv when x._fauna.id != event.resource._fauna.id)
+ rv
+
+exports.EventSequence = EventSequence
@@ -1,80 +1,34 @@
Q = require 'q'
util = require 'util'
+event_sequence = require("./event_sequence")
rest = require("./rest")
schema = require("./schema")
+EventSequence = event_sequence.EventSequence
+Rest = rest.Rest
+Schema = schema.Schema
-topoSort = (graph) ->
- ###
- given a graph of { id: [id] } where each key refers to a list of the keys
- dependent on it, return a sorted array of ids in dependency order.
- ###
- rv = []
- # make a copy of 'graph' so we don't destroy it. it's mutable in JS.
- work = {}
- for k, v of graph then work[k] = v
- recursing = {}
- visit = (id) ->
- if recursing[id]? then throw new Error("Dependency graph has a cycle")
- recursing[id] = true
- for d in work[id] then if work[d]? then visit(d)
- delete work[id]
- delete recursing[id]
- rv.push id
- while Object.keys(work).length > 0
- visit(Object.keys(work)[0])
- rv
-
-
-class EventSequence
- constructor: (@schema, data) ->
- @events = []
- if data?
- @before = data.resource.before
- if not @before? then @before = 0
- @after = data.resource.after
- @unpack(data)
- else
- @before = 0
- @after = 0
-
- # unpack a response of { resource:{}, references:{} }
- unpack: (data) ->
- # first, sort the attached 'references' by dependency.
- dependencies = {}
- for refid, struct of data.references
- dependencies[refid] = []
- for k, v of struct.references
- dependencies[refid].push.apply(dependencies[refid], if v instanceof Array then v else [v])
- # then, inflate each reference.
- references = {}
- for refid in topoSort(dependencies)
- struct = data.references[refid]
- newrefs = {}
- for k, v of struct.references
- v = if v instanceof Array then v.map((x) -> references[x]) else references[v]
- newrefs[k] = v
- struct.references = newrefs
- references[refid] = @schema.inflate(struct, @client)
- # finally, fill in the references in the event set.
- @events = data.resource.events
- for event in @events
- refid = event.resource
- if refid? and references[refid]? then event.resource = references[refid]
-
- # return only the objects with a "create" event and no corresponding "delete" event.
- # objects are ordered oldest to newest.
- toArray: ->
- rv = []
- for event in @events then if event.action == "create" then rv.unshift(event.resource)
- for event in @events then if event.action == "delete"
- rv = (x for x in rv when x._fauna.id != event.resource._fauna.id)
- rv
-
-exports.EventSequence = EventSequence
+dump = (x) -> util.inspect(x, false, null, true)
+# ----- helper decorators
+
+requireOwner = (f) ->
+ ->
+ if not (@ownerAuthentication.username? and @ownerAuthentication.password?)
+ return Q.reject(new Error("Requires authentication as owner"))
+ f.bind(@)()
+
+asEventArray = (f) ->
+ ->
+ f.bind(@)().then (data) =>
+ (new EventSequence(@schema, data)).toArray()
+
+asObject = (f) ->
+ ->
+ f.bind(@)().then (data) => @schema.inflate(data)
+
class FaunaClient
constructor: ->
# three kinds of authentication: owner, publisher, client, user
@@ -84,6 +38,9 @@ class FaunaClient
@userToken = null
# all js/json object transformations use the schema:
@schema = new Schema(@)
+ # hook up nested namespaces
+ @publisherKeys = new _PublisherKeys
+ for k, v of @publisherKeys then @publisherKeys[k] = v.bind(@)
debug: (message) -> Rest.debug(message)
@@ -101,30 +58,24 @@ class FaunaClient
urlFor: (path) ->
"#{@protocol}://#{encodeURIComponent(@username)}:#{escape(@password)}@#{@hostname}/#{@apiVersion}/#{path}"
- op: (method, path, data) ->
- options.url = @urlFor(path)
+ rest: (method, path, data) ->
+ options = { url: @urlFor(path) }
if data? then options.body = JSON.stringify(data)
Rest.op(method, options).then (body) ->
if body? then JSON.parse(body) else null
-
+ setOwnerAuth: (username, password) ->
+ @ownerAuthentication.username = username
+ @ownerAuthentication.password = password
-
- publisherKeys:
- get: -> @requireOwner => @asEventArray => @op("get", "keys/publisher")
+ class _PublisherKeys
+ get: requireOwner asEventArray -> @rest("get", "keys/publisher")
+ create: requireOwner -> @rest("post", "keys/publisher")
- # ----- helper decorators
- requireOwner: (f) ->
- if not @ownerAuthentication? then return Q.reject(new Error("Requires authentication as owner"))
- f()
-
- asEventArray: (f) ->
- f().then (data) =>
- (new EventSequence(@schema, data)).toArray()
View
@@ -132,7 +132,7 @@ class Schema
obj[k] = resource.data[k]
else if fieldType == "reference"
ref = resource.references[k]
- if ref? then obj[k] = @inflate(ref)
+ if ref? then obj[k] = (if ref._fauna? then ref else @inflate(ref))
obj
deflate: (obj) ->
@@ -56,8 +56,7 @@ describe "EventSequence", ->
@field "name"
schema.addPrototypes Cat
list = (new fauna.EventSequence(schema, data2)).toArray()
- list[0].name.should.eql("Simba")
- list[1].name.should.eql("Spooky")
+ list.map((x) -> x.name).should.eql [ "Spooky", "Simba" ]
Oops, something went wrong.

0 comments on commit da279ff

Please sign in to comment.