Skip to content

Commit

Permalink
Ecosystem (#12)
Browse files Browse the repository at this point in the history
* Remove package-lock stuff

* Big changes

* Remove React deps and keyword
  • Loading branch information
andrejewski committed Sep 11, 2017
1 parent 87bfac1 commit d5913c8
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 4,236 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ typings/
# dotenv environment variables file
.env

package-lock.json
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
language: node_js
node_js:
- node
before_install: npm install -g greenkeeper-lockfile@1
before_script: greenkeeper-lockfile-update
after_script: greenkeeper-lockfile-upload
deploy:
provider: npm
email: christopher.andrejewski@gmail.com
Expand Down
98 changes: 74 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,6 @@ npm install raj
[![Build Status](https://travis-ci.org/andrejewski/raj.svg?branch=master)](https://travis-ci.org/andrejewski/raj)
[![Greenkeeper badge](https://badges.greenkeeper.io/andrejewski/raj.svg)](https://greenkeeper.io/)

## Documentation

- `raj/effect`: group and transform effects
- `effect.map(mapper, effect)`: transforms the dispatched values of `effect` using the function `mapper`
- `effect.batch(effects)`: group an array of effects into a single effect
- `raj/runtime`: create generic runtimes
- `program({init, update, view})`
- `init`: the initial state and optional effect
- `update(message, state)`: return the new state and optional effect
- `view(state, dispatch)`: use the state and dispatch messages

#### Integrations
- `raj/react`: React bindings
- `program(Component, props => ({init, update, view}))`: create a React program
- `Component`: a React Component class
- `props`: the React component `props`
- `init`: the initial state and optional effect
- `update(message, state)`: return the new state and optional effect
- `view(state, dispatch)`: return the React view

## Architecture

The data flow is unidirectional.
Expand All @@ -39,13 +19,83 @@ The view and any side-effects communicate by dispatching messages.
Building any app follows the same steps:

1. Define your data model with `init`
1. Define your messages with something like [`tagmeme`](https://github.com/andrejewski/tagmeme)
1. Define your messages
1. Define your behaviors with `update(message, state)`
1. Define your effects as functions which accept a dispatch function
1. Define your view with `view(state, dispatch)`
1. Tie it all together with `program()`

## Examples
## Documentation
The `raj` package contains a single module `raj/runtime`. This module creates runtimes for every Raj application. The `runtime` module exports a single method `program` which will create a runtime for a "program." These programs have the same interface.

```ts
interface RajProgram<State, Message, View> {
init: [
// initial state
State,
// initial effect (optional)
void | ((dispatch: (message: Message) => void) => void)
]
update (message: Message, state: State): [
// new state
State,
// new effect (optional)
void | ((dispatch: (message: Message) => void) => void)
]
view (state: State, dispatch: (message: Message) => void): View;
}
```

*Note: TypeScript is not required for Raj applications. This is hard to read, so I wanted syntax highlighting from a typed language.*

The `runtime` module itself is about 20 lines of JavaScript, which may be easier to understand for those who are not familiar with TypeScript.

## Example
A counter that increments by one every time the user confirms.

```js
import {program} from 'raj/runtime'

// State: Integer - We need a single number to count
// Message: void - We receive one message, increment
// View: void - We use the confirm() pop-up as our "view"

program({
init: [0],
update (message, state) {
return [state + 1]
},
view (state, dispatch) {
const keepCounting = window.confirm(`Count is ${state}. Increment?`)
if (keepCounting) {
dispatch()
}
}
})
```

Examples exist in the `examples/` folder.

## Ecosystem

##### Raj packages

| Package | Description |
| ------- | ----------- |
| [`raj-compose`](https://github.com/andrejewski/raj-compose) | Program composition. Raj applications assemble from small programs. Common composition patterns are in this package. |
| [`raj-react`](https://github.com/andrejewski/raj-react) | React bindings. Raj is view library agnostic. This package integrates Raj's runtime into the React ecosystem. |
| [`raj-spa`](https://github.com/andrejewski/raj-spa) | Single page applications. Most apps need a way of coordinating navigation and views. This package provides a coordinator which has lazy-loading and code-splitting support. |

##### Recommended non-Raj packages

| Package | Description |
| ------- | ----------- |
| [`tagmeme`](https://github.com/andrejewski/tagmeme) | Tagged union library. The Raj runtime is message driven. Tagmeme is the recommended way to construct messages. It has tagged unions with pattern matching. |

## Roadmap

Raj is small, leaving most complexity to libraries or applications. Right now the Raj ecosystem is `0.0.x` to ensure that no one can get mad as we make changes to the framework.

A Raj `1.0.0` will happen once we iron out all conceptual problems and have built enough real-world applications for us to feel confident in promoting this approach.

- `examples/search`: Dummy search widget where a query updates a list of search results.
- `examples/make-n-model`: Dummy loader where a selected make loads a list of relevant models.
[I](https://github.com/andrejewski) created this framework, but don't want others to miss out on contributing to its development or building applications with it. If I find good collaborator(s), we can switch these projects over to a community organization and/or a mono-repo as we build towards a version 1. Please reach out if interested in contributing to or building an application with Raj.
28 changes: 0 additions & 28 deletions effect.js

This file was deleted.

2 changes: 1 addition & 1 deletion examples/make-n-model.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import react from 'raj/react'
import react from 'raj-react'
import tag from 'tagmeme'

export const init = [{
Expand Down
2 changes: 1 addition & 1 deletion examples/search.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import react from 'raj/react'
import react from 'raj-react'
import tag from 'tagmeme'

export const init = [{
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
throw new Error('Do not import/require raj directly, use "raj/runtime" or "raj/effect"')
throw new Error('Do not import/require raj directly, use "raj/runtime"')
Loading

0 comments on commit d5913c8

Please sign in to comment.