ShortId = require('shortid')
Type = require('type-of-is')ShortId = require('shortid')
Type = require('type-of-is')attribute name used for serializing a model’s type with its data via deflate
MODEL_KEY = '$model'object mapping from model names to constructors that needs to be set via Message.setModels
models = nullDeflate the passed object so that it can be passed over the wire as json and inflated on the other end into models
obj : object to deflate
deflate = (obj)->
switch Type(obj)
when Array
obj.map(deflate)
when Object
res = {}
for k,v of obj
res[k] = deflate(v)
res
else
if (obj and obj.deflate and Type(obj.deflate, Function))
obj.deflate(
model_key : MODEL_KEY
)
else
objInflate the passed json object by converting plain json objects into instances of their associated model. Model types are specified via model key defined in Strings
obj : object to inflate
inflate = (obj)->
unless models
return obj
switch Type(obj)map over arrays
when Array
obj.map(inflate)traverse object and inflate its values
when Object
res = {}
Model = nullif there is a MODEL_KEY attribute present in the json, use it to lookup the associated model
if (MODEL_KEY of obj)
model_name = obj[MODEL_KEY]
delete obj[MODEL_KEY]
Model = if (model_name of models)
models[model_name]
else
console.error("Can't find Model for #{model_name}")
null
for k,v of obj
res[k] = inflate(v)
if Model
res = new Model(res)
resreturn everything else as is
else
objA WebSocket message
class Messagename for this message
name : nullunique id for this message (shared by its reply)
id : nulljwt auth token
token : nullthe data for this message
data : nullan error if needed
error : nullCreate a message
name : the name for this message
id : id for this message, otherwise will be generated
token : jwt token used to identify / authorize the user sending this message
data : the data / params for this message
error : used in replies if error occured during processing of message
constructor : (args)->
unless args.name
throw new Error("Message must have name")
@name = args.name
@id = args.id || ShortId.generate()
@token = args.token
@data = if ('data' of args)
inflate(args.data)
else
{}
@error = null
if args.error
@error = args.error
unless Type(@error, Error)
@error = new Error(@error) @setModels : (_models)->
models = _models @parse : (json)->
try
message_data = JSON.parse(json)
catch error
return @error("JSON.parse failed")
new @(message_data) reply : (args)->
args.name = @replyName()
args.id = @id
new @constructor(args)The name of the reply to this message
replyName : ()->
"#{@name}Reply"The event name that gets triggered by this message’s reply This is used in the ClientStore in order to trigger load callback once the data is available
replyEventName : ()->
"message:#{@replyName()}:id:#{@id}"Encode this message into json, deflating its data in the process
stringify : ()->
message = {
name : @name
id : @id
token : @token
}
if @error
message.error = @error.message
if @data
message.data = @data
message = deflate(message)
JSON.stringify(message)Returns true if this message has an error
isError : ()->
!!@error is : (name)->
(@name is name)Convenience method for checking whether this message’s is one of several possibilities
names : message names to check against
in : (names)->
(@name in names)
module.exports = Message