diff --git a/src/Updux.js b/src/Updux.js index 5524aaf..0ae1d4b 100644 --- a/src/Updux.js +++ b/src/Updux.js @@ -1,6 +1,10 @@ import R from 'remeda'; -import { Action, ActionGenerator } from './actions.js'; +import { action } from './actions.js'; + +function isActionGen(action) { + return typeof action === 'function' && action.type; +} export class Updux { #localInitial = {}; @@ -14,10 +18,25 @@ export class Updux { this.#localInitial = config.initial ?? {}; this.#subduxes = config.subduxes ?? {}; - this.#actions = R.mergeAll([ - config.actions ?? {}, - ...Object.values(this.#subduxes).map(R.prop('actions')), - ]); + this.#actions = R.mapValues(config.actions ?? {}, (arg, name) => + isActionGen(arg) ? arg : action(name, arg), + ); + Object.entries(this.#subduxes).forEach(([slice, sub]) => + this.#addSubduxActions(slice, sub), + ); + } + + #addSubduxActions(_slice, subdux) { + if (!subdux.actions) return; + // TODO action 'blah' defined multiple times: + Object.entries(subdux.actions).forEach(([action, gen]) => { + if (this.#actions[action]) { + if (this.#actions[action] === gen) return; + throw new Error(`action '${action}' already defined`); + } + + this.#actions[action] = gen; + }); } get actions() { diff --git a/src/actions.test.js b/src/actions.test.js index b81d8e1..eb6e22f 100644 --- a/src/actions.test.js +++ b/src/actions.test.js @@ -51,3 +51,36 @@ test('subduxes actions', () => { expect(foo.actions).toHaveProperty('foo'); expect(foo.actions).toHaveProperty('bar'); }); + +test('throw if double action', () => { + expect( + () => + new Updux({ + actions: { + foo: action('foo'), + }, + subduxes: { + beta: { + actions: { + foo: action('foo'), + }, + }, + }, + }), + ).toThrow(/action 'foo' already defined/); +}); + +test('action definition shortcut', () => { + const foo = new Updux({ + actions: { + foo: null, + bar: (x) => ({ x }), + }, + }); + + expect(foo.actions.foo('hello')).toEqual({ type: 'foo', payload: 'hello' }); + expect(foo.actions.bar('hello')).toEqual({ + type: 'bar', + payload: { x: 'hello' }, + }); +});