A smarter client-side in ClojureScript
Shoreleave is a collection of integrated libraries that focuses on:
- 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
(defproject ... :dependencies [[org.clojure/clojure "1.4.0"] [shoreleave "0.2.2"] [shoreleave/shoreleave-remote-noir "0.2.2"] ... ] ... )
Individual utilies can be pulled in with
[shoreleave/UTILITY "0.2.2"]. See the specific repo/artifact names below.
Shoreleave has support for the following:
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
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,
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/activate-remotes!) (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  (do (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.
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.
simple pub/sub bus has very little overhead, but operates synchronously. You can trade-off some performance for an async bus, the
event pubsub bus.
(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").
In most cases, the simple bus is the best choice.
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
Functionobject 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:
- shoreleave-core - Marg docs
- shoreleave-browser - Marg docs
- shoreleave-pubsub - Marg docs
- shoreleave-remote - Marg docs
- shoreleave-remote-noir - Temp Marg docs
- shoreleave-services - Temp Marg docs
- shoreleave-worker - Marg docs
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 doc pages (ie: Marginalia docs) above for library specifics.
Google Group and General Help
There is a Shoreleave CLJS Google Group. Please feel free to post all questions and general comments there.
Additionally, you can ping
ohpauleez in #clojure on Freenode.
Copyright (C) 2012 Paul deGrandis
Distributed under the Eclipse Public License, the same as Clojure.