basic selector mechanism

This commit is contained in:
Yanick Champoux 2022-08-26 10:37:17 -04:00
parent 378d61337f
commit fa3300004d
4 changed files with 73 additions and 2 deletions

View File

@ -1,6 +1,7 @@
import R from 'remeda'; import R from 'remeda';
import { createStore as reduxCreateStore } from 'redux'; import { createStore as reduxCreateStore } from 'redux';
import { buildSelectors } from './selectors.js';
import { action } from './actions.js'; import { action } from './actions.js';
function isActionGen(action) { function isActionGen(action) {
@ -19,6 +20,7 @@ export class Updux {
#actions; #actions;
#mutations = {}; #mutations = {};
#config = {}; #config = {};
#selectors = {};
constructor(config = {}) { constructor(config = {}) {
this.#config = config; this.#config = config;
@ -31,6 +33,8 @@ export class Updux {
Object.entries(this.#subduxes).forEach(([slice, sub]) => Object.entries(this.#subduxes).forEach(([slice, sub]) =>
this.#addSubduxActions(slice, sub), this.#addSubduxActions(slice, sub),
); );
this.#selectors = buildSelectors( config.selectors, config.splatSelectors, this.#subduxes );
} }
#addSubduxActions(_slice, subdux) { #addSubduxActions(_slice, subdux) {
@ -46,6 +50,10 @@ export class Updux {
}); });
} }
get selectors() {
return this.#selectors;
}
get actions() { get actions() {
return this.#actions; return this.#actions;
} }
@ -119,3 +127,5 @@ export class Updux {
return store; return store;
} }
} }
export const dux = (config) => new Updux(config);

View File

@ -13,7 +13,5 @@ test('basic createStore', async () => {
expect(store.getState()).toEqual({ a: 1 }); expect(store.getState()).toEqual({ a: 1 });
console.log(store.actions.a1);
expect(store.actions.a1).toBeTypeOf('function'); expect(store.actions.a1).toBeTypeOf('function');
}); });

26
src/dux-selectors.test.js Normal file
View File

@ -0,0 +1,26 @@
import { test, expect } from 'vitest';
import { dux } from './Updux.js';
test( "basic selectors", () => {
const foo = dux({
initial: {
x: 1,
},
selectors: {
getX: ({x}) => x,
},
subduxes: {
bar: {
initial: { y: 2 },
selectors: {
getY: ({y}) => y
}
}
}
});
expect( foo.selectors.getY({bar:{y:3}} ) ).toBe(3);
} );

37
src/selectors.js Normal file
View File

@ -0,0 +1,37 @@
import R from 'remeda';
export function buildSelectors(
localSelectors,
splatSelector = {},
subduxes = {}
) {
const subSelectors = Object.entries(subduxes).map(([slice,{ selectors }]) => {
if (!selectors) return {};
if (slice === '*') return {};
return R.mapValues(
selectors,
(func) => (state) => func(state[slice])
);
});
let splat = {};
for (const name in splatSelector) {
splat[name] =
(state) =>
(...args) => {
const value = splatSelector[name](state)(...args);
const res = () => value;
return merge(
res,
mapValues(
subduxes['*'].selectors,
(selector) => () => selector(value)
)
);
};
}
return R.mergeAll([ ...subSelectors, localSelectors, splat ]);
}