Permalink
Browse files

* first commit after package renaming

  • Loading branch information...
1 parent 0178ede commit be7aaeb802d3a19a91b864b537ddb2d967037e30 @Meettya committed Aug 13, 2012
View
@@ -0,0 +1,4 @@
+.DS_Store
+node_modules
+*.sock
+
View
@@ -0,0 +1,7 @@
+support
+test
+test_browser
+examples
+doc
+*.sock
+.DS_Store
View
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
View
@@ -0,0 +1,89 @@
+fs = require 'fs'
+CoffeeScript = require 'coffee-script'
+{spawn, exec} = require 'child_process'
+Stitch = require 'stitch'
+
+
+# ANSI Terminal Colors.
+enableColors = no
+unless process.platform is 'win32'
+ enableColors = not process.env.NODE_DISABLE_COLORS
+
+bold = red = green = reset = ''
+if enableColors
+ bold = '\x1B[0;1m'
+ red = '\x1B[0;31m'
+ green = '\x1B[0;32m'
+ reset = '\x1B[0m'
+
+# Log a message with a color.
+log = (message, color, explanation) ->
+ console.log color + message + reset + ' ' + (explanation or '')
+
+# Run a CoffeeScript through our node/coffee interpreter.
+run = (args, cb) ->
+ proc = spawn 'node', ['./node_modules/.bin/coffee'].concat(args)
+ proc.stderr.on 'data', (buffer) -> log buffer.toString(), red
+ proc.on 'exit', (status) ->
+ process.exit(1) if status != 0
+ cb() if typeof cb is 'function'
+
+# Run a mocha tests
+run_test = (args, cb) ->
+ proc = spawn 'node', ['./node_modules/.bin/mocha'].concat(args)
+ proc.stderr.on 'data', (buffer) -> log buffer.toString(), red
+ proc.stdout.on 'data', (buffer) -> console.log buffer.toString()
+ proc.on 'exit', (status) ->
+ process.exit(1) if status != 0
+ cb() if typeof cb is 'function'
+
+jade = (args, cb) ->
+ proc = spawn 'jade', args
+ proc.stderr.on 'data', (buffer) -> log buffer.toString(), red
+ # proc.stdout.on 'data', (buffer) -> console.log buffer.toString()
+ proc.on 'exit', (status) ->
+ process.exit(1) if status != 0
+ cb() if typeof cb is 'function'
+
+task 'build', 'build module from source', build = (cb) ->
+ files = fs.readdirSync 'src'
+ files = ('src/' + file for file in files when file.match(/\.coffee$/))
+ run ['-c', '-o', 'lib/'].concat(files), ->
+ log ' -> build done', green
+ cb() if typeof cb is 'function'
+
+task 'test', 'test builded module', ->
+ build ->
+ test_file = 'test/dendrite-test.coffee'
+ run_test test_file, -> log ' -> all tests passed :)', green
+
+task 'build_test_browser_page', 'build test html for browser', build_test_browser_html = (cb) ->
+ files = fs.readdirSync 'test_browser/src'
+ files = ('test_browser/src/' + file for file in files when file.match(/\.jade$/))
+ jade ['--pretty', '--no-debug', '--out', 'test_browser'].concat(files), ->
+ log ' -> build test html for browser done', green
+ cb() if typeof cb is 'function'
+
+task 'build_browser_comp_js', 'build browser-compatibility module with stitch', build_browser_comp_js = (cb) ->
+ my_res_filename = __dirname + '/test_browser/js/dendrite.js'
+ my_package = Stitch.createPackage(
+ paths: [ __dirname + '/src']
+ )
+ my_package.compile (err, source) ->
+ fs.writeFile my_res_filename, source, encoding='utf8', (err) ->
+ throw err if err?
+ log ' -> lib compiled', green
+ cb() if typeof cb is 'function'
+
+task 'build_test_browser_js', 'build test js for browser', build_test_browser_js = (cb) ->
+ files = fs.readdirSync 'test'
+ files = ('test/' + file for file in files when file.match(/\.coffee$/))
+ run ['-c', '-o', 'test_browser/js/'].concat(files), ->
+ log ' -> build test js for browser done', green
+ cb() if typeof cb is 'function'
+
+task 'build_test_browser', 'build test browser suite', ->
+ build_browser_comp_js ->
+ build_test_browser_html ->
+ build_test_browser_js ->
+ log ' -> build test browser suite start', green
View
@@ -0,0 +1,47 @@
+## 0.4.1 / 2012-08-07 01:00 PM
+
+ - Add #subscribeGuarded() - now we are MAY to manage on error at publishing (see README)
+ - Add 'verbose' option to constructor - if you want some info from observer (see README)
+ - Add #publishSync() as alias to #publish() method - if you like significant names
+ - Add standalone examples
+ - Refactored some things
+
+## 0.3.7 / 2012-07-07 01:51 PM
+
+ - Refactored all to improve readability
+
+
+## 0.3.5 / 2012-07-05 01:40 PM
+
+ - Add 'Install' section to Readme
+ - Small fixs
+
+## 0.3.3 / 2012-07-05 09:07 AM
+
+ - Add #publishAsync method - at now its possible to use observer in asynchronously manner
+ - Add tests for #publishAsync
+ - Change test path to (/src) for fast development tests. The browser tests still use compiled .js version
+ - Some small fix
+
+## 0.2.9 / 2012-06-30 10:51 AM
+
+ - Change test suite to use one version for node and browser
+ - Small fix at package defs
+
+## 0.2.7 / 2012-06-24 05:27 PM
+
+ - Add JSFIDDLE example
+
+## 0.2.5 / 2012-06-23 02:02 AM
+
+ - Change require('underscore') to browser-compatibility type
+ - Add browser test suite (see /test_browser)
+
+## 0.2.3 / 2012-06-21 03:38 PM
+
+ - Rename base file to whet.observer
+
+## 0.2.1 / 2012-06-04 01:07 PM
+
+ - Initial release
+ - Travis added
View
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Dmitrii Karpich
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
View
174 README.md
@@ -1,4 +1,172 @@
-dendrite
-========
+[![Build Status](https://secure.travis-ci.org/Meettya/whet.observer.png)](http://travis-ci.org/Meettya/whet.observer)
-An extended Observer pattern implementation, worked at any JavaScript environment
+# whet.observer
+
+A standalone Observer that actually works on node.js, adapted from Publish/Subscribe plugin for jQuery.
+
+Oh! Yes, it works in browser too, just connect undercore above. See test_browser folder for detail or [jsfiddle example](http://jsfiddle.net/Meettya/r5XkG/embedded/result/)
+
+And last, but not least - it have asynchronous publishing method #publishAsync()
+
+Surprise! At now we have a dog! Its name "watchdog" and its lives in #subscribeGuarded(). Its watch on callbacks when they firing. See Readme/tests/example for more.
+
+## Description:
+
+This script implement Observer pattern in Object Oriented-manner.
+
+I find this mush more predictable than one huge global observer.
+
+Also its allow you to operate to multiple topics just by separating the topic names with a space, as [JZ-Publish-Subscribe-jQuery-Plugin](https://github.com/joezimjs/JZ-Publish-Subscribe-jQuery-Plugin) do it.
+
+See the examples below or test files.
+
+## Install:
+
+ npm install whet.observer
+
+## Usage:
+
+All examples use CoffeeScript, you may use plain JS instead (but why?).
+
+
+At first you must create Observer object to interact with it
+
+ Observer = require 'whet.observer'
+ observer_obj = new Observer
+
+Constructor have some options on create
+
+ verbose : ['debug'|'warning'|'error'|'silent'] # verbose levels placed by decrementing
+
+### Subscribing:
+
+Subscribe to a single topic called 'foo'
+
+The callback function receives two arguments:
+
+- data: any data that the publisher sent
+- topic: the topic that was published to that called the function
+
+Note: #subscribe() returns a 'handle' that can be used to unsubscribe easily
+
+ handle = observer_obj.subscribe("foo", (topic, data) -> console.log data, topic )
+
+Subscribe to multiple topics at once
+'foo', 'bar', and 'baz' are three different topics
+
+ handle = observer_obj.subscribe("foo bar baz", (topic, data) -> console.log data, topic )
+
+Subscribe with a context
+Callback now has its this variable assigned to the specified object
+
+ obj =
+ internal_data: 0
+ func: (topic, data) -> console.log data, topic, @internal_data
+
+ handle = observer_obj.subscribe("foo", obj.func, obj)
+
+### Subscribing with watchdog:
+
+Guarded subscription give as powerful technique to manage errors in subscribed functions
+
+ observer_obj = new Observer verbose : 'silent'
+
+ callback = (topic, data) -> throw Error "Die at #{topic}"
+ watchdog = (err, options) ->
+ console.log "Error string: | #{err} |"
+ console.log "Error detail", options
+ null
+ handle = observer_obj.subscribeGuarded 'foo', callback, watchdog
+
+ observer_obj.publish 'foo', 'some data'
+
+return to console
+
+ Error string: | Error: Die at foo |
+ Error detail { topic: 'foo',
+ callback: [Function],
+ object: {},
+ data: [ 'some data' ] }
+
+Now subscribed object MAY decide how support itself errors
+
+### Unsubscribing:
+
+Unsubscribe using the handle gained from calling #subscribe().
+The callback that was sent into the #subscribe() call that you retrieved the
+handle from will be unsubscribed from all of the topics subscribed to
+
+ observer_obj.unsubscribe(handle)
+
+Unsubscribe by specifying the topics, callback, and context (if one was
+when subscribed).
+Note: if you use an anonymous in the #subscribe() call, you can retrieve a
+reference to the callback from the handle's 'callback' property
+
+ observer_obj.unsubscribe("foo bar", callback_reference, obj)
+ # or
+ observer_obj.unsubscribe("foo bar", handle.callback);
+
+Using the second syntax is useful if you used an anonymous function and got
+the handle, but don't want to unsubscribe from all of the topics.
+
+Unsubscribe all callbacks from 1+ topics
+If you skip giving a callback as a parameter, it'll unsubscribe all functions
+from the topic(s) given
+
+ observer_obj.unsubscribe("foo bar")
+
+
+### Publishing:
+
+Publish to a topic (or topics)
+When you publish, you may send data to the subscribers, or you can leave the
+parameter empty if you have no particular data to send. The data does not have
+a particular format that it must be in, giving you the flexibility to use it
+in whatever way is appropriate for your application
+
+ observer_obj.publish("foo bar", "This is some data")
+
+Or you may send task to queue for asynchronous execution (see ./tests for more examples)
+
+ observer_obj.publishAsync("foo bar", "This is some data")
+
+## General Notes
+
+### Topics:
+
+Topics can use any name that can also be used as a property name. Since the
+topic is always retrieved using the bracket notation (e.g. object["prop"]), as
+opposed to the dot notation (e.g. object.prop), you are allowed to use a large
+numbers of characters that aren't legal for variable names, such as slashes ("/")
+or periods ("."). You cannot, however, use a space (" ") because this is the
+character that separates multiple topics.
+All three functions (subscribe, unsubscribe, and publish) are able to take one
+or multiple topics (separated by a space).
+
+### Callback Context:
+When a callback function is invoked, it is called in the context of blank object.
+This means that `` this === {} `` inside of your function.
+You may use you own object instead, passed it as context object.
+
+### Handle:
+The handle that is returned from the #subscribe() function is simply an object
+with three properties, named "topics", "callback", and "context" that correspond
+to the three parameters that you sent in (or context will be a blank object if
+no context was provided):
+
+ handle =
+ topics : "the topics you sent in"
+ callback : (topic, data)->
+ // this is the callback function you sent in
+ context : contextObjYouSentIn || {}
+
+### Callback Topic Argument:
+The first argument that the callback receives is the topic in which the
+function was subscribed and invoked from. This will always be a string
+containing only one topic, even if the #publish() function is called with
+multiple topics because the callback will be run once for each individual
+topic that is published.
+
+## Need you help!
+If you feel ability to translate good Russain README (I'm add it soon) to correct English - please, ping me. Thanks in advance!
Oops, something went wrong.

0 comments on commit be7aaeb

Please sign in to comment.