A smarter client-side for ClojureScript
Switch branches/tags
Nothing to show
Pull request Compare This branch is 8 commits behind ohpauleez:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



A smarter client-side in ClojureScript

###Shoreleave is a collection of integrated libraries that focuses on:

  • Security
  • Idiomatic interfaces
  • Common client-side strategies
  • HTML5 capabilities
  • ClojureScript's advantages

Installing and using

You can pull all the pieces of Shoreleave into your project by adding the following to your project.clj

(defproject ...
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [shoreleave "0.2.2-SNAPSHOT"]
                 [shoreleave/shoreleave-remote-noir "0.2.2-SNAPSHOT"]

Individual utilies can be pulled in with [shoreleave/UTILITY "0.2.2-SNAPSHOT"]. See the specific repo/artifact names below.


Shoreleave has support for the following:

A remotes package

Shoreleave's remotes package includes XHR, Pooled-XHR, JSONP, and HTTP-RPC capabilities.

CSRF protection is built in if your Clojure server is using the ring-anti-forgery middleware.

The HTTP-RPC allows for exposing a server-side namespace as a client-side API, via a single server-side call, remote-ns.

A typical Noir setup might look like:

(ns example
  (:require [example.api] ; You don't have to pull this in, but it is suggested
            [noir.shoreleave.rpc :as rpc]))

;; ...

;; The Base Web Server
;; ---------------------
;; Serve every view file found in `src/example/views`
(server/load-views "src/example/views/")

;; Remote Namespaces
;; -----------------
(rpc/remote-ns 'example.api :as "api")

;; Middleware
(server/add-middleware ring.middleware.gzip/wrap-gzip)
(server/add-middleware ring.middleware.file-info/wrap-file-info)
(server/add-middleware ring.middleware.anti-forgery/wrap-anti-forgery)

You can also define single "global" rpc functions:

(defremote ping []
    (println "Pinged by client!")
    "PONG - from the server"))

A pub/sub abstraction (and implementations)

Why would I ever want to use this?

Shoreleave's pub/sub system enables you to completely decouple parts of your app and declaratively bind them together. New features and functionalities can be built by composing pre-existing services/publishables.

Additionally you can express cross-cutting functionality (like logging or metrics reporting) as a service.

Reactive ClojureScript

This gives you the heart of Reactive JavaScript (RxJS), without the additional verbs (both a benefit and a tradeoff). It's often most beneficial to use DOM listeners as entry-points into the pub/sub system.

Shoreleave's pub/sub system is built upon two protocols: "brokers" and "publishables"

Out of the box, Shoreleave allows you to publish funtions, atoms, web workers, and anything that implements (str ...)/.toString, as topics. The simple pub/sub bus has little overhead but will only work in single document cases.

(In-progress) The cross document bus has a small amount of overhead, but allows you to publish and subscribe from/to functions that live in other web workers or windows (in-browser concurrency for "free").

Common client-side interactions

  • An idiomatic interface to cookies
  • An idiomatic interface to browser history (with extended support for HTML5 History API)
  • BlobBuilders and on-demand asset building
  • (Coming soon) An idiomatic interface to browser storage (Local Storage, Session Storage, and App Cache)
  • Common auxiliary functions out-of-the-box to handle query strings, browser-repl, hash strings, and CLJS/JS interop

Common external API support

Shoreleave has JSONP-wrapped support for external APIs including:

  • Google Maps
  • DuckDuckGo Zero-Click
  • (Coming soon) Wikipedia and Alpha

An enhanced ClojureScript experience

  • A Function object that supports metadata
  • The ability to create embedded web workers

Where's the code?

Shoreleave is a big project and has been split up into smaller pieces within the Shoreleave organization:

Plays well with others

Shoreleave makes no assumptions about other libraries you might be using in your app.

I have found it to pair particularly well with Enfocus

Examples and usage

Please the github wiki for examples of each library feature


Copyright (C) 2012 Paul deGrandis

Distributed under the Eclipse Public License, the same as Clojure.