• Stars
    star
    127
  • Rank 282,790 (Top 6 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created over 12 years ago
  • Updated over 11 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A smarter client-side for ClojureScript

shoreleave

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.3.0"]
                 [shoreleave/shoreleave-remote-ring "0.3.0"]
                 ...
                 ]
...
)

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

Overview

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)
  • HTML Blob construction and on-demand asset building
  • An idiomatic interface to browser storage (Local Storage, Session Storage. App Cache coming soon)
  • Common auxiliary functions out-of-the-box to handle query strings, browser-repl, hash strings, and CLJS/JS interop
  • and more...

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. See shoreleave-baseline for anti-forgery details.

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 Compojure setup might look like:

(ns baseline.handler
  (:require [compojure.handler :as handler]
            [baseline.routes :as routes]
            [baseline.config :refer [config]]
            [ring.middleware.gzip]
            [ring.middleware.file-info]
            [ring.middleware.anti-forgery]
            [ring.middleware.session.cookie :refer [cookie-store]]
            [shoreleave.middleware.rpc]
            [hiccup.middleware]))

(def app routes/all-routes)

(defn get-handler [app]
  (-> app
    (shoreleave.middleware.rpc/wrap-rpc)
    (ring.middleware.anti-forgery/wrap-anti-forgery)
    (ring.middleware.gzip/wrap-gzip)
    (handler/site {:session {:cookie-name "baseline"
                             :store (cookie-store {:key (config :session-secret)})
                             ;:store (cookie-store)
                             :cookie-attrs {:max-age (config :session-max-age-seconds)
                                            :http-only true}}})
    (ring.middleware.file-info/wrap-file-info)
    (hiccup.middleware/wrap-base-url)))

(def war-handler (get-handler app))

With a routes file that might look like this:

(ns baseline.routes
  (:require [compojure.core :as c-core :refer [defroutes
                                               GET POST PUT DELETE
                                               HEAD OPTIONS PATCH
                                               ANY]]
            [compojure.route :as c-route]
            [shoreleave.middleware.rpc :refer [remote-ns]]
            ;; Controllers
            [baseline.controllers.site :as cont-site]
            ;; Public APIs
            [baseline.controllers.api]))

;; Remote APIs exposed
;; -------------------
(remote-ns 'baseline.controllers.api :as "api")

;; Controller routes, ROA oriented
;; -------------------------------
(defroutes site
  (GET "/" {session :session} (cont-site/index session))
  (GET "/test" [] (cont-site/test-shoreleave)))

;; Core system routes
;; ------------------
(defroutes app-routes
  (c-route/resources "/")
  (c-route/not-found "404 Page not found."))

;; The top-level collection of all routes
;; --------------------------------------
(def all-routes (c-core/routes site
                               app-routes))

You can also define single "global" rpc functions:

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

See the full example in the shoreleave-baseline project

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 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

  • The ability to create embedded web workers

Where's the code?

There is a starter project that you can use as template, similar to how ClojureScript:One worked. It's also a great source to see how to build out Shoreleave+Compojure projects.

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

Deprecated

What's new in the latest version?

The latest version is 0.3.0

  • Example application and template project, shoreleave-baseline
  • Finalized protocols and support for browser web storage (localStorage, sessionStorage)
  • Ring middleware updated and moved to be the standard Shoreleave server-side component
  • Dropped Noir support
  • Updated remotes support for better error handling
  • Improved pub/sub handling of various flow combinations
  • subscribe-> added the pub/sub bus procotol - allows threading of flows
  • Replaced deprecated CLJS protocol usage
  • Code migrated from this project to CLJS proper
  • removed jQuery support from remotes
  • Updated all interfaces to their HTML5 finalized specs
  • bug fixes and performance improvements
  • Added more documentation

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.

There is a community-contributed demo app thanks to the hard work of Robert Stuttaford

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.

License

Copyright (C) 2012-2013 Paul deGrandis

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

More Repositories

1

cljs-terra

A Terra-backed ClojureScript compiler
Clojure
86
star
2

sterling

Explorations into specification-as-a-value
Clojure
42
star
3

clojure-leap

An idiomatic Clojure interface to the Leap Motion
JavaScript
36
star
4

ttt

An example ClojureScript+Node.js scripting app; A git-backed text-based ticket tracker
JavaScript
24
star
5

pdx_guide

A guide for Downtown Portland
20
star
6

daisneon

Dais interceptor chain in Rust+ClojureScript on Node.js
Clojure
18
star
7

themis

A data structure processing library - validation, response or message generation, etc.; inspired by Metis.
Clojure
16
star
8

se_checklist

A quality/architecture checklist for building internet-facing applications
TeX
12
star
9

cmma

Clojure + Make Managed Applications
Clojure
8
star
10

cljs-android

ClojureScript on Android via SL4A
JavaScript
7
star
11

lein-pedestal

A Pedestal plugin for Leiningen
Clojure
7
star
12

clj-bitbucket

BitBucket API bindings for Clojure
Clojure
6
star
13

jloj

Java 8 and Clojure interop
Java
5
star
14

soymacchiato

OpenJDK 1.7 for Mac OS X
5
star
15

acm_talk_apr2013

An introduction talk about Clojure for PSU // ACM
Clojure
3
star
16

data-driven-slides

My slides from Clojure Conj 2014
3
star
17

logsel

CSS-like selectors for Clojure data structures
Clojure
3
star
18

saclib

SAClib2.1 computer algebra system // simple and convenient C library
JavaScript
3
star
19

turing-challenge

The Turing Award Challenge
3
star
20

tee

An all-clojure parallel and distributed job queue
Clojure
3
star
21

cassaforte

High performance and extendable Cassandra client for Clojure (Currently NOT being developed)
Clojure
3
star
22

coopquo

Collective Intelligence library for Clojure
Clojure
3
star
23

aupy

Autonomic micro-framework for Python based on Application Utility functions
Python
2
star
24

scratch

Sanbox repo to play with technolgies and ideas
Clojure
2
star
25

net-ns

A remote namespace system for Clojure
Clojure
2
star
26

enact

a CSS selection-based templating system for Python, based on Clojure's Enlive
Python
1
star
27

research

Previous and current research projects I've worked on.
Java
1
star
28

dais

A simple sync-only interceptor chain in Java
Java
1
star
29

cmma-template

A Leiningen template for CMMA/Makefile projects
Clojure
1
star
30

uberclj

A bundled Clojure distribution
Clojure
1
star
31

ohpauleez-maven-repo

Maven Repo of in-progress work releases
1
star
32

i2p-dashbord-widget

A OS X Dashboard widget to start/stop I2P (anon network)
JavaScript
1
star
33

clopi

Clojure Package Index - Stats for clojure libs and packages
Clojure
1
star