diff --git a/README.md b/README.md index 8d49f03..58f4dcf 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,6 @@ npm install raj ## Documentation -- `raj/message`: define message and message unions - - `message([displayName])`: create a message - - `message.union([displayName, ] messages)`: create a message union - `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 @@ -41,7 +38,7 @@ The view and any side-effects communicate by dispatching messages. Building any app follows the same steps: 1. Define your data model with `init(flags)` -1. Define your messages with `message/message.union` +1. Define your messages with something like [`tagmeme`](https://github.com/andrejewski/tagmeme) 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)` diff --git a/examples/make-n-model.js b/examples/make-n-model.js index 550389e..8db940a 100644 --- a/examples/make-n-model.js +++ b/examples/make-n-model.js @@ -1,6 +1,6 @@ import React from 'react' -import message from 'raj/message' import react from 'raj/react' +import message from 'tagmeme' export function init () { return { diff --git a/examples/search.js b/examples/search.js index 4a0f987..7d580f0 100644 --- a/examples/search.js +++ b/examples/search.js @@ -1,6 +1,6 @@ import React from 'react' -import message from 'raj/message' import react from 'raj/react' +import message from 'tagmeme' export function init () { return [{ diff --git a/index.js b/index.js index 30265d9..388b631 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -throw new Error('Do not import/require raj directly, use "raj/message" or "raj/react"') +throw new Error('Do not import/require raj directly, use "raj/runtime" or "raj/effect"') diff --git a/message.js b/message.js deleted file mode 100644 index f8a4d19..0000000 --- a/message.js +++ /dev/null @@ -1,96 +0,0 @@ -function assert (condition, message) { - if (!condition) { - throw new Error(message) - } -} - -function createMessage (displayName) { - function Message (...args) { - if (!(this instanceof Message)) { - return new Message(...args) - } - - this.args = arguments - } - - Message.is = function is (x) { - return x instanceof Message - } - - Message.unwrap = function unwrap (message, fn) { - assert(Message.is(message), 'Cannot unwrap messages using an incorrect type') - return fn.apply(null, message.args) - } - - if (typeof displayName === 'string') { - Message.name = displayName - Message.displayName = displayName - } - - return Message -} - -function createMessageUnion (displayName, types) { - if (Array.isArray(displayName)) { - return createMessageUnion(null, displayName) - } - - function UnionMessage () { - throw new Error('Union messages cannot be created directly') - } - - UnionMessage.is = function is (type) { - return unionIs(types, type) - } - - UnionMessage.unwrap = function unwrap (type, fn) { - return fn(type) - } - - UnionMessage.match = function match (type, cases) { - return unionMatch(types, cases, type) - } - - return UnionMessage -} - -function unionMatch (types, cases, type) { - const hasCatchAll = cases.length % 2 === 1 - let fullCases = cases.length - if (hasCatchAll) { - fullCases = fullCases - 1 - } - fullCases = fullCases / 2 - - if (!hasCatchAll) { - const typeCases = [] - const caseTypes = cases.filter(function even (_, i) { - return (i % 2) === 0 - }) - caseTypes.forEach(function (type) { - const isTypeCovered = typeCases.includes(type) - assert(!isTypeCovered, 'Each message can only be covered by one case') - typeCases.push(type) - }) - assert(types.length === caseTypes.length, 'Each message should have exactly one case') - assert(typeCases.length === caseTypes.length, 'Each message needs to be handled') - } - - for (let i = 0; i < fullCases; i++) { - const Type = cases[2 * i] - if (Type.is(type)) { - const fn = cases[(2 * i) + 1] - return Type.unwrap(type, fn) - } - } - - assert(hasCatchAll, 'No type was found that matches the passed value') - return cases[cases.length - 1]() -} - -function unionIs (types, type) { - return types.some(Type => Type.is(type)) -} - -createMessage.union = createMessageUnion -module.exports = createMessage diff --git a/package.json b/package.json index 158c744..9c21811 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "keywords": [ "best", "framework", - "message", + "runtime", "react" ], "license": "MIT", diff --git a/test/message.js b/test/message.js deleted file mode 100644 index 8d7867f..0000000 --- a/test/message.js +++ /dev/null @@ -1,84 +0,0 @@ -import test from 'ava' -import message from '../message' - -test('createMessage() should return a message type', t => { - const Foo = message() - const foo = Foo(0, 1, 2) - - t.is(Foo.is(foo), true) - t.is(Foo.is(Foo), false) - t.is(Foo.is(0), false) - - Foo.unwrap(foo, (x, y, z) => { - t.is(x, 0) - t.is(y, 1) - t.is(z, 2) - }) -}) - -test('Message.unwrap() should throw if used on the wrong message type', t => { - const Foo = message() - const Bar = message() - const bar = Bar(0) - - t.throws(() => { - Foo.unwrap(bar, () => t.fail()) - }) -}) - -test('createMessageUnion() should return a union type', t => { - const Foo = message() - const Bar = message() - const Msg = message.union([Foo, Bar]) - - const foo = Foo(12) - const bar = Bar(18) - - t.is(Msg.is(foo), true) - t.is(Msg.is(bar), true) - t.is(Msg.is(Foo), false) - t.is(Msg.is(Bar), false) - - Msg.unwrap(foo, x => t.is(x, foo)) - - const val = Msg.match(foo, [ - Foo, n => { - t.is(n, 12) - return 8 - }, - Bar, () => t.fail() - ]) - - t.is(val, 8) -}) - -test('Union.match() should allow a catch-all', t => { - const Foo = message() - const Bar = message() - const Msg = message.union([Foo, Bar]) - - const foo = Foo(12) - - Msg.match(foo, [ - () => t.pass() - ]) - - Msg.match(foo, [ - Bar, () => t.fail(), - () => t.pass() - ]) -}) - -test('Union.match should throw if their are missing cases and no catch-all', t => { - const Foo = message() - const Bar = message() - const Msg = message.union([Foo, Bar]) - - const foo = Foo(12) - - t.throws(() => { - Msg.match(foo, [ - Foo, () => {} - ]) - }) -})