Export Observable object

Export Observable object

Jnoid
=====

This is a functional reactive programming library in Coffescript to use in
browser or Node.js applications. It owes the idea to Bacon.js, but should
describe the domain in proper terms, have less operations in primitives and be
shorter and simpler.

    Jnoid = {
      VERSION: "0.0.1"
    }

The core idea is having an abstraction of `Stream` which is a discrete
sequence of values and an abstraction of a `Box` which is a continous
time-varying value, both of which you can subscribe on.

Maybe and Events
----------------

We'll slightly extend the famous `Maybe` idiom to support error values. Now
it's a sum of `Maybe` and `Either` and can be described as `Maybe = Just x |
Wrong y | Nothing`.

    class Maybe

    class Just extends Maybe
      constructor: (@value) ->
      getOrElse: -> @value
      filter: (f) -> if @test(f) then @ else Nothing
      test: (f) -> f @value
      map: (f) -> new Just(f @value)
      isEmpty: -> false
      inspect: -> "Just #{@value}"

    class Bad extends Maybe
      getOrElse: (some)-> some
      filter: (f) -> @
      test: (f) -> true
      map: (f) -> @
      isEmpty: -> true

    class Wrong extends Bad
      constructor: (@error) ->
      inspect: -> "Wrong #{@error}"

    Nothing = new class extends Bad
      constructor: ->
      inspect: -> "Nothing"

`Event` class will be just a type alias for it.

    [Event, Fire, Error, Stop] = [Maybe, Just, Wrong, Nothing]
    toEvent = (x) -> if x instanceof Event then x else new Fire x
    toError = (x) -> if x instanceof Event then x else new Error x

Observable
----------

The point is that we can abstract from `Stream` and `Box` and define a common
behavior, calling it `Observable`.

Class `Observable` will be determined via a `subscribe` function. This
function should receive a subscriber or sink function as an argument and
call it whenever event is fired. This enables push semantics for `Stream`
and `Box`.

There are two ways to unsubscribe. First is to call function that subscribe
returns. Second is return `Reply.stop` from event listener.

    class Observable
      constructor: (subscribe)->
        @subscribe = @dispatched subscribe

`dispathed` is a function that makes `Observable` abstract and will hold the
actual implementation differences between `Stream` and `Box`. If you are
interested in `dispatched`, check it's implementations there.

      dispatched: fail

A basic ways to listen to Observable are `onValue` and `onError`. While
`subscribe` sends raw events, `onValue` unwraps them in case they hold values
and deliver them to the subscriber.

      onValue: (f) ->
        @subscribe (event) ->
          event.map((v)-> f(v)).getOrElse(Reply.more)

`onError` does roughly the same as `onValue`, but is selecting errors and
unwraps them.

      onError: (f) ->
        @subscribe (event) ->
          if event instanceof Error
            f event.error
          else
            Reply.more

We can now define basic transforms. Start with `map` and `filter`. We can
see common pattern there, it's abstracted in `withHandler`.

      withHandler: (handler)->
        new @constructor @dispatched(@subscribe, handler)

      map: (f)->
        @withHandler (event)-> @push event.map(f)

      filter: (f)->
        @withHandler (event)-> if event.test(f) then @push event else Reply.more

A useful combinator is `recover`, with will turn errors into regular
events using transform function.

      recover: (f)->
        @withHandler (event) ->
          if event instanceof Error
            @push new Fire f(event.error)
          else
            @push event

The most powerful combinator in our case is `flatMap`. It accepts a function
that turns each of the values in observable to a new observable. We then return
a new Observable that will combine them.

The first way to combine them is to just collect all the events from the
spawned childen. This matches the semantics of `Stream` and will allow us to
produce `merge`.

Another way to combine events is to unsubscribe all the existing children, when
a new event occurs on root, then spawn a new one and just listen to it. You can
think of it as swiching from one observable to another one. This matches the
semantics of `Box` and will allow us to produce `zip`.

      flatMapGeneric: (f, lastOnly) ->
        root = this
        new @constructor (sink) ->
          children = []
          rootStop = false
          unsubRoot = ->
          unsubChildren = ->
            unsubChild() for unsubChild in children
            children = []
          unbind = ->
            unsubChildren()
            unsubRoot()
          checkStop = ->
            if rootStop and (children.length == 0)
              sink Stop
          spawner = (event) ->
            if event == Stop
              rootStop = true
              checkStop()
            else
              unsubChildren() if lastOnly
              if event instanceof Error
                sink event
              else
                child = f event.value
                unsubChild = undefined
                childStopped = false
                removeChild = ->
                  remove(unsubChild, children) if unsubChild?
                  checkStop()
                handler = (event) ->
                  if event == Stop
                    removeChild()
                    childStopped = true
                    Reply.stop
                  else
                    tap sink(event), (reply)->
                      unbind() if reply == Reply.stop
                unsubChild = child.subscribe handler
                children.push unsubChild if not childStopped
          unsubRoot = root.subscribe(spawner)
          unbind

      flatMapAll: (f)-> @flatMapGeneric(f, false)
      flatMapLast: (f)-> @flatMapGeneric(f, true)

We can also define `skipDuplicates` which is extremely useful.

      withStateMachine: (initState, f) ->
        state = initState
        @withHandler (event) ->
          [newState, outputs] = f(state, event)
          state = newState
          stopped = any outputs,
                    (output)=> @push(output) == Reply.stop
          if stopped then Reply.stop else Reply.more

      skipDuplicates: (isEqual = (a, b) -> a is b) ->
        @withStateMachine Nothing, (prev, event) ->
          event.map((v)->
            if prev == Nothing || !prev.test((p)-> isEqual(v, p))
              [new Just(v), [event]]
            else
              [prev, []]
          ).getOrElse [prev, [event]]

From `withStateMachine` we can easily define `scan`:

      scan: (initState, f) ->
        @withStateMachine initState, (acc, event)->
          newAcc = event.map((v)->f(acc, v)).getOrElse(acc)
          [newAcc, [toEvent newAcc]]

Always good in UI there is an option to `debounce`:

      debounce: (delay)->
        @flatMapLast (value)=>
          @constructor.later delay, value

Let's do `take` and `takeWhile`:

      take: (n)->
        return @constructor.nothing() if n <= 0
        @withHandler (event) ->
          unless event instanceof Fire
            @push event
          else
            n--
            if n > 0
              @push event
            else
              @push event if n == 0
              @push Stop
              Reply.stop

      takeWhile: (f)->
        @withHandler (event) ->
          if event.test(f)
            @push event
          else
            @push Stop
            Reply.stop

`takeUntil` is going to be slightly more complicated - it's going to listen to
one stream till an event on another appears. A very useful one:

      takeUntil: (other)->
        source = this
        stopper = other.changes()
        new @constructor (sink)->
          unsubSource = ->
          unsubStopper = ->
          unbind = ->
            unsubSource()
            unsubStopper()

          transport = (event)->
            sink event
            unbind() if event == Stop
          watcher = (event)->
            sink Stop
            unbind()

          unsubSource = source.subscribe(transport)
          unsubStopper = stopper.subscribe(watcher)
          unbind

A helper method for boolean algebra (others are map2 based methods and so are
just applicable to box):

      not: -> @map (x)-> !x

How to build observables

------------------------

The basic ways to build an observable are `nothing`, `unit` and `error`. In
`Stream` semantics they mean `never`, `once` and `error`, in `Box` semantics
they mean `empty`, `always` and `error`. We won't create the aliases and give
these names to get you the feel of what they mean.

      @fromList: (values, wrapper = toEvent)->
        new @ (sink) ->
          sink event for event in map wrapper, values
          sink Stop

      @nothing: -> @fromList []
      @unit: (value)-> @fromList [value]
      @error: (value)-> @fromList [value], toError

`fromBinder` just adds a syntax sugar for us to easily define more
sophisticated constructors.

      @fromBinder: (binder, transform = id) ->
        new @ (sink) ->
          unbinder = binder (args...) ->
            events = toArray transform args...
            for event in map toEvent, events
              tap sink(event), (reply)->
                unbinder() if event == Stop or reply == Reply.stop

`poll` polls a function within given interval.

      @poll: (delay, poll) ->
        @fromBinder (handler) ->
          i = setInterval(handler, delay)
          -> clearInterval(i)
        , poll

`interval` and `later` send a fixed list of events or one event
respectively within given interval.

      @interval: (delay, list)->
        index = 0
        @poll delay, ->
          value = list[index++]
          if index < list.length
            value
          else if index == list.length
            [value, Stop]
          else
            Stop

      @later: (delay, value)->
        @interval(delay, [value])

Let's also define a function that works on promises, e.g., ajax. The
resource releasing here for ajax is abort. We should also handle promise
errors here. In a transform function we attach end to our stream.

      @fromPromise: (promise) ->
        @fromBinder (handler) ->
          promise.then handler, (e) ->
            handler new Error e
          -> promise.abort?()
        , (value) -> [value, Stop]

Finally let's define the way to receive events from DOM objects. We'll do
it assuming we're called in jQuery/Zepto fashion.

We allow to override `transform` - by default it'll take the first
argument, which is usually a jQuery event. We use `on` to subscribe and
`off` to unsubscribe.

      @fromDOM: (element, event, selector, transform) ->
        [transform, selector] = [selector, null] if isFunction(selector)

        @fromBinder (handler) =>
          element.on(event, selector, handler)
          => element.off(event, selector, handler)
        , transform

Stream
------

Class `Stream` represents a disrete sequence of values, coupled with time.  So
it uses the appropriate dispatcher to do it.

`Dispatcher` activates the listeners when a first sink is added and then just
adds them. On each event it just pushes it to all sinks.

    class StreamDispatcher
      constructor: (subscribe, handler) ->
        subscribe ?= (event) ->
        sinks = []
        @push = (event) =>
          for sink in sinks by -1
            tap sink(event), (reply)->
              remove sink, sinks if reply == Reply.stop
        handler ?= (event) -> @push event
        @handler = (event) => handler.apply(this, [event])
        @subscribe = (sink) =>
          sinks.push(sink)
          unsubSelf = subscribe @handler if sinks.length == 1
          ->
            remove sink, sinks
            unsubSelf?() unless any sinks

To have `Stream` class we just need to override abstract `dispatched` method
from the base class to use `StreamDispatcher`.

    class Stream extends Observable
      dispatched: (subscribe, handler)->
        new StreamDispatcher(subscribe, handler).subscribe

For this class we can have `flatMap` aka `bind`. In our case it's `flatMapAll`.

      flatMap: (args...)-> @flatMapAll(args...)

Having this we can easily have `merge`.

      merge: (others...)->
        Stream.fromList(map method("changes"), [@, others...]).flatten()
      flatten: -> @flatMap(id)

Using Stream when we need Box
-----------------------------

To make it transparent for a user, is this stream or box, we proxy the box
methods to box. First we define a conversion method with an optional starting
value.

      box: (initial = Nothing)->
        initial = toMaybe(initial)
        new Box (sink)=>
          sink initial unless initial.isEmpty()
          @subscribe (event)-> sink event
      changes: -> @

We could also define a new stream with initial value merged to the beginning,
but the current code is simple enough.

All proxy methods are trivial.

      zipWith: (others..., f)-> @box().zipWith(others..., f)
      and: (others...)-> @box().and(others...)
      or: (others...)-> @box().or(others...)
      not: -> @box().not()

Box
---

Class `Box` represents continuous value that changes with time. So we need a
slightly tweaked dispatcher. The difference is that it holds the current
value and sends it to each new subscriber. Another difference is that even when
the Box is ended, it still sends the last value and then immediately sends stop

    class BoxDispatcher extends StreamDispatcher
      constructor: (subscribe, handler) ->
        super subscribe, handler
        current = Nothing
        push = @push
        subscribe = @subscribe
        stopped = false

        @push = (event) =>
          event.map((x) -> current = new Just x)
          stopped = true if event == Stop
          push.apply(this, [event])
        @subscribe = (sink) =>
          reply = current.map((v)-> sink new Fire v)
          if reply.getOrElse(Reply.more) == Reply.stop
            nop
          else if stopped
            sink Stop
            nop
          else
            subscribe.apply(@, [sink])

Now class `Box` is going to use that dispatcher.

    class Box extends Observable
      dispatched: (subscribe, handler)->
        new BoxDispatcher(subscribe, handler).subscribe

For this class we can have `flatMap` aka `bind`. In our case it's `flatMapLast`.

      flatMap: (args...)-> @flatMapLast(args...)

With this `flatMap` we can define a glorious `map2`, also known as `zipWith`
for two boxes.

      map2: (other, f)->
        @flatMap (x)-> other.box().map (y)-> f(x, y)

Having this, `zipWith` is easy.

      @sequence: (boxes)->
        foldl boxes, @unit([]), (acc, box)->
          acc.map2 box, (memo, value)-> append memo, value
      @zipWith: (boxes, f)->
        @sequence(boxes).map uncurry f
      zipWith: (others..., f)->
        Box.zipWith [@, others...], f

`zip` method is it just sugar for the `sequence`.

      zip: (boxes...)-> Box.sequence([@, boxes...])

Helpful would be to define boolean algebra over boxes. `not` is defined on
`Observable`.

      and: (others...)-> @zipWith others..., (a, b)-> a && b
      or: (others...)-> @zipWith others..., (a, b)-> a || b

An interesting `sampledBy` function should take a property and stream it's
value when sampler pops:

      sampledBy: (sampler)->
        sampler.flatMap(=> @take(1)).changes()

Using Box when we need Stream
-----------------------------

To convert `Box` into `Stream` we take it's changes.

      changes: ->
        new Stream (sink)=>
          @subscribe (event)-> sink event
      box: -> @

Here are the proxy methods.

      merge: (others...)-> @changes().merge(others...)

Helpers
-------

Pretty trivial special values to return from event listeners.

    Reply =
      stop: "<stop>"
      more: "<more>"

We need some simple helper functions.

    empty = (xs)-> xs.length == 0
    method = (meth)-> (obj)-> obj[meth]()
    nop = ->
    id = (x)-> x
    fail = -> throw "method not implemented"
    head = (xs) -> xs[0]
    tail = (xs) -> xs[1...xs.length]
    uncurry = (f) -> (args)-> f(args...)
    map = (f, xs) -> f(x) for x in xs
    foldl = (xs, seed, f) ->
      for x in xs
        seed = f(seed, x)
      seed
    tap = (x, f) ->
      f(x)
      x
    remove = (x, xs) ->
      i = xs.indexOf(x)
      xs.splice(i, 1) if i >= 0
    all = (xs, f = id) ->
      for x in xs
        return false if not f(x)
      return true
    any = (xs, f = id) ->
      for x in xs
        return true if f(x)
      return false
    copyArray = (xs)-> xs.slice()
    append = (xs, x)-> tap copyArray(xs), (copy)-> copy.push x
    isFunction = (f) -> typeof f == "function"
    toArray = (x) -> if x instanceof Array then x else [x]
    toMaybe = (x) ->
      if x instanceof Maybe then x else new Just x

Exports
-------

We now need to make our objects usable outside.

    for name, value of {Observable, Stream, Box, Event, Fire, Error, Stop,
                                     Maybe, Just, Wrong, Nothing}
      Jnoid[name] = value

    if define?.amd
      define [], -> Jnoid
    else if module?.exports
      module.exports = Jnoid
    else
      @Jnoid = Jnoid

Conclusion
----------

Have fun!

Jnoid
=====

This is a functional reactive programming library in Coffescript to use in
browser or Node.js applications. It owes the idea to Bacon.js, but should
describe the domain in proper terms, have less operations in primitives and be
shorter and simpler.

    Jnoid = {
      VERSION: "0.0.1"
    }

The core idea is having an abstraction of `Stream` which is a discrete
sequence of values and an abstraction of a `Box` which is a continous
time-varying value, both of which you can subscribe on.

Maybe and Events
----------------

We'll slightly extend the famous `Maybe` idiom to support error values. Now
it's a sum of `Maybe` and `Either` and can be described as `Maybe = Just x |
Wrong y | Nothing`.

    class Maybe

    class Just extends Maybe
      constructor: (@value) ->
      getOrElse: -> @value
      filter: (f) -> if @test(f) then @ else Nothing
      test: (f) -> f @value
      map: (f) -> new Just(f @value)
      isEmpty: -> false
      inspect: -> "Just #{@value}"

    class Bad extends Maybe
      getOrElse: (some)-> some
      filter: (f) -> @
      test: (f) -> true
      map: (f) -> @
      isEmpty: -> true

    class Wrong extends Bad
      constructor: (@error) ->
      inspect: -> "Wrong #{@error}"

    Nothing = new class extends Bad
      constructor: ->
      inspect: -> "Nothing"

`Event` class will be just a type alias for it.

    [Event, Fire, Error, Stop] = [Maybe, Just, Wrong, Nothing]
    toEvent = (x) -> if x instanceof Event then x else new Fire x
    toError = (x) -> if x instanceof Event then x else new Error x

Observable
----------

The point is that we can abstract from `Stream` and `Box` and define a common
behavior, calling it `Observable`.

Class `Observable` will be determined via a `subscribe` function. This
function should receive a subscriber or sink function as an argument and
call it whenever event is fired. This enables push semantics for `Stream`
and `Box`.

There are two ways to unsubscribe. First is to call function that subscribe
returns. Second is return `Reply.stop` from event listener.

    class Observable
      constructor: (subscribe)->
        @subscribe = @dispatched subscribe

`dispathed` is a function that makes `Observable` abstract and will hold the
actual implementation differences between `Stream` and `Box`. If you are
interested in `dispatched`, check it's implementations there.

      dispatched: fail

A basic ways to listen to Observable are `onValue` and `onError`. While
`subscribe` sends raw events, `onValue` unwraps them in case they hold values
and deliver them to the subscriber.

      onValue: (f) ->
        @subscribe (event) ->
          event.map((v)-> f(v)).getOrElse(Reply.more)

`onError` does roughly the same as `onValue`, but is selecting errors and
unwraps them.

      onError: (f) ->
        @subscribe (event) ->
          if event instanceof Error
            f event.error
          else
            Reply.more

We can now define basic transforms. Start with `map` and `filter`. We can
see common pattern there, it's abstracted in `withHandler`.

      withHandler: (handler)->
        new @constructor @dispatched(@subscribe, handler)

      map: (f)->
        @withHandler (event)-> @push event.map(f)

      filter: (f)->
        @withHandler (event)-> if event.test(f) then @push event else Reply.more

A useful combinator is `recover`, with will turn errors into regular
events using transform function.

      recover: (f)->
        @withHandler (event) ->
          if event instanceof Error
            @push new Fire f(event.error)
          else
            @push event

The most powerful combinator in our case is `flatMap`. It accepts a function
that turns each of the values in observable to a new observable. We then return
a new Observable that will combine them.

The first way to combine them is to just collect all the events from the
spawned childen. This matches the semantics of `Stream` and will allow us to
produce `merge`.

Another way to combine events is to unsubscribe all the existing children, when
a new event occurs on root, then spawn a new one and just listen to it. You can
think of it as swiching from one observable to another one. This matches the
semantics of `Box` and will allow us to produce `zip`.

      flatMapGeneric: (f, lastOnly) ->
        root = this
        new @constructor (sink) ->
          children = []
          rootStop = false
          unsubRoot = ->
          unsubChildren = ->
            unsubChild() for unsubChild in children
            children = []
          unbind = ->
            unsubChildren()
            unsubRoot()
          checkStop = ->
            if rootStop and (children.length == 0)
              sink Stop
          spawner = (event) ->
            if event == Stop
              rootStop = true
              checkStop()
            else
              unsubChildren() if lastOnly
              if event instanceof Error
                sink event
              else
                child = f event.value
                unsubChild = undefined
                childStopped = false
                removeChild = ->
                  remove(unsubChild, children) if unsubChild?
                  checkStop()
                handler = (event) ->
                  if event == Stop
                    removeChild()
                    childStopped = true
                    Reply.stop
                  else
                    tap sink(event), (reply)->
                      unbind() if reply == Reply.stop
                unsubChild = child.subscribe handler
                children.push unsubChild if not childStopped
          unsubRoot = root.subscribe(spawner)
          unbind

      flatMapAll: (f)-> @flatMapGeneric(f, false)
      flatMapLast: (f)-> @flatMapGeneric(f, true)

We can also define `skipDuplicates` which is extremely useful.

      withStateMachine: (initState, f) ->
        state = initState
        @withHandler (event) ->
          [newState, outputs] = f(state, event)
          state = newState
          stopped = any outputs,
                    (output)=> @push(output) == Reply.stop
          if stopped then Reply.stop else Reply.more

      skipDuplicates: (isEqual = (a, b) -> a is b) ->
        @withStateMachine Nothing, (prev, event) ->
          event.map((v)->
            if prev == Nothing || !prev.test((p)-> isEqual(v, p))
              [new Just(v), [event]]
            else
              [prev, []]
          ).getOrElse [prev, [event]]

From `withStateMachine` we can easily define `scan`:

      scan: (initState, f) ->
        @withStateMachine initState, (acc, event)->
          newAcc = event.map((v)->f(acc, v)).getOrElse(acc)
          [newAcc, [toEvent newAcc]]

Always good in UI there is an option to `debounce`:

      debounce: (delay)->
        @flatMapLast (value)=>
          @constructor.later delay, value

Let's do `take` and `takeWhile`:

      take: (n)->
        return @constructor.nothing() if n <= 0
        @withHandler (event) ->
          unless event instanceof Fire
            @push event
          else
            n--
            if n > 0
              @push event
            else
              @push event if n == 0
              @push Stop
              Reply.stop

      takeWhile: (f)->
        @withHandler (event) ->
          if event.test(f)
            @push event
          else
            @push Stop
            Reply.stop

`takeUntil` is going to be slightly more complicated - it's going to listen to
one stream till an event on another appears. A very useful one:

      takeUntil: (other)->
        source = this
        stopper = other.changes()
        new @constructor (sink)->
          unsubSource = ->
          unsubStopper = ->
          unbind = ->
            unsubSource()
            unsubStopper()

          transport = (event)->
            sink event
            unbind() if event == Stop
          watcher = (event)->
            sink Stop
            unbind()

          unsubSource = source.subscribe(transport)
          unsubStopper = stopper.subscribe(watcher)
          unbind

A helper method for boolean algebra (others are map2 based methods and so are
just applicable to box):

      not: -> @map (x)-> !x

How to build observables

------------------------

The basic ways to build an observable are `nothing`, `unit` and `error`. In
`Stream` semantics they mean `never`, `once` and `error`, in `Box` semantics
they mean `empty`, `always` and `error`. We won't create the aliases and give
these names to get you the feel of what they mean.

      @fromList: (values, wrapper = toEvent)->
        new @ (sink) ->
          sink event for event in map wrapper, values
          sink Stop

      @nothing: -> @fromList []
      @unit: (value)-> @fromList [value]
      @error: (value)-> @fromList [value], toError

`fromBinder` just adds a syntax sugar for us to easily define more
sophisticated constructors.

      @fromBinder: (binder, transform = id) ->
        new @ (sink) ->
          unbinder = binder (args...) ->
            events = toArray transform args...
            for event in map toEvent, events
              tap sink(event), (reply)->
                unbinder() if event == Stop or reply == Reply.stop

`poll` polls a function within given interval.

      @poll: (delay, poll) ->
        @fromBinder (handler) ->
          i = setInterval(handler, delay)
          -> clearInterval(i)
        , poll

`interval` and `later` send a fixed list of events or one event
respectively within given interval.

      @interval: (delay, list)->
        index = 0
        @poll delay, ->
          value = list[index++]
          if index < list.length
            value
          else if index == list.length
            [value, Stop]
          else
            Stop

      @later: (delay, value)->
        @interval(delay, [value])

Let's also define a function that works on promises, e.g., ajax. The
resource releasing here for ajax is abort. We should also handle promise
errors here. In a transform function we attach end to our stream.

      @fromPromise: (promise) ->
        @fromBinder (handler) ->
          promise.then handler, (e) ->
            handler new Error e
          -> promise.abort?()
        , (value) -> [value, Stop]

Finally let's define the way to receive events from DOM objects. We'll do
it assuming we're called in jQuery/Zepto fashion.

We allow to override `transform` - by default it'll take the first
argument, which is usually a jQuery event. We use `on` to subscribe and
`off` to unsubscribe.

      @fromDOM: (element, event, selector, transform) ->
        [transform, selector] = [selector, null] if isFunction(selector)

        @fromBinder (handler) =>
          element.on(event, selector, handler)
          => element.off(event, selector, handler)
        , transform

Stream
------

Class `Stream` represents a disrete sequence of values, coupled with time.  So
it uses the appropriate dispatcher to do it.

`Dispatcher` activates the listeners when a first sink is added and then just
adds them. On each event it just pushes it to all sinks.

    class StreamDispatcher
      constructor: (subscribe, handler) ->
        subscribe ?= (event) ->
        sinks = []
        @push = (event) =>
          for sink in sinks by -1
            tap sink(event), (reply)->
              remove sink, sinks if reply == Reply.stop
        handler ?= (event) -> @push event
        @handler = (event) => handler.apply(this, [event])
        @subscribe = (sink) =>
          sinks.push(sink)
          unsubSelf = subscribe @handler if sinks.length == 1
          ->
            remove sink, sinks
            unsubSelf?() unless any sinks

To have `Stream` class we just need to override abstract `dispatched` method
from the base class to use `StreamDispatcher`.

    class Stream extends Observable
      dispatched: (subscribe, handler)->
        new StreamDispatcher(subscribe, handler).subscribe

For this class we can have `flatMap` aka `bind`. In our case it's `flatMapAll`.

      flatMap: (args...)-> @flatMapAll(args...)

Having this we can easily have `merge`.

      merge: (others...)->
        Stream.fromList(map method("changes"), [@, others...]).flatten()
      flatten: -> @flatMap(id)

Using Stream when we need Box
-----------------------------

To make it transparent for a user, is this stream or box, we proxy the box
methods to box. First we define a conversion method with an optional starting
value.

      box: (initial = Nothing)->
        initial = toMaybe(initial)
        new Box (sink)=>
          sink initial unless initial.isEmpty()
          @subscribe (event)-> sink event
      changes: -> @

We could also define a new stream with initial value merged to the beginning,
but the current code is simple enough.

All proxy methods are trivial.

      zipWith: (others..., f)-> @box().zipWith(others..., f)
      and: (others...)-> @box().and(others...)
      or: (others...)-> @box().or(others...)
      not: -> @box().not()

Box
---

Class `Box` represents continuous value that changes with time. So we need a
slightly tweaked dispatcher. The difference is that it holds the current
value and sends it to each new subscriber. Another difference is that even when
the Box is ended, it still sends the last value and then immediately sends stop

    class BoxDispatcher extends StreamDispatcher
      constructor: (subscribe, handler) ->
        super subscribe, handler
        current = Nothing
        push = @push
        subscribe = @subscribe
        stopped = false

        @push = (event) =>
          event.map((x) -> current = new Just x)
          stopped = true if event == Stop
          push.apply(this, [event])
        @subscribe = (sink) =>
          reply = current.map((v)-> sink new Fire v)
          if reply.getOrElse(Reply.more) == Reply.stop
            nop
          else if stopped
            sink Stop
            nop
          else
            subscribe.apply(@, [sink])

Now class `Box` is going to use that dispatcher.

    class Box extends Observable
      dispatched: (subscribe, handler)->
        new BoxDispatcher(subscribe, handler).subscribe

For this class we can have `flatMap` aka `bind`. In our case it's `flatMapLast`.

      flatMap: (args...)-> @flatMapLast(args...)

With this `flatMap` we can define a glorious `map2`, also known as `zipWith`
for two boxes.

      map2: (other, f)->
        @flatMap (x)-> other.box().map (y)-> f(x, y)

Having this, `zipWith` is easy.

      @sequence: (boxes)->
        foldl boxes, @unit([]), (acc, box)->
          acc.map2 box, (memo, value)-> append memo, value
      @zipWith: (boxes, f)->
        @sequence(boxes).map uncurry f
      zipWith: (others..., f)->
        Box.zipWith [@, others...], f

`zip` method is it just sugar for the `sequence`.

      zip: (boxes...)-> Box.sequence([@, boxes...])

Helpful would be to define boolean algebra over boxes. `not` is defined on
`Observable`.

      and: (others...)-> @zipWith others..., (a, b)-> a && b
      or: (others...)-> @zipWith others..., (a, b)-> a || b

An interesting `sampledBy` function should take a property and stream it's
value when sampler pops:

      sampledBy: (sampler)->
        sampler.flatMap(=> @take(1)).changes()

Using Box when we need Stream
-----------------------------

To convert `Box` into `Stream` we take it's changes.

      changes: ->
        new Stream (sink)=>
          @subscribe (event)-> sink event
      box: -> @

Here are the proxy methods.

      merge: (others...)-> @changes().merge(others...)

Helpers
-------

Pretty trivial special values to return from event listeners.

    Reply =
      stop: "<stop>"
      more: "<more>"

We need some simple helper functions.

    empty = (xs)-> xs.length == 0
    method = (meth)-> (obj)-> obj[meth]()
    nop = ->
    id = (x)-> x
    fail = -> throw "method not implemented"
    head = (xs) -> xs[0]
    tail = (xs) -> xs[1...xs.length]
    uncurry = (f) -> (args)-> f(args...)
    map = (f, xs) -> f(x) for x in xs
    foldl = (xs, seed, f) ->
      for x in xs
        seed = f(seed, x)
      seed
    tap = (x, f) ->
      f(x)
      x
    remove = (x, xs) ->
      i = xs.indexOf(x)
      xs.splice(i, 1) if i >= 0
    all = (xs, f = id) ->
      for x in xs
        return false if not f(x)
      return true
    any = (xs, f = id) ->
      for x in xs
        return true if f(x)
      return false
    copyArray = (xs)-> xs.slice()
    append = (xs, x)-> tap copyArray(xs), (copy)-> copy.push x
    isFunction = (f) -> typeof f == "function"
    toArray = (x) -> if x instanceof Array then x else [x]
    toMaybe = (x) ->
      if x instanceof Maybe then x else new Just x

Exports
-------

We now need to make our objects usable outside.

    for name, value of {Stream, Box, Event, Fire, Error, Stop,
                                     Maybe, Just, Wrong, Nothing}
      Jnoid[name] = value

    if define?.amd
      define [], -> Jnoid
    else if module?.exports
      module.exports = Jnoid
    else
      @Jnoid = Jnoid

Conclusion
----------

Have fun!


Fix spacing on the app.coffee

Fix spacing on the app.coffee

Kickstart File
--------------
This file is responsible for starting up the entire server.

Lets start by initializing our basic express stuff.

    express = require 'express'
    app = express()

We need to set a default "views" directory. "/views" makes sense.

    app.set 'views', __dirname + '/views'

Right now, jade templates are the default.

    app.set 'view engine', 'jade'

Let's set the /public directory to be the only public directory for assets

    app.use(express.static(__dirname + '/public'))

This is our route-mapper

    require('./guts/routing')(app)

We will listen on the port 3000.

    app.listen(3000)


Fix logging comment.

Fix logging comment.

# Main Entry Point

We are using the [Express](http://expressjs.com) web framework for our server.

    express = require 'express'
    app = express()

Desmond Morris's [twitter](https://www.npmjs.com/package/twitter) library is the shizzle for talking to the Twitter API.  Don't forget to set your Twitter consumer key environment variables!

    twitter = require 'twitter'
    twitter = new twitter
      consumer_key: process.env.TWITTER_CONSUMER_KEY
      consumer_secret: process.env.TWITTER_CONSUMER_SECRET

We are using [Jade](http://jade-lang.com) to render the RSS.

    app.set 'view engine', 'jade'

Log requests.

    logger = require 'connect-logger'
    app.use logger()

## Routes

The first route gets the most recent tweets for a particular user.

    app.get '/user/:user', (req, res) ->
      opts =
        screen_name: req.params.user

      twitter.get '/statuses/user_timeline', opts, (err, body) ->
        if err
          return res.send 500, err

        res.render 'rss', { statuses: body }

The second route gets the most recent tweets based on a search term.

    app.get '/search/:term', (req, res) ->
      opts =
        q: req.params.term

      twitter.get '/search/tweets', opts, (err, body) ->
        if err
          return res.send 500, err

        res.render 'rss', body

## Startup

In dev, we listen on port 5000.  The port environment variable is set on common deployment sites like [Heroku](http://heroku.com/).

    port = process.env.PORT || 5000
    app.listen port
    console.log 'Server is listening on port ' + port

# Main Entry Point

We are using the [Express](http://expressjs.com) web framework for our server.

    express = require 'express'
    app = express()

Desmond Morris's [twitter](https://www.npmjs.com/package/twitter) library is the shizzle for talking to the Twitter API.  Don't forget to set your Twitter consumer key environment variables!

    twitter = require 'twitter'
    twitter = new twitter
      consumer_key: process.env.TWITTER_CONSUMER_KEY
      consumer_secret: process.env.TWITTER_CONSUMER_SECRET

We are using [Jade](http://jade-lang.com) to render the RSS.

    app.set 'view engine', 'jade'

If you've set the production variable, you get different logs.

    logger = require 'connect-logger'
    app.use logger()

## Routes

The first route gets the most recent tweets for a particular user.

    app.get '/user/:user', (req, res) ->
      opts =
        screen_name: req.params.user

      twitter.get '/statuses/user_timeline', opts, (err, body) ->
        if err
          return res.send 500, err

        res.render 'rss', { statuses: body }

The second route gets the most recent tweets based on a search term.

    app.get '/search/:term', (req, res) ->
      opts =
        q: req.params.term

      twitter.get '/search/tweets', opts, (err, body) ->
        if err
          return res.send 500, err

        res.render 'rss', body

## Startup

In dev, we listen on port 5000.  The port environment variable is set on common deployment sites like [Heroku](http://heroku.com/).

    port = process.env.PORT || 5000
    app.listen port
    console.log 'Server is listening on port ' + port


Remove reset method

Remove reset method

    Module = require '../../module'
    q      = require 'q'

    class PngRenderer extends Module
      deps: [ 'fs', 'canvas', 'path', 'config' ]
      pub:  [ 'render', 'flush' ]

      @draw_to: undefined
      @ctx:     undefined

      initialize: (params) =>
        deferred = q.defer()

        super()
          .then =>
            @initialize_drawing_context() unless PngRenderer.draw_to?

            deferred.resolve @

        deferred.promise

      initialize_drawing_context: =>
        width  = @config.width  * @config.grid[0].length
        height = @config.height * @config.grid.length

        PngRenderer.draw_to = new @canvas width, height
        PngRenderer.ctx     = PngRenderer.draw_to.getContext '2d'

      render: (path) => @done @do_render path

      flush: (level) =>
        stream = @fs.createWriteStream @path.join __dirname, '..', '..', '..', 'output', "#{level}.png"

        for row, r in @config.grid
          for cell, c in @config.grid[r]
            @config.grid[r][c] = false

        stream.on 'finish', => @done 'Persisted', location: level

        PngRenderer.draw_to.createPNGStream().pipe stream

    module.exports = PngRenderer

    Module = require '../../module'
    q      = require 'q'

    class PngRenderer extends Module
      deps: [ 'fs', 'canvas', 'path', 'config' ]
      pub:  [ 'render', 'flush', 'reset' ]

      @draw_to: undefined
      @ctx:     undefined

      initialize: (params) =>
        deferred = q.defer()

        super()
          .then =>
            @initialize_drawing_context() unless PngRenderer.draw_to?

            deferred.resolve @

        deferred.promise

      initialize_drawing_context: =>
        width  = @config.width  * @config.grid[0].length
        height = @config.height * @config.grid.length

        PngRenderer.draw_to = new @canvas width, height
        PngRenderer.ctx     = PngRenderer.draw_to.getContext '2d'

      render: (path) => @done @do_render path

      flush: (level) =>
        stream = @fs.createWriteStream @path.join __dirname, '..', '..', '..', 'output', "#{level}.png"

        for row, r in @config.grid
          for cell, c in @config.grid[r]
            @config.grid[r][c] = false

        stream.on 'finish', => @done 'Persisted', location: level

        PngRenderer.draw_to.createPNGStream().pipe stream

      reset: => @done @initialize_drawing_context()

    module.exports = PngRenderer


Split l & levels into seperate parameters

-l is now the number of auto-named levels to generate
--levels is now an array of named levels to generate

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] name1 name2 ...'
      .example '$0',
        'Creates a 50 x 15 level with 16 x 14 cells and an auto-generated name'
      .example '$0 -vvvvvvvv',
        "Create a 50 x 15 level with 16 x 14 cells, an auto-generated name, and
        logging set to verbosity level 8 (max)"
      .example '$0 -w 20 -h 20',
        'Creates a 50 x 15 level with 40 X 40 cells & an auto-generated name'
      .example '$0 -w 10 -h 10 -x 4',
        'Creates a 50 x 15 level with 40 x 40 cells and an auto-generated name'
      .example '$0 lvl1 lvl2',
        'Creates two levels, lvl1 & lvl2, each 50 X 15 with 16 x 14 cells'
      .count 'verbosity'
      .alias 'v', 'verbosity'
      .describe 'v', 'Level of logging verbosity: 1 - 8'
      .alias 'r', 'rows'
      .describe 'r', 'Number of rows for map'
      .alias 'c', 'columns'
      .describe 'c', 'Number of columns for map'
      .alias 'w', 'width'
      .describe 'w', 'Width of a grid cell'
      .alias 'h', 'height'
      .describe 'h', 'Height of a grid cell'
      .alias 'x', 'multiplier'
      .describe 'x', 'Increase cell size by x times'
      .number 'l'
      .describe 'l', 'Number of auto-named levels to create'
      .array 'levels'
      .describe 'levels', 'Array of named levels to create'
      .alias 'p', 'pipeline'
      .describe 'p', 'The steps of the render pipleline'
      .conflicts 'levels', 'l'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      8
        height:     7
        multiplier: 4
        levels:     1
        pipeline:   'png_blocks,png_walls,png_step_count'
      .help 'help'
      .epilogue '© Bryan Maynard 2016'
      .argv

    module.exports = require 'yargs'
      .usage 'Usage: $0 [options] name1 name2 ...'
      .example '$0',
        'Creates a 50 x 15 level with 16 x 14 cells and an auto-generated name'
      .example '$0 -vvvvvvvv',
        "Create a 50 x 15 level with 16 x 14 cells, an auto-generated name, and
        logging set to verbosity level 8 (max)"
      .example '$0 -w 20 -h 20',
        'Creates a 50 x 15 level with 40 X 40 cells & an auto-generated name'
      .example '$0 -w 10 -h 10 -x 4',
        'Creates a 50 x 15 level with 40 x 40 cells and an auto-generated name'
      .example '$0 lvl1 lvl2',
        'Creates two levels, lvl1 & lvl2, each 50 X 15 with 16 x 14 cells'
      .count 'verbosity'
      .alias 'v', 'verbosity'
      .describe 'v', 'Level of logging verbosity: 1 - 8'
      .alias 'r', 'rows'
      .describe 'r', 'Number of rows for map'
      .alias 'c', 'columns'
      .describe 'c', 'Number of columns for map'
      .alias 'w', 'width'
      .describe 'w', 'Width of a grid cell'
      .alias 'h', 'height'
      .describe 'h', 'Height of a grid cell'
      .alias 'x', 'multiplier'
      .describe 'x', 'Increase cell size by x times'
      .alias 'l', 'levels'
      .describe 'l', 'Number of auto-named levels to create'
      .alias 'p', 'pipeline'
      .describe 'p', 'The steps of the render pipleline'
      .default
        verbosity:  3
        rows:       15
        columns:    50
        width:      8
        height:     7
        multiplier: 4
        levels:     1
        pipeline:   'png_blocks,png_walls,png_step_count'
      .help 'help'
      .epilogue '© Bryan Maynard 2016'
      .argv


value search list

value search list

Copyright 2014 - 2015
Author: Varuna Jayasiri http://blog.varunajayasiri.com

#List

    Mod.require 'Models.Properties',
     'Models.Property.Base'
     'Weya.Base'
     'Weya'
     (PROPERTIES, Base, WeyaBase, Weya) ->

Class

      class Value extends Base
       @extend()

       @default 'value', (str) ->
        if (typeof str) isnt 'string'
         throw new Error "Exected string: #{typeof str}, #{str}"
        return str

       @default 'string', (value) -> "#{str}"

       @default 'rows', 1
       @default 'columns', 20

       @default 'valid', (str) ->
        if (typeof str) isnt 'string'
         return false
        else
         return true

       @default 'search', (str) -> null

       @default 'default', -> ''

       @default 'isDefault', (value) -> (value is @schema.default())

       parse: (data) ->
        r = super data
        return r unless r is true
        if not @schema.valid data
         return @error 'invalid'

        res =
         score: 1
         errors: []
         value: @schema.value data

        return res

       toJSON: (value) -> value
       toJSONFull: (value) -> value

       edit: (elem, value, changed) ->
        new Edit this, elem, value, changed

Edit

      class Edit extends WeyaBase
       @extend()

       @initialize (property, elem, value, changed) ->
        @property = property
        @elems =
         parent: elem
        @value = value
        @onChanged = changed
        @render()

       render: ->
        schema = @property.schema
        Weya elem: @elems.parent, context: this, ->
         if schema.rows is 1
          @$.elems.input = @input '.value',
           type: 'text'
           style:
            width: "#{2 + Math.round schema.columns * 7.25}px"
         else
          @$.elems.input = @textarea '.value',
           rows: schema.rows
           columns: schema.columns
           style:
            width: "#{2 + Math.round schema.columns * 7.25}px"
            height: "#{Math.round schema.rows * 18}px"

         @$.elems.search = @div '.search', style: {display: 'none'}

        @elems.input.value = @value
        @elems.input.addEventListener "input", @on.change
        @elems.input.addEventListener "focus", @on.focus
        @elems.search.addEventListener 'click', @on.searchClick

       search: ->
        value = @elems.input.value
        results = @property.schema.search.call @property, value
        return if not results?
        return if not Array.isArray results

        if results.length is 0
         @elems.search.style.display = 'none'
         return

        @elems.search.style.display = 'block'
        @elems.search.innerHTML = ''
        Weya elem: @elems.search, ->
         for r in results
          e = @div r
          e._result = r

       @listen 'searchClick', (e) ->
        n = e.target
        result = null
        while n? and n isnt @elems.search
         if n._result
          result = n._result
          break
         n = n.parentNode

        return if not result?
        @elems.input.value = result
        @on.change()

       @listen 'focus', (e) ->
        @search()

       @listen 'change', (e) ->
        @search()
        value = @elems.input.value
        if not @property.schema.valid.call @property, value
         @elems.input.classList.add 'invalid'
        else
         @elems.input.classList.remove 'invalid'
         value = @property.schema.value.call this, value
         @onChanged value, true

      PROPERTIES.register 'value', Value

Copyright 2014 - 2015
Author: Varuna Jayasiri http://blog.varunajayasiri.com

#List

    Mod.require 'Models.Properties',
     'Models.Property.Base'
     'Weya.Base'
     'Weya'
     (PROPERTIES, Base, WeyaBase, Weya) ->

Class

      class Value extends Base
       @extend()

       @default 'value', (str) ->
        if (typeof str) isnt 'string'
         throw new Error "Exected string: #{typeof str}, #{str}"
        return str

       @default 'string', (value) -> "#{str}"

       @default 'rows', 1
       @default 'columns', 20

       @default 'valid', (str) ->
        if (typeof str) isnt 'string'
         return false
        else
         return true

       @default 'search', (str) ->
        if (typeof str) isnt 'string'
         throw new Error "Exected string: #{typeof str}, #{str}"
        return str

       @default 'default', -> ''

       @default 'isDefault', (value) -> (value is @schema.default())

       parse: (data) ->
        r = super data
        return r unless r is true
        if not @schema.valid data
         return @error 'invalid'

        res =
         score: 1
         errors: []
         value: @schema.value data

        return res

       toJSON: (value) -> value
       toJSONFull: (value) -> value

       edit: (elem, value, changed) ->
        new Edit this, elem, value, changed

Edit

      class Edit extends WeyaBase
       @extend()

       @initialize (property, elem, value, changed) ->
        @property = property
        @elems =
         parent: elem
        @value = value
        @onChanged = changed
        @render()

       render: ->
        schema = @property.schema
        Weya elem: @elems.parent, context: this, ->
         if schema.rows is 1
          @$.elems.input = @input '.value',
           type: 'text'
           style:
            width: "#{2 + Math.round schema.columns * 7.25}px"
         else
          @$.elems.input = @textarea '.value',
           rows: schema.rows
           columns: schema.columns
           style:
            width: "#{2 + Math.round schema.columns * 7.25}px"
            height: "#{Math.round schema.rows * 18}px"
        @elems.input.value = @value
        @elems.input.addEventListener "input", @on.change

       @listen 'change', (e) ->
        #TODO validate
        value = @elems.input.value
        if not @property.schema.valid.call @property, value
         @elems.input.classList.add 'invalid'
        else
         @elems.input.classList.remove 'invalid'
         value = @property.schema.value.call this, value
         @onChanged value, true

      PROPERTIES.register 'value', Value


Copy comments over to document @layout

Copy comments over to document @layout

# Batman.App

`Batman.App` is the central object in any Batman application. It manages the routing table and the current URL parameters, as well as the initial start of the application. It should also be used as a namespace for models and views so that other objects can find them. Batman assumes that there will only ever be one `Batman.App` in use at once.

## Batman.currentApp

A Batman-wide reference to the currently running `Batman.App`.

## @run() : App

`App.run` is the central entry point for a Batman application. `@run` takes these steps to initialize a Batman application:

 1. Instantiate a `Dispatcher`, an internal object for mananging action dispatch to controllers.
 2. Instantiate a `Navigator`, an internal object for managing the URL via pushState or hashbangs.
 3. Instantiate the `layout` view according to the `layout` property on the `App`.
 4. Wait for the layout view to fire it's `ready` event.
 5. Start the first action dispatch by telling the `Navigator` to begin monitoring the URL.

_Note_: `@run` emits the `run` class event on the `App`, but not necessarily as soon as `@run` is called. Because the `layout` View renders asynchronously and may need to fetch other components, the `run` event can and often does fire long after `@run` is called. If you need to execute code as soon as the `App` has started running, add a listener to the `run` event on the `App` class. If you need to execute code as soon as the layout has rendered, you can use the `ready` event on the `App` class.

`@run` can be called before or on the `load` DOMEvent of the window. `@run` will return the App if the commencement was successful and complete, or `false` if the App must wait for the `layout` to render or if the `App` has already run.

#### starting an application with DOMEvents
```coffeescript
window.addEventListener 'load', ->
  MyApp.run()
```

#### starting an application with jQuery
```coffeescript
$ ->
  MyApp.run()
```

## @stop() : App

`@stop` stops the `App` it's called upon. The URL will stop being monitored and no more actions will be dispatched. In usual Batman development you shouldn't have to call this.

## @routes

`@routes` is a class level property referencing the root level `NamedRouteQuery` which allows for binding to routes on objects. See `data-route` bindings for more information.

## @controllers

`@controllers` is a class level property containing the singleton `Batman.Controller` instances for each subclass in the application. This `controllers` directory puts these instances at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`. `@controllers` ideally should never be bound to, but it is very useful for debugging in the console and other such workarounds.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

## @layout

`@layout` is the base view that other views can be yielded into. The
default behavior is that when `app.run()` is called, a new view will
be created for the layout using the `document` node as its content.
Use `MyApp.layout = null` to turn off the default behavior.

## @currentParams
## @paramsManager
## @paramsPusher

## 'run' class event

The `run` class event is fired once the app has run. This indeterminately but often happens before the app's layout has finished rendering.

## 'ready' class event

The `ready` class event is fired once the app's layout is rendered.

# Batman.App Routing

The `Batman` routing DSL is similar to Rails 3's routing DSL. It is oriented around the notion of a resource:

## @resources(resourceName : String[, otherResourceNames... : String][, options : Object][, scopedCallback : Function])

## @member
## @collection
## @route
## @root

# Batman.App

`Batman.App` is the central object in any Batman application. It manages the routing table and the current URL parameters, as well as the initial start of the application. It should also be used as a namespace for models and views so that other objects can find them. Batman assumes that there will only ever be one `Batman.App` in use at once.

## Batman.currentApp

A Batman-wide reference to the currently running `Batman.App`.

## @run() : App

`App.run` is the central entry point for a Batman application. `@run` takes these steps to initialize a Batman application:

 1. Instantiate a `Dispatcher`, an internal object for mananging action dispatch to controllers.
 2. Instantiate a `Navigator`, an internal object for managing the URL via pushState or hashbangs.
 3. Instantiate the `layout` view according to the `layout` property on the `App`.
 4. Wait for the layout view to fire it's `ready` event.
 5. Start the first action dispatch by telling the `Navigator` to begin monitoring the URL.

_Note_: `@run` emits the `run` class event on the `App`, but not necessarily as soon as `@run` is called. Because the `layout` View renders asynchronously and may need to fetch other components, the `run` event can and often does fire long after `@run` is called. If you need to execute code as soon as the `App` has started running, add a listener to the `run` event on the `App` class. If you need to execute code as soon as the layout has rendered, you can use the `ready` event on the `App` class.

`@run` can be called before or on the `load` DOMEvent of the window. `@run` will return the App if the commencement was successful and complete, or `false` if the App must wait for the `layout` to render or if the `App` has already run.

#### starting an application with DOMEvents
```coffeescript
window.addEventListener 'load', ->
  MyApp.run()
```

#### starting an application with jQuery
```coffeescript
$ ->
  MyApp.run()
```

## @stop() : App

`@stop` stops the `App` it's called upon. The URL will stop being monitored and no more actions will be dispatched. In usual Batman development you shouldn't have to call this.

## @routes

`@routes` is a class level property referencing the root level `NamedRouteQuery` which allows for binding to routes on objects. See `data-route` bindings for more information.

## @controllers

`@controllers` is a class level property containing the singleton `Batman.Controller` instances for each subclass in the application. This `controllers` directory puts these instances at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`. `@controllers` ideally should never be bound to, but it is very useful for debugging in the console and other such workarounds.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

## @layout

## @currentParams
## @paramsManager
## @paramsPusher

## 'run' class event

The `run` class event is fired once the app has run. This indeterminately but often happens before the app's layout has finished rendering.

## 'ready' class event

The `ready` class event is fired once the app's layout is rendered.

# Batman.App Routing

The `Batman` routing DSL is similar to Rails 3's routing DSL. It is oriented around the notion of a resource:

## @resources(resourceName : String[, otherResourceNames... : String][, options : Object][, scopedCallback : Function])

## @member
## @collection
## @route
## @root


Added currentParams docs

Added currentParams docs

# /api/App Components/Batman.App

`Batman.App` manages routing and action dispatching, as well as the initial start of the application. It is also the namespace for all `Batman.Model`s, `Batman.Controller`s, and `Batman.View`s. Only one `Batman.App` can be running on a page.

A batman.js application extends `Batman.App`. It is never instantiated and it is started by calling `run`.

```coffeescript
class @MyApp extends Batman.App
  @root 'blogPosts#index'

  @on 'run', -> alert("Welcome to my blog!")

class MyApp.BlogPostsController extends Batman.Controller
  index: -> @set('blogPosts', MyApp.BlogPost.get('all'))

class MyApp.BlogPost extends Batman.Model
  # model definition ...

MyApp.run()
```

See [`Batman.App` routing](/docs/api/batman.app_routing.html) for information about batman.js routing.

## @%current : App

The currently-running `Batman.App`. Also available at `Batman.currentApp`.

## @run()

Initializes the `Batman.App` class by:

- Closing any already-running apps
- Creates its [`dispatcher`](/docs/api/batman.app.html#class_accessor_navigator) and [`navigator`](/docs/api/batman.app.html#class_accessor_navigator) and starts the navigator.
- Instantiating the `layout` view according to the `layout` property on the `App`
- Emitting `run`

`@run` can be called before or on the `load` DOMEvent of the window.

```coffeescript
# JavaScript:
window.addEventListener 'load', ->
  MyApp.run()
# or jQuery:
$ ->
  MyApp.run()
```

## @stop() : App

Stops the `App`. The URL will stop being monitored and no more actions will be dispatched. You generally shouldn't have to call this.

## @%routes : NamedRouteQuery

Returns the `Batman.NamedRouteQuery` which allows for binding to routes on objects. See the [`data-route` binding](batman.view_bindings.html#data-route) for more information.

## @%controllers : ControllerDirectory

Returns the `Batman.ControllerDirectory` for application. `Batman.Controller` instances are accessible at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

_Note:_ `@controllers` should not be observed, but it is very useful for debugging.

## @.layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any `data-*` attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @%currentURL : String

The request path relative to `Batman.config.pathToApp`, including query string.

## @%currentParams : Batman.Params

Returns the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). It includes named parameters (eg `id` from `/items/:id`), query string parameters (eg `key` of `?key=value`).

`currentParams` also offers a way to change the current request URL's parameters without refreshing or reloading anything on the page. This way you can influence data on the page and allow your users to get the same data on hard refreshes. Here's an example:

    Batman.currentApp.get('currentParams.url').update(page: 5)

It will even update the URL match a defined route if found:

    Batman.currentApp.get('currentParams.url').update(action: show, id: 6) # /items/6
    Batman.currentApp.get('currentParams.url').update(page: 5) # /items/page/5

## @%currentRoute : ControllerActionRoute

The `Batman.ControllerActionRoute` for the current route, which exposes routing information such as `controller` and `action`.

## @%navigator : Navigator

The `App`'s `Batman.Navigator` instance.

## @%dispatcher : Dispatcher
## @%routeMap : RouteMap
## @%routeMapBuilder : RouteMapBuilder
## @paramsManager : ParamsReplacer
## @paramsPusher : ParamsPusher

## 'run' class event

`run` is fired after a successful `run`.

## 'ready' class event

`ready` is fired after the app's layout is rendered.

# /api/App Components/Batman.App

`Batman.App` manages routing and action dispatching, as well as the initial start of the application. It is also the namespace for all `Batman.Model`s, `Batman.Controller`s, and `Batman.View`s. Only one `Batman.App` can be running on a page.

A batman.js application extends `Batman.App`. It is never instantiated and it is started by calling `run`.

```coffeescript
class @MyApp extends Batman.App
  @root 'blogPosts#index'

  @on 'run', -> alert("Welcome to my blog!")

class MyApp.BlogPostsController extends Batman.Controller
  index: -> @set('blogPosts', MyApp.BlogPost.get('all'))

class MyApp.BlogPost extends Batman.Model
  # model definition ...

MyApp.run()
```

See [`Batman.App` routing](/docs/api/batman.app_routing.html) for information about batman.js routing.

## @%current : App

The currently-running `Batman.App`. Also available at `Batman.currentApp`.

## @run()

Initializes the `Batman.App` class by:

- Closing any already-running apps
- Creates its [`dispatcher`](/docs/api/batman.app.html#class_accessor_navigator) and [`navigator`](/docs/api/batman.app.html#class_accessor_navigator) and starts the navigator.
- Instantiating the `layout` view according to the `layout` property on the `App`
- Emitting `run`

`@run` can be called before or on the `load` DOMEvent of the window.

```coffeescript
# JavaScript:
window.addEventListener 'load', ->
  MyApp.run()
# or jQuery:
$ ->
  MyApp.run()
```

## @stop() : App

Stops the `App`. The URL will stop being monitored and no more actions will be dispatched. You generally shouldn't have to call this.

## @%routes : NamedRouteQuery

Returns the `Batman.NamedRouteQuery` which allows for binding to routes on objects. See the [`data-route` binding](batman.view_bindings.html#data-route) for more information.

## @%controllers : ControllerDirectory

Returns the `Batman.ControllerDirectory` for application. `Batman.Controller` instances are accessible at the lowercase name of the controller. For example, the `TodosController` would be found at `controllers.todos`.

    test "App.controllers references a directory of controller instances", ->
      class Alfred extends Batman.App
      class Alfred.TodosController extends Batman.Controller
      controller = Alfred.get('controllers.todos')
      equal Batman._functionName(controller.constructor), "TodosController"

    test "Multi-word controller names have a lowercase first letter", ->
      class Alfred extends Batman.App
      class Alfred.ReminderEmailsController extends Batman.Controller
      controller = Alfred.get('controllers.reminderEmails')
      equal Batman._functionName(controller.constructor), "ReminderEmailsController"

_Note:_ `@controllers` should not be observed, but it is very useful for debugging.

## @.layout

`@layout` is the base view of the entire view hierarchy. By default, it will parse any `data-*` attributes in the entire document, excluding any `data-yield`'s, when `App.run()` is called. Use `MyApp.layout = null` to disable the creation of this default view.

## @%currentURL : String

The request path relative to `Batman.config.pathToApp`, including query string.

## @%currentParams : Hash

Returns the URL parameters for the current request, including the path relative to the app's base path (`Batman.config.pathToApp`). It includes named parameters (eg `id` from `/items/:id`), query string parameters (eg `key` of `?key=value`).

## @%currentRoute : ControllerActionRoute

The `Batman.ControllerActionRoute` for the current route, which exposes routing information such as `controller` and `action`.

## @%navigator : Navigator

The `App`'s `Batman.Navigator` instance.

## @%dispatcher : Dispatcher
## @%routeMap : RouteMap
## @%routeMapBuilder : RouteMapBuilder
## @paramsManager : ParamsReplacer
## @paramsPusher : ParamsPusher

## 'run' class event

`run` is fired after a successful `run`.

## 'ready' class event

`ready` is fired after the app's layout is rendered.