An open API service indexing awesome lists of open source software.

https://github.com/reagent-project/reagent-cursor

Optional cursors library for Reagent
https://github.com/reagent-project/reagent-cursor

Last synced: 6 months ago
JSON representation

Optional cursors library for Reagent

Awesome Lists containing this project

README

          

Deprecated
==============

As part of the migration to the new **reagent-project** organization, an earlier version of this **cursors** library was folded into Reagent's core. As part of the Reagent 0.5.0 release, that implementation of cursors has been substantially enhanced (both in performance and in generalization) so this standalone cursor library should be considered **deprecated**.

Note that the argument order in Reagent core is different - atom first, path second - so switching from this library to Reagent core will involve code changes but they are straightforward.

Cursors
==============

Cursors can be seen as a kind of *pointer* to a particular part of an
atom, which behaves exactly like a normal atom. This means that you
use the same functions you would on an atom (`reset!`, `swap!`,
`deref`, `add-watch`, etc) but affect only the part you are interested
in.

This enables you to create reusable functions and components by
abstracting away complex paths and getter/setter functions.

```clj
;; what was...
(swap! my-atom update-in [:some :path :that :might :be :quite :deep] my-fn)

;; ...can now become

(swap! my-cursor my-fn)

;; Notice that the path is no longer hardcoded; it could be a simple
;; atom, or a cursor pointing to the 10th level of a complex nested
;; hashmap.

;; How about associating a value into the nested structure? No
;; problem! Just `reset!` the cursor:

(reset! my-cursor "my-new-value")

;; Now just deref it:

@my-cursor

=> "my-new-value"

```

Usage
-----

Add `[reagent/reagent-cursor "0.1.2"]` to `:dependencies` in `project.clj`.

In your Reagent application `(:require [reagent.cursor :as rc])`.

There are two main functions available to create cursors: `cursor` and `cur`.

## cursor

`cursor` has two arities.

When given a single argument (a path), it returns a function that can
create a cursor when given an atom. *Useful to create mutliple cursors
with the same path.*

```clj
(def my-custom-cursor-fn (rc/cursor [:some :arbitrary :path]))

(map my-custom-cursor-fn [atom1 atom2 atom3])

;; this will return a collection of [cursor1 cursor2 cursor3]
```

When given two arguments, `cursor` will return a cursor.

```clj
(def c1 (rc/cursor [:some :arbitrary :path] atom1))

```

## cur

`cur` is the little brother of `cursor`. It will *only* accept 2
arguments (the atom and a path), but is guaranteed to return a
cursor.

Note that the atom argument is placed on the left, allowing
you to use a thread-first macro (`cursor` requires a thread-last
macro).

```clj

(-> my-atom
(rc/cur [:some :path]) ;; <---- create the cursor
(add-watch :my-watch #(println "updated!"))
(historian/record! :my-state)
(ls/local-storage :my-state))

```

License
-------

Copyright (c) 2014 Sean Corfield

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