basic selector mechanism
This commit is contained in:
parent
378d61337f
commit
fa3300004d
10
src/Updux.js
10
src/Updux.js
@ -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);
|
||||||
|
@ -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
26
src/dux-selectors.test.js
Normal 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
37
src/selectors.js
Normal 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 ]);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user