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

Make runtime the main module #28

Merged
merged 1 commit into from
Jun 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ npm install raj
A counter that increments by one every time the user confirms.

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

program({
runtime({
init: [0], // State is an integer to count
update (message, state) {
return [state + 1] // Increment the state
Expand All @@ -34,7 +34,8 @@ program({
})
```

*Note:* Raj is view layer agnostic. Here we use the browser's built-in view to play the part.
*Note:* Raj is view layer agnostic.
Here we use the browser's built-in view to play the part.

## Architecture

Expand All @@ -50,10 +51,12 @@ Building any app follows the same steps:
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()`
1. Tie it all together with `runtime()`

## 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.
The `raj` package contains a function `runtime`.
This function creates a runtime for a Raj program.
These programs have the same interface.

```ts
interface RajProgram<State, Message, View> {
Expand All @@ -73,6 +76,6 @@ interface RajProgram<State, Message, 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 40 lines of JavaScript, which may be easier to understand for those who are not familiar with TypeScript.
*Note:* TypeScript is not required for Raj applications.
This is hard to read, so I wanted syntax highlighting from a typed language.
Raj is 34 lines of JavaScript, which may be easier to understand for those who are not familiar with TypeScript.
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ <h3>Features</h3>
<div>
<h4>Understandable</h4>
<p>
Raj is 34 lines; 203 bytes minified.
Raj is 34 lines; 190 bytes minified.
This framework can fit in your head or even a tweet.
</p>
</div>
Expand Down
34 changes: 33 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1,33 @@
throw new Error('Do not import/require raj directly, use "raj/runtime"')
exports.runtime = function (program) {
var update = program.update
var view = program.view
var done = program.done
var state
var isRunning = true

function dispatch (message) {
if (isRunning) {
change(update(message, state))
}
}

function change (change) {
state = change[0]
var effect = change[1]
if (effect) {
effect(dispatch)
}
view(state, dispatch)
}

change(program.init)

return function end () {
if (isRunning) {
isRunning = false
if (done) {
done(state)
}
}
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"devDependencies": {
"ava": "^0.25.0",
"fixpack": "^2.3.1",
"prettier": "^1.13.5",
"standard": "^11.0.0"
},
"homepage": "https://jew.ski/raj/",
Expand All @@ -26,7 +27,7 @@
"url": "git+https://github.com/andrejewski/raj.git"
},
"scripts": {
"lint": "fixpack && standard --fix",
"lint": "fixpack && prettier index.js test/**/*.js --write && standard --fix",
"test": "npm run lint && ava"
}
}
34 changes: 0 additions & 34 deletions runtime.js

This file was deleted.

22 changes: 11 additions & 11 deletions test/runtime.js → test/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import test from 'ava'
import {program} from '../runtime'
import { runtime } from '../'

test('program() should call view() initially', t => {
test('runtime() should call view() initially', t => {
const initialState = 1
return new Promise(resolve => {
program({
runtime({
init: [initialState],
view (state) {
t.is(state, initialState)
Expand All @@ -14,10 +14,10 @@ test('program() should call view() initially', t => {
})
})

test('program() should call view() after dispatch', t => {
test('runtime() should call view() after dispatch', t => {
let count = 0
return new Promise(resolve => {
program({
runtime({
init: ['init'],
update (msg) {
return [msg]
Expand All @@ -38,11 +38,11 @@ test('program() should call view() after dispatch', t => {
}).then(() => t.is(count, 3))
})

test('program() should call done() when killed', t => {
test('runtime() should call done() when killed', t => {
t.plan(1)
return new Promise(resolve => {
const initialState = 'state'
const kill = program({
const kill = runtime({
init: [initialState],
update (msg, state) {
return state
Expand All @@ -58,7 +58,7 @@ test('program() should call done() when killed', t => {
})
})

test('program() should not call update/view if killed', t => {
test('runtime() should not call update/view if killed', t => {
t.plan(2)
let initialRender = true
const initialState = 'state'
Expand All @@ -70,7 +70,7 @@ test('program() should not call update/view if killed', t => {
resolve()
}, 10)
}
const kill = program({
const kill = runtime({
init: [initialState, afterKillEffect],
update () {
t.fail('update() should not be called')
Expand All @@ -90,9 +90,9 @@ test('program() should not call update/view if killed', t => {
})
})

test('program() should only call done() once', t => {
test('runtime() should only call done() once', t => {
let initialCall = true
const kill = program({
const kill = runtime({
init: [],
update () {},
view () {},
Expand Down