From 9d64c8bde52542b5c078fc4bca52f2469fe0f701 Mon Sep 17 00:00:00 2001 From: Chris Andrejewski Date: Sun, 17 Jun 2018 00:00:30 -0400 Subject: [PATCH] Make runtime the main module --- README.md | 19 +++++++++++-------- docs/index.html | 2 +- index.js | 34 +++++++++++++++++++++++++++++++++- package.json | 3 ++- runtime.js | 34 ---------------------------------- test/{runtime.js => index.js} | 22 +++++++++++----------- 6 files changed, 58 insertions(+), 56 deletions(-) delete mode 100644 runtime.js rename test/{runtime.js => index.js} (81%) diff --git a/README.md b/README.md index 1f8828b..739b21a 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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 { @@ -73,6 +76,6 @@ interface RajProgram { } ``` -*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. \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index ee0ca78..d61e775 100644 --- a/docs/index.html +++ b/docs/index.html @@ -277,7 +277,7 @@

Features

Understandable

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

diff --git a/index.js b/index.js index 92192fb..f78eea1 100644 --- a/index.js +++ b/index.js @@ -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) + } + } + } +} diff --git a/package.json b/package.json index 996e23c..3e5020b 100644 --- a/package.json +++ b/package.json @@ -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/", @@ -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" } } diff --git a/runtime.js b/runtime.js deleted file mode 100644 index 97958c3..0000000 --- a/runtime.js +++ /dev/null @@ -1,34 +0,0 @@ -exports.program = 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 kill () { - if (!isRunning) { - return - } - isRunning = false - if (done) { - done(state) - } - } -} diff --git a/test/runtime.js b/test/index.js similarity index 81% rename from test/runtime.js rename to test/index.js index 2b952b0..aad60f3 100644 --- a/test/runtime.js +++ b/test/index.js @@ -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) @@ -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] @@ -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 @@ -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' @@ -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') @@ -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 () {},