-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalamity-min.js.map
1 lines (1 loc) · 20.2 KB
/
calamity-min.js.map
1
{"version":3,"file":"calamity-min.js","sources":["/calamity/calamity/Bridge.coffee","/calamity/calamity/Bus.coffee","/calamity/calamity/Emitter.coffee","/calamity/calamity/Message.coffee","/calamity/calamity/Subscription.coffee","/calamity/calamity/util.coffee"],"names":[],"mappings":"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","sourcesContent":["# # Bridge\n# Allows multiple busses to be linked together.\nBridge = class Calamity.Bridge\n\t# The number of miliseconds to remember seen messages for.\n\tSEEN_TIME: 500\n\t# All busses connected by thisbcridge.\n\t_busses: null\n\t# A temporary record of all messages seen.\n\t_seen: null\n\t# The timeout ID of the next cleaning of seen messages.\n\t_cleanId: null\n\n\tconstructor: (busses...) ->\n\t\t@_seen = {}\n\t\t@_busses = busses\n\t\tfor bus in busses\n\t\t\t@subscribeBus bus\n\t\treturn\n\n\t# Subscribes to all messages on the bus\n\tsubscribeBus: (bus) ->\n\t\tbus.subscribe \"*\", do (bus) => (msg) => @handle bus, msg\n\t\treturn\n\n\t# Handles a single message.\n\t# Bus is the event bus instance which the message came from.\n\t# The default implementation sends the message to all other busses.\n\thandle: (bus, msg) ->\n\t\treturn if @seen msg\n\t\tfor b in @_busses\n\t\t\tunless b is bus\n\t\t\t\tb.publish msg\n\t\treturn\n\n\t# Returns true if the supplied message has been seen previously.\n\t# Unless `save` is set to false, the message will be saved as seen.\n\tseen: (msg, save = true) ->\n\t\t# Returns true if message has been seen and its time limit is within the bounds.\n\t\tlimit = new Date().getTime() - @SEEN_TIME\n\t\ttime = @_seen[msg.id]\n\t\tif time? and time > limit\n\t\t\treturn true\n\t\t# Message not seen, save it.\n\t\tif save\n\t\t\t@_seen[msg.id] = new Date().getTime()\n\t\t\t@_scheduleClean()\n\t\treturn false\n\n\t# Schedules a cleanout of the seen messages.\n\t_scheduleClean: ->\n\t\treturn if @_cleanId\n\t\t@_cleanId = _.delay (=>\n\t\t\t@_clean()\n\t\t\t# Schedule another if we still have messages.\n\t\t\tunless _.isEmpty @_seen\n\t\t\t\t@_scheduleClean()\n\t\t\treturn\n\t\t), @SEEN_TIME\n\t\treturn\n\n\t# Clean the seen messages.\n\t_clean: ->\n\t\tseen = @_seen\n\t\tlimit = new Date().getTime() - @SEEN_TIME\n\t\tfor own id, time of seen\n\t\t\tif time < limit\n\t\t\t\tdelete seen[id]\n\t\treturn\n","# # Bus\n# Manages passing events from publishers to subscribers.\nBus = class Calamity.Bus\n\tconstructor: ->\n\t\t# Generate ID.\n\t\t@id = util.genId()\n\t\t# Registered subscriptions container.\n\t\t@_subscriptions = {}\n\t\t# Registered bridges container.\n\t\t@_bridges = []\n\n\t# ## `subscribe()`\n\t# Register a handler to an address.\n\tsubscribe: (address, handler, context) ->\n\t\t# Initialize subscriptions container for this address.\n\t\tunless @_subscriptions[address]\n\t\t\t@_subscriptions[address] = []\n\t\t# Create subscription.\n\t\tsub = new Subscription address, handler, context, @\n\t\t# Add to list.\n\t\t@_subscriptions[address].push sub\n\t\t# Send to bridges.\n\t\t@_bridgeProp \"subscribe\", subscription: sub\n\t\t# Return subscription.\n\t\treturn sub\n\n\t# ## `unsubscribe()`\n\t# Unsubscribes a handler.\n\tunsubscribe: (address, handler) ->\n\t\tsub = address\n\t\t# Search by subscription.\n\t\tif sub instanceof Subscription\n\t\t\t# Check address.\n\t\t\taddress = sub.address\n\t\t\treturn unless @_subscriptions[address]\n\t\t\tfor s, i in @_subscriptions[address]\n\t\t\t\tif s is sub\n\t\t\t\t\t@_subscriptions[address].splice i\n\t\t# Otherwise search by address and handler.\n\t\telse\n\t\t\t# Check for address.\n\t\t\treturn unless @_subscriptions[address]\n\t\t\tfor s, i in @_subscriptions[address]\n\t\t\t\tif s.address is address and s.handler is handler\n\t\t\t\t\tsub = s\n\t\t\t\t\t@_subscriptions[address].splice i\n\t\t# Send to bridges.\n\t\t@_bridgeProp \"unsubscribe\", subscription: sub\n\t\treturn\n\n\t# ## `publish()`\n\t# Publishes an event to a all subscribers on an address.\n\tpublish: (address, data, reply) ->\n\t\tmsg = @_createMessage address, data, reply\n\t\taddress = msg.address\n\t\t# Check if message has already been processed by this bus.\n\t\treturn @ if msg.sawBus @\n\t\t# Register this bus on the event\n\t\tmsg.addBus @\n\t\t# Publish to target address.\n\t\t@_publishAddress address, msg\n\t\t# Publish to wildcard address.\n\t\t@_publishAddress \"*\", msg\n\t\t# Send to bridges.\n\t\t@_bridgeProp \"publish\", message: msg\n\n\t\treturn @\n\n\t# ## `send()`\n\t# Sends an event to a single subscribed address.\n\t# Sends are sent to wildcard addresses, ever.\n\tsend: (address, data, reply) ->\n\t\tmsg = @_createMessage address, data, reply\n\t\taddress = msg.address\n\t\t# Check if message has already been processed by this bus.\n\t\treturn @ if msg.sawBus @\n\t\t# Register this bus on the event\n\t\tmsg.addBus @\n\t\t# Publish to target address.\n\t\t@_sendAddress address, msg\n\t\t# Send to bridges.\n\t\t@_bridgeProp \"send\", message: msg\n\n\t\treturn @\n\n\t# ## `bridge()`\n\t# Attached a bridge object to this bus.\n\t# Briges will receive information about everything that's going on.\n\tbridge: (bridge) ->\n\t\tthrow new Error \"Briges must extend Calamity.EventBridge\" unless bridge instanceof EventBridge\n\t\t@_bridges.push bridge unless _.contains @_bridges, bridge\n\t\treturn @\n\n\t# Utility function for creating messages.\n\t_createMessage: (address, data, reply) ->\n\t\t# Construct new Message is necesarry.\n\t\tmsg = address\n\t\tunless msg instanceof Message\n\t\t\tmsg = new Message address, data, reply\n\t\treturn msg\n\n\t# Publishes a message to an address.\n\t_publishAddress: (address, msg) ->\n\t\t# Check if we have subscriptions at all for this address.\n\t\treturn unless @_subscriptions[address]\n\t\t# Send message to all subscriptions.\n\t\tfor subscription in @_subscriptions[address]\n\t\t\tsubscription.trigger msg\n\t\treturn\n\n\t# Sends a message to an address.\n\t_sendAddress: (address, msg) ->\n\t\t# Check if we have subscriptions at all for this address.\n\t\treturn unless @_subscriptions[address]\n\t\t# Send message to a single random subscription.\n\t\tsubs = @_subscriptions[address]\n\t\tlen = subs.length\n\t\ti = Math.floor(Math.random()*len)\n\t\tsubs[i].trigger msg\n\t\treturn\n\n\t# Propagates to all bridges.\n\t_bridgeProp: (type, data) ->\n\t\treturn unless @_bridges.length > 0\n\t\taddress = \"bus.#{type}\"\n\t\tdata.bus = @\n\t\tfor b in @_bridges\n\t\t\tb.trigger address, data\n\t\treturn\n\n# We automatically construct a default global bus when needed.\nGLOBAL_BUS = null\nCalamity.global = ->\n\tGLOBAL_BUS or= new Bus()\n\treturn GLOBAL_BUS","# # Emitter\n# Mixin class for attaching an instance-local event bus to objects.\n# It adds the `on()`, `off()`, and `trigger()` methods to the object, which allows object-local addresses to be\n# published and subscribed to.\n# To mix this into any object or class, use `Calamity.emitter(*obj*)`.\nEmitter = class Calamity.Emitter\n\t# ## `on()`\n\t# Register a handler to an address.\n\t# this returns a `Subscription` object which can be used to unregister later.\n\ton: (address, handler, context) ->\n\t\tcontext or= @\n\t\treturn getEmitterBus(@).subscribe address, handler, context\n\n\t# ## `off()`\n\t# Unregisters a handler from an address.\n\toff: (address, handler, context) ->\n\t\treturn unless hasEmitterBus(@)\n\t\tcontext or= @\n\t\treturn getEmitterBus(@).unsubscribe address, handler, context\n\n\t# ## `trigger()`\n\t# Publishes an event to an address.\n\ttrigger: (address, data, reply) ->\n\t\treturn unless hasEmitterBus(@)\n\t\treturn getEmitterBus(@).publish address, data, reply\n\n# Private statis function for checking is the object has an emitter bus.\nhasEmitterBus = (obj) ->\n\treturn false unless obj?._calamity?.emitter?.bus?\n\treturn true\n\n# Private static function for preparing an on-demand event bus for an object.\ngetEmitterBus = (obj) ->\n\tcalamity = (obj._calamity or= {})\n\temitter = (calamity.emitter or= {})\n\treturn emitter.bus or= new Bus()\n\n\n# ## `Calamity.emitter()`\n# Adds emitter functionality to the supplied object.\nCalamity.emitter = (obj) ->\n\t_.extend obj, Emitter.prototype\n","# # Message\n# Represents a single message in the system.\nMessage = class Calamity.Message\n\t# Constructor.\n\tconstructor: (@address, @data = {}, replyHandler) ->\n\t\t# Generate ID.\n\t\t@id = util.genId()\n\t\t# Remebered busses container.\n\t\t# This will store the ID of every bus the event has seen, to prevent repeated execution.\n\t\t@_busses = []\n\t\t# Check reply handler.\n\t\tunless _.isUndefined(replyHandler) or _.isFunction(replyHandler)\n\t\t\tthrow new Error \"Reply must be a function\"\n\t\t@_replyHandler = replyHandler\n\t\t# Default values.\n\t\t@status = \"ok\"\n\t\t@error = null\n\n\t# ## `reply()`\n\t# Executes the reply handler, if this message has one.\n\treply: (data, replier) ->\n\t\treplyHandler = @_replyHandler\n\t\t# Don't do anything if we don't have a reply handler.\n\t\treturn unless _.isFunction(replyHandler)\n\t\t# Wrap data and further replies in another message.\n\t\tunless data instanceof Message\n\t\t\tdata = new Message null, data, replier\n\t\t# Execute.\n\t\treplyHandler data\n#\t\t_.defer ->\n#\t\t\treplyHandler data\n#\t\t\treturn\n\t\treturn @\n\n\t# ## `replyError()`\n\t# Executes the reply handler with an error instead of a reply.\n\treplyError: (error, data = {}) ->\n\t\t# Ensure meaningful serialization.\n\t\tif error instanceof Error\n\t\t\t# Transfer values to data.\n\t\t\tfor v in \"message,name,stack,fileName,lineNumber,description,number\".split(\",\")\n\t\t\t\tval = error[v]\n\t\t\t\tval = val.toString() if val and typeof val.toString is \"function\"\n\t\t\t\tdata[v] = val\n\t\t\tif typeof error.toString is \"function\"\n\t\t\t\tdata.string = error.toString()\n\t\t\t\terror = data.string\n\t\t\t\tif data.stack\n\t\t\t\t\terror += \" :: \" + data.stack\n\t\t# Create new error message.\n\t\tmsg = new Message null, data\n\t\tmsg.status = \"error\"\n\t\tmsg.error = error\n\t\t# Send reply.\n\t\t@reply msg\n\t\treturn @\n\n\t# Automatically catches and propagates errors, removing the need to constantly check incoming messages for errors.\n\t# Example usage:\n\t#\n\t# @send \"address\", (reply) => msg.catch reply, =>\n\t# # your code here, reply will never be an error.\n\t#\n\t# In the above example, catch will check reply for errors, and pass them to the reply handler on msg.\n\t# If no errors are detected, it will execute the supplied handler inside a try/catch block, and pass\n\t# any errors back through msg.\n\t# If no reply handler exists on msg, errors will be rethrown, or no try/catch block will be used.\n\t# The first argument is optional and can be an Message, or any throwable value.\n\t# If it's falsy, then it's simply ignored and handler is executed.\n\tcatch: (other, handler) ->\n\t\tunless handler?\n\t\t\tunless _.isFunction other\n\t\t\t\tthrow new Error \"Supplied handler is not a function, #{typeof other} supplied\"\n\t\t\thandler = other\n\t\t\tother = undefined\n\t\t# If we don't have a reply handler, throw error directly.\n\t\tunless _.isFunction @_replyHandler\n\t\t\t# Throw error if we have one.\n\t\t\tif other?\n\t\t\t\tif other instanceof Message\n\t\t\t\t\tif other.isError()\n\t\t\t\t\t\tthrow other.error\n\t\t\t\telse\n\t\t\t\t\tother = new Error other unless other instanceof Error\n\t\t\t\t\tthrow other\n\t\t\t# Execute handler.\n\t\t\thandler other\n\t\t# If we have a reply handler, pass errors to it.\n\t\telse\n\t\t\t# Pass supplied errors.\n\t\t\tif other?\n\t\t\t\tif other instanceof Message\n\t\t\t\t\tif other.isError()\n\t\t\t\t\t\t@reply other\n\t\t\t\t\t\treturn\n\t\t\t\telse\n\t\t\t\t\tother = new Error other unless other instanceof Error\n\t\t\t\t\t@replyError other\n\t\t\t\t\treturn\n\t\t\t# Execute handler inside try/catch block.\n\t\t\ttry\n\t\t\t\thandler other\n\t\t\tcatch err\n\t\t\t\t@replyError err\n\t\treturn\n\n\t# ## `isSuccess()`\n\t# Returns true if this message is marked successful, which is the default state.\n\tisSuccess: ->\n\t\treturn @status is \"ok\"\n\n\t# ## `isError()`\n\t# Returns true if this message is marked as errored, such as when replying with `replyError()`.\n\tisError: ->\n\t\treturn @status is \"error\"\n\n\t# Returns a parameter message data.\n\t# If the parameter is not present, `def` is returned.\n\tgetOptional: (param, def) ->\n\t\tparts = param.split \".\"\n\t\tval = @data[parts[0]]\n\t\t# Iterate from second element onwards.\n\t\tif parts.length > 1 then for part in parts.splice 1\n\t\t\tif _.isObject(val) and val[part]?\n\t\t\t\tval = val[part]\n\t\t\telse\n\t\t\t\tval = undefined\n\t\t\t\tbreak\n\t\t# Default.\n\t\tif typeof val is \"undefined\"\n\t\t\treturn def\n\t\treturn val\n\n\t# Returns a parameter message data.\n\t# If the parameter is not present, an error is thrown.\n\tgetRequired: (param) ->\n\t\tval = @getOptional param\n\t\tif typeof val is \"undefined\"\n\t\t\tthrow new Error \"Variable \\\"#{param}\\\" not found on message with address \\\"#{@address}\\\"\"\n\t\treturn val\n\n\t# ## `addBus()`\n\t# Adds a bus to the internal list.\n\taddBus: (bus) ->\n\t\treturn @ if @sawBus(bus)\n\t\t@_busses.push bus.id\n\t\treturn @\n\n\t# ## `sawBus()`\n\t# Returns true if this message has been processed by the supplied bus.\n\tsawBus: (bus) ->\n\t\treturn _.contains @_busses, bus.id\n\n\t# ## `toJSON()`\n\t# Converts the message to a plain JSON object for possible storage or transmission.\n\ttoJSON: ->\n\t\tjson =\n\t\t\tcalamity: Calamity.version\n\t\t\taddress: @address\n\t\t\tdata: @data\n\t\t\tstatus: @status\n\t\t\terror: @error\n\t\tif @_replyHandler?\n\t\t\tjson.reply = _.bind @reply, @\n\t\treturn json\n\n\t# ## `fromJSON()`\n\t# Converts a JSON object to an Message.\n\t# The message must have been serialized using `Message`'s own `toJSON()` method, otherwise weird things could happen.\n\t@fromJSON = (json) ->\n\t\tthrow new Error \"JSON must be an object\" unless _.isObject json\n\t\tthrow new Error \"Serialized JSON is not for calamity: #{JSON.stringify(json)}\" unless json.calamity?\n\t\tmsg = new Message json.address, json.data, json.reply\n\t\tmsg.status = json.status\n\t\tmsg.error = json.error\n\t\treturn msg\n","# # Subscription\n# Represents a subscription of a handler to an address on an bus.\nSubscription = class Calamity.Subscription\n\t# Constructor.\n\tconstructor: (@address, @handler, @context, @bus) ->\n\t\t@id = util.genId()\n\t\t@active = true\n\t\treturn\n\n\t# ## `unsubscribe()`\n\t# Shorthand for unsubscribing.\n\tunsubscribe: ->\n\t\treturn unless @active\n\t\[email protected] @\n\t\t@active = false\n\t\treturn @\n\n\t# ## `trigger()`\n\t# Fires the handler with the supplied message.\n\ttrigger: (msg) ->\n\t\treturn @ unless @active\n\t\t# Bind handler.\n\t\tbound = _.bind @handler, @context\n\t\t# Execute.\n\t\tbound msg\n#\t\t_.defer ->\n#\t\t\tbound msg\n#\t\t\treturn\n\n\t\treturn @\n","# # util\n# A set of utilities used inside Calamity.\n\n# Import Math functions.\nrandom = Math.random\nfloor = Math.floor\n\n# Hexadecimals.\nHEX = \"0123456789abcdef\".split \"\"\n\n# Generic utility functions.\nutil = Calamity.util =\n\t# Generates a 128 bit ID.\n\tgenId: ->\n\t\tid = \"\"\n\t\tfor i in [1..32]\n\t\t\tid += HEX[floor(random() * HEX.length)]\n\t\treturn id\n"],"sourceRoot":"/calamity"}