In addition to strings and keywords, functions as topics, allowing for a
pipeline-like binding to take place. For example:

(subscribe my-bus user-search render-search-results)

... where user-search is a function that returns some search results,
and render-search-results takes search data and renders it to the DOM.

When user-search is called, the results are automatically rendered to the DOM.
This frees the developer from having to liter DOM, view, and state logic
throughout the application. Shoreleave's pubsub allows you to bind together
pure functions to build out functionality.

Additionally, cross-cutting functionality (like logging) is more easily managed
through the pubsub system.

IPublishable

The second protocol is used to define things that can be published,
ie: things that be used as a topic.

Publishables are usually constructed as a decorator (which result in a
Function object containing metadata), or as an adapter to IWatchable interfaces.

A Publishable knows how to make a string-based topic of itself (topicify),
can tell if it has already been decorated (publishized?), and can generate
the decorator form that is bound to a bus (publishize)

Publishables

Shoreleave comes with out-of-the-box support for the most common
publishables

Functions and Function types

Functions need to be decorated (much like how memoize works).
This is now supported by CLJS core - ported from Shoreleave.

For example:

(def a-bus (simple-bus/bus))
(defn some-fn [] 5)
(def some-fn-p (publishize some-fn))
(defn another-fn [x] (inc x))
(def another-fn-p (publishize another-fn))
(subscribe a-bus another-fn-p some-fn-p) ;; some-fn-p will automatically publish its result to another-fn-p
;; Note that the subscribing function (or entity) doesn't need to be `publishize`
(some-fn) ;; This DOES NOT get sent to the bus
(some-fn-p) ;; The results of this call are published on the bus

Anything that is subscribed to some-fn-p will get the value 5 when the
function is called, as shown above.

Atoms

Atoms can also be topics. This is no different than watching the atom.

All subscribed functions will be passed a map: {:old some-val :new another-val}

Browser storages (localStorage and sessionStorage)

All storage systems behave exactly like an atom, as described above

WorkerFn

Embedded workers behave exactly like atoms, as described above

The default case

You can also use strings and keywords as topics (the most useful case for
cross-cutting functionality).

This is left in the code for historical reasons,
You can use it as an example on how to build custom
function decorators in ClojureScript, correctly use the Blob system,
generate new Object URLs, and how WebWorkers execute.