From 141d959d286ef183b7a3bfd3f9c42f26177c247a Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Mon, 29 Aug 2022 11:56:30 -0400 Subject: [PATCH] selectors in tutorial --- docs/tutorial-selectors.test.js | 27 ++++++++++++++++++++++ docs/tutorial.md | 41 +++++++++++++++++++++++++++++++++ src/Updux.js | 19 +++++++-------- src/createStore.test.js | 1 + 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 docs/tutorial-selectors.test.js diff --git a/docs/tutorial-selectors.test.js b/docs/tutorial-selectors.test.js new file mode 100644 index 0000000..a3a4969 --- /dev/null +++ b/docs/tutorial-selectors.test.js @@ -0,0 +1,27 @@ +import { test, expect } from 'vitest'; + +import { Updux } from '../src/index.js'; + +test( 'selectors', () => { + const dux = new Updux({ + initial: { a: 1, b: 2 }, + selectors: { + getA: ({a}) => a, + getBPlus: ({b}) => addition => b + addition, + }, + subduxes: { + subbie: new Updux({ + initial: { d: 3 }, + selectors: { + getD: ({d}) => d + } + }) + } + }) + + const store = dux.createStore(); + + expect( store.getState.getA() ).toEqual(1); + expect( store.getState.getBPlus(7) ).toEqual(9); + expect( store.getState.getD() ).toEqual(3); +} ); diff --git a/docs/tutorial.md b/docs/tutorial.md index 1167b61..22184c0 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -126,8 +126,49 @@ store.dispatch.addTodo('Do the thing'); ### Catch-all effect It is possible to have an effect match all actions via the special `*` token. + ``` todosUpdux.addEffect('*', () => next => action => { console.log( 'seeing action fly by:', action ); next(action); }); +``` + +## Adding selectors + +Selectors can be defined to get data derived from the state. +From now you should know the drill: selectors can be defined at construction +time or via `setSelector`. + +``` +const getTodoById = ({todos}) => targetId => todos.find(({id}) => id === targetId); + +const todosUpdux = new Updux({ + selectors: { + getTodoById + } +}) +``` + +or + +``` +todosDux.setSelector('getTodoById', getTodoById); +``` + +### Accessing selectors + +The `getState` method of a dux store is augmented +with its selectors, with the first call for the state already +called in for you. + +```js +const store = todosDux.createStore(); + +console.log( + todosUpdux.getState.getTodoById(1) +); +``` + + + diff --git a/src/Updux.js b/src/Updux.js index 7577f38..5eb76b3 100644 --- a/src/Updux.js +++ b/src/Updux.js @@ -148,20 +148,17 @@ export class Updux { store.actions = this.actions; - // store.selectors = this.selectors; + store.selectors = this.selectors; - // store.getState = R.merge( - // store.getState, - // R.mapValues(this.selectors, (selector) => { - // return (...args) => { - // let result = selector(store.getState()); + Object.entries(this.selectors).forEach(([selector, fn]) => { + store.getState[selector] = (...args) => { + let result = fn(store.getState()); - // if (typeof result === 'function') return result(...args); + if (typeof result === 'function') return result(...args); - // return result; - // }; - // }) - // ); + return result; + }; + }); for (const action in this.actions) { store.dispatch[action] = (...args) => { diff --git a/src/createStore.test.js b/src/createStore.test.js index 161822b..286de5e 100644 --- a/src/createStore.test.js +++ b/src/createStore.test.js @@ -11,6 +11,7 @@ test('basic createStore', async () => { const store = foo.createStore(); + expect(store.getState).toBeTypeOf('function'); expect(store.getState()).toEqual({ a: 1 }); expect(store.actions.a1).toBeTypeOf('function');