Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularize core functionality, consolidate global state #2

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a511874
Fix up Navigation Links
mike-thompson-day8 Dec 20, 2016
22187ba
Better Table Of Contents
mike-thompson-day8 Dec 20, 2016
6df7c09
Add figma file used to create the infographics
mike-thompson-day8 Dec 21, 2016
1569186
Add re-frame-datatable to External-Resources.md
smahood Dec 21, 2016
34b64c5
Merge pull request #300 from Day8/smahood-patch-2
smahood Dec 21, 2016
21d151d
Provide more direction to docs readers
mike-thompson-day8 Dec 22, 2016
816a5a0
Add figma file used to create the infographics
mike-thompson-day8 Dec 21, 2016
870c64d
Provide more direction to docs readers
mike-thompson-day8 Dec 22, 2016
2f0f406
Improve docs navigation and remove unnecessary Tables of Contexts
mike-thompson-day8 Dec 22, 2016
d33fef2
Merge branch 'develop'
mike-thompson-day8 Dec 22, 2016
3fc3478
Add react-flip-move example to Resources
mike-thompson-day8 Dec 22, 2016
de8be2e
Improve FAQ entry
mike-thompson-day8 Dec 22, 2016
55919de
Docs improvement
mike-thompson-day8 Dec 23, 2016
fd58618
Fix links to DataScript database
ilyazub Dec 23, 2016
ab89b9b
Merge pull request #301 from ilyazub/patch-2
mike-thompson-day8 Dec 23, 2016
9f1f54b
Clean up External Resources for Effects
mike-thompson-day8 Dec 24, 2016
dc63a4f
More work on External Resouces
mike-thompson-day8 Dec 24, 2016
2b17501
Improve docs on reg-sub-raw
mike-thompson-day8 Dec 27, 2016
51a2e7f
Move docs on reg-sub-raw
mike-thompson-day8 Dec 27, 2016
6ae5d8e
Docs typos
mike-thompson-day8 Dec 27, 2016
bd58f7d
Docs clarity
mike-thompson-day8 Dec 27, 2016
649d9d9
Add example use of reg-sub-raw
mike-thompson-day8 Dec 27, 2016
3657f0f
More reg-sub-raw
mike-thompson-day8 Dec 27, 2016
209470e
Correct the `:id` given to `on-change` interceptor (ie. fix cut and …
mike-thompson-day8 Dec 28, 2016
4bba231
Add more comments to todomvc
mike-thompson-day8 Dec 28, 2016
ae7da52
Improve docs
mike-thompson-day8 Dec 28, 2016
be3f45d
Better docs navigation
mike-thompson-day8 Dec 28, 2016
767f6a9
Wrangle the top of MentalModelOmnibus docs
mike-thompson-day8 Dec 28, 2016
fcd0db5
Get image position correct in docs (relative to github rendering)
mike-thompson-day8 Dec 28, 2016
2a8e5dc
Improve Table of Contexts in various docs
mike-thompson-day8 Dec 29, 2016
9b74822
Improve "simple" example
mike-thompson-day8 Dec 29, 2016
ab54e2f
move registry and event-queue state into re-frame.core
martinklepsch Dec 19, 2016
af1c112
make make-restore-fn use core/registry
martinklepsch Dec 19, 2016
ab732f1
turn public API into protocol and singleton in re-frame.core
martinklepsch Dec 19, 2016
b897a4d
refactor subs-cache; integrate into frame singleton
martinklepsch Dec 20, 2016
823930a
allow parameteriziation of default interceptors
martinklepsch Dec 20, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ change, but sometimes the outside world must also be effected

### 3rd Domino - Effect Handling

The descriptions of `effects` are realised (actioned). This is where mutations happens.
The descriptions of `effects` are realised (actioned).

Now, to a functional programmer, `effects` are scary in a
[xenomorph kind of way](https://www.google.com.au/search?q=xenomorph).
Expand All @@ -143,17 +143,17 @@ never achieving anything.
So re-frame embraces the protagonist nature of `effects` - the entire, unruly zoo of them - but
it does so in a largely hidden way, and in a manner which is debuggable, auditable, mockable and pluggable.

### A Pivot Point
### We're At A Pivot Point

The world just changed and, very often, one particular part of it: the **application state**.

re-frame's `app state` is held in one place - think of it like you
would an in-memory, central database for the app (more details later).
would an in-memory, central database for the app (details later).

When domino 3 changes this `app state`, it triggers the next part of the cascade
involving dominoes 4-5-6.

### There's a formula
### There's a Formula

The 4-5-6 domino cascade implements the formula made famous by Facebook's ground-breaking React library:
`v = f(s)`
Expand Down
27 changes: 15 additions & 12 deletions docs/ApplicationState.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## Application State

<blockquote class="twitter-tweet" lang="en"><p>Well-formed Data at rest is as close to perfection in programming as it gets. All the crap that had to happen to put it there however...</p>&mdash; Fogus (@fogus) <a href="https://twitter.com/fogus/status/454582953067438080">April 11, 2014</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<div style="width:520px">
<blockquote class="twitter-tweet" lang="en"><p>Well-formed Data at rest is as close to perfection in programming as it gets. All the crap that had to happen to put it there however...</p>&mdash; Fogus (@fogus) <a href="https://twitter.com/fogus/status/454582953067438080">April 11, 2014</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>

### The Big Ratom

Expand Down Expand Up @@ -42,10 +44,11 @@ Further Notes:
2. In the documentation and code, I make a distinction between `app-db` (the `ratom`) and
`db` which is the (map) `value` currently stored **inside** this `ratom`. Be aware of that naming as you read code.
3. re-frame creates and manages an `app-db` for you, so
you don't need to declare one yourself (see the 1st FAQ if you want to inspect the value it holds).
you don't need to declare one yourself (see the [the first FAQ](FAQs/Inspecting-app-db.md) if you want
to inspect the value it holds).
4. `app-db` doesn't actually have to be a `ratom` containing a map. It could, for example,
be a [datascript](https://github.com/tonsky/datascript database). In fact, any database which
can signal you when it changes would do. We'd love! to be using [datascript](https://github.com/tonsky/datascript database) - so damn cool -
be a [datascript database](https://github.com/tonsky/datascript). In fact, any database which
can signal you when it changes would do. We'd love! to be using [datascript database](https://github.com/tonsky/datascript) - so damn cool -
but we had too much data in our apps. If you were to use it, you'd have to tweak re-frame a bit and use [Posh](https://github.com/mpdairy/posh).


Expand All @@ -69,7 +72,7 @@ Again, this simplicity causes a certain class of bugs or design problems to evap
so that, at any moment, we can validate all the data in the application. **All of it!**
We do this check after every single "event handler" runs (event handlers compute new state).
And this enables us to catch errors early (and accurately). It increases confidence in the way
that Types can increase confidence, only [a good schema can provide more
that Types can increase confidence, only [a good schema can potentially provide more
**leverage** than types](https://www.youtube.com/watch?v=nqY4nUMfus8).

4. Undo/Redo [becomes straight forward to implement](https://github.com/Day8/re-frame-undo).
Expand All @@ -91,22 +94,22 @@ source of data is elsewhere.

### Create A Leveragable Schema

You really need a `spec` schema for `app-db`. The derived power is immense.
You need to create a [spec](http://clojure.org/about/spec) schema for `app-db`. You want that leverage.

Of course, that means you'll have to learn [spec](http://clojure.org/about/spec) and there's
some overhead in that, so maybe, just maybe, in your initial experiments, you can
get away without one. But not for long. Promise me you'll write a `spec`. Promise me. Okay, good.

The [todomvc example](https://github.com/Day8/re-frame/tree/master/examples/todomvc)
shows how to use a spec. Look in `src/db.cljs` for the spec itself, and then in `src/events.cljs` for
Soon we'll look at the [todomvc example](https://github.com/Day8/re-frame/tree/master/examples/todomvc)
which shows how to use a spec. (Check out `src/db.cljs` for the spec itself, and then in `src/events.cljs` for
how to write code which checks `app-db` against this spec after every single event has been
processed.
processed.)

Specs are more leveragable than types. This is a big interesting idea which is not yet mainstream.
Specs are potentially more leveragable than types. This is a big interesting idea which is not yet mainstream.
Watch how: <br>
https://www.youtube.com/watch?v=VNTQ-M_uSo8

Also, the mighty Rich Hickey (poor audio):<br>
Also, watch the mighty Rich Hickey (poor audio):<br>
https://vimeo.com/195711510

### How do I inspect it?
Expand Down
14 changes: 5 additions & 9 deletions docs/Basic-App-Structure.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table Of Contents

- [Simpler Apps](#simpler-apps)
- [There's A Small Gotcha](#theres-a-small-gotcha)
- [Larger Apps](#larger-apps)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Simpler Apps

Expand Down Expand Up @@ -73,3 +64,8 @@ Continue to [Navigation](Navigation.md) to learn how to switch between panels of
Previous: [Correcting a wrong](SubscriptionsCleanup.md)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Up: [Index](README.md)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Next: [Navigation](Navigation.md)


<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
55 changes: 27 additions & 28 deletions docs/CodeWalkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,63 +2,58 @@

## Initial Code Walk-through

At this point, you are about 50% of the way to understanding re-frame. You are armed with:
- a high level understanding of the 6 domino process (from re-frame's README)
- an understanding of application state (from the previous tutorial)
At this point, you are about 50% of the way to understanding re-frame. You have:
- an overview of the 6 domino process [from this repo's README](../README.md)
- an understanding of app state ([from the previous tutorial)](ApplicationState.md))

By the end of this tutorial, you'll be at 70%, which is good
In this tutorial, **we look at re-frame code**. By the end of it, you'll be at 70% knowledge, which is good
enough to start coding by yourself.

In this tutorial, **we'll look at re-frame code**.


<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table Of Contents
### Table Of Contents

- [What Code?](#what-code)
- [What Does It Do?](#what-does-it-do)
- [Namespace](#namespace)
- [Data Schema](#data-schema)
- [Events (domino 1)](#events-domino-1)
- [dispatch](#dispatch)
- [After dispatch](#after-dispatch)
- [Event Handlers (domino 2)](#event-handlers-domino-2)
- [reg-event-db](#reg-event-db)
- [:initialize](#initialize)
- [:timer](#timer)
- [:time-color-change](#time-color-change)
- [Effect Handlers (domino 3)](#effect-handlers-domino-3)
- [Subscription Handlers (domino 4)](#subscription-handlers-domino-4)
- [reg-sub](#reg-sub)
- [View Functions (domino 5)](#view-functions-domino-5)
- [Hiccup](#hiccup)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## What Code?

This repo contains an example application called ["simple"](https://github.com/Day8/re-frame/tree/develop/examples/simple),
which has around 70 lines of code. We'll look at every line of [the file](https://github.com/Day8/re-frame/blob/develop/examples/simple/src/simple/core.cljs).
This repo contains an `/examples` application called ["simple"](https://github.com/Day8/re-frame/tree/develop/examples/simple),
which contains 70 lines of code. We'll look at every line of [the file](https://github.com/Day8/re-frame/blob/develop/examples/simple/src/simple/core.cljs).

This app:
- displays the current time in a nice big, colourful font
- provides a single text input field, into which you can type a hex colour code,
like "#CCC", used for the time display

Here's what it looks like:
When it is running, here's what it looks like:

![Example App image](../images/example_app.png)

To run the code:
To run the code yourself:
* Install Java 8
* Install leiningen (http://leiningen.org/#install)

Then:
1. `git clone https://github.com/Day8/re-frame.git`
2. `cd re-frame/examples/simple`
3. `lein do clean, figwheel`
4. open http://localhost:3449/example.html
4. wait a minute and then open `http://localhost:3449/example.html`

So, what's just happened? The ClojureScript code under `src` has been compiled across to `javascript` and
put into `/resources/public/js/client.js` which is loaded into `/resources/public/example.html` (the HTML you just openned)

Figwheel provides for hot-loading, so you can edit the source and watch the loaded HTML change.


## Namespace
Expand Down Expand Up @@ -94,7 +89,7 @@ to your various handlers as required.

## Events (domino 1)

Events are data. You choose the format.
Events are data.

re-frame uses a vector
format for events. For example:
Expand All @@ -108,15 +103,13 @@ associated with the event. The additional value above, `42`, is
presumably the id of the item to delete.

Here are some other example events:

```clj
[:admit-to-being-satoshi false]
[:set-spam-wanted false :continue-harassment-nevertheless-flag]
[:some-ns/on-GET-success response]
[:dressing/put-pants-on "velour flares" {:method :left-leg-first :belt false}]
```

The `kind` of event is always a keyword, and for non-trivial
applications it tends to be namespaced.
The `kind` of event is a keyword, and for non-trivial
applications it will be namespaced.

**Rule**: events are pure data. No sneaky tricks like putting
callback functions on the wire. You know who you are.
Expand Down Expand Up @@ -501,10 +494,16 @@ structure exists in `app-db` before any subscriptions or event handlers run.
- write and register query functions which implement nodes in a signal graph (query layer) (domino 4)
- write Reagent view functions (view layer) (domino 5)

## Further Code
## Next Steps

You should now take time to carefully review the [todomvc example application](https://github.com/Day8/re-frame/tree/develop/examples/todomvc).

You should also look at the [todomvc example application](https://github.com/Day8/re-frame/tree/develop/examples/todomvc).
After that, you'll be ready to write your own code. Perhaps you will use a
template to create your own project: <br>
Client only: https://github.com/Day8/re-frame-template <br>
Full Stack: http://www.luminusweb.net/

Obviously you should also go on to read the further documentation.

***

Expand Down
30 changes: 15 additions & 15 deletions docs/Coeffects.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ to manage them in tests.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table Of Contents

- [What Are They?](#what-are-they)
- [An Example](#an-example)
- [How We Want It](#how-we-want-it)
- [Abracadabra](#abracadabra)
- [Which Interceptors?](#which-interceptors)
- [`inject-cofx`](#inject-cofx)
- [More `inject-cofx`](#more-inject-cofx)
- [Meet `reg-cofx`](#meet-reg-cofx)
- [Example Of `reg-cofx`](#example-of-reg-cofx)
- [Another Example Of `reg-cofx`](#another-example-of-reg-cofx)
- [Secret Interceptors](#secret-interceptors)
- [Testing](#testing)
- [The 5 Point Summary](#the-5-point-summary)
### Table Of Contents

* [What Are They?](#what-are-they-)
* [An Example](#an-example)
* [How We Want It](#how-we-want-it)
* [Abracadabra](#abracadabra)
* [Which Interceptors?](#which-interceptors-)
* [`inject-cofx`](#-inject-cofx-)
* [More `inject-cofx`](#more--inject-cofx-)
* [Meet `reg-cofx`](#meet--reg-cofx-)
* [Example Of `reg-cofx`](#example-of--reg-cofx-)
* [Another Example Of `reg-cofx`](#another-example-of--reg-cofx-)
* [Secret Interceptors](#secret-interceptors)
* [Testing](#testing)
* [The 5 Point Summary](#the-5-point-summary)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand Down
2 changes: 1 addition & 1 deletion docs/EffectfulHandlers.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Yes, a surprising claim.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table Of Contents
### Table Of Contents

- [Events Happen](#events-happen)
- [Handling The Happening](#handling-the-happening)
Expand Down
34 changes: 11 additions & 23 deletions docs/Effects.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ This tutorial explains how side effects are actioned,
how you can create your own side effects, and how you can
make side effects a noop in event replays.

> imperative programming is a big pile of do <br>
> &nbsp; &nbsp; -- @stuarthalloway


<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table Of Contents
### Table Of Contents

- [Where Effects Come From](#where-effects-come-from)
- [The Effects Map](#the-effects-map)
Expand Down Expand Up @@ -54,38 +50,38 @@ Like this:

An effects map contains instructions.

Each key/value pair in the map is one instruction - the `key` uniquely identifies
the particular side effect required, and the `value` for that `key` provides
further data. The structure of `value` is different for each side-effect.
Each key/value pair in the map is one instruction - the `key` uniquely identifies
the particular side effect required, and the `value` for that `key` provides
further data. The structure of `value` is different for each side-effect.

Here's the two instructions from the example above:
Here's the two instructions from the example above:
```cljs
{:db (assoc db :flag a) ;; side effect on app-db
:dispatch [:do-something-else 3]} ;; dispatch this event
```

The `:db` `key` instructs that "app-db" should be `reset!` to the
`value` supplied.
`value` supplied.

And the `:dispatch` `key` instructs that an event should be
dispatched. The `value` is the vector to dispatch.

There's many other possible
effects, like for example `:dispatch-later` or `:set-local-store`.

And so on. And so on. Which brings us to a problem.
And so on. And so on. Which brings us to a problem.

### Infinite Effects

While re-frame supplies a number of builtin effects, the set of
While re-frame supplies a number of builtin effects, the set of
possible effects is open ended.

What if you use PostgreSQL and want an effect which issues mutating
What if you use PostgreSQL and want an effect which issues mutating
queries? Or what if you want to send logs to Logentries or metrics to DataDog.
Or write values to windows.location. And what happens if your database is
X, Y or Z?

The list of effects is long and varied, with everyone needing to use a
The list of effects is long and varied, with everyone needing to use a
different combination.

So effect handling has to be extensible. You need a way to define
Expand Down Expand Up @@ -347,16 +343,8 @@ usage:

### External Effects

- https://github.com/Day8/re-frame-http-fx (GETs and POSTs)
- https://github.com/Day8/re-frame-forward-events-fx (slightly exotic)
- https://github.com/Day8/re-frame-async-flow-fx (more complicated)
- https://github.com/micmarsh/re-frame-youtube-fx (YouTube iframe API wrapper)
- https://github.com/madvas/re-frame-web3-fx (Ethereum Web3 API)
- https://github.com/madvas/re-frame-google-analytics-fx (Google Analytics API)

Create a PR to include yours in this list.
Please see the [External-Resources document](External-Resources.md) for a list of 3rd part Effect Handlers.

XXX maybe put this list into the Wiki, so editable by all.

***

Expand Down
4 changes: 2 additions & 2 deletions docs/EventHandlingInfographic.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Event Handling Infographics

Three diagrams are provided:
Three diagrams are provided below:
- a beginner's romp
- an intermediate schematic depiction
- an advanced, full detail rendering
Expand All @@ -11,6 +11,6 @@ They should be reviewed in conjunction with the written tutorials.

***


Previous: [Mental Model Omnibus](MentalModelOmnibus.md)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Up: [Index](README.md)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Next: [Effectful Handlers](EffectfulHandlers.md)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Loading