adding the findSelectors
This commit is contained in:
parent
63d8235346
commit
51421c1052
@ -40,7 +40,7 @@ export class Updux {
|
|||||||
|
|
||||||
this.#selectors = buildSelectors(
|
this.#selectors = buildSelectors(
|
||||||
config.selectors,
|
config.selectors,
|
||||||
config.splatSelectors,
|
config.findSelectors,
|
||||||
this.#subduxes,
|
this.#subduxes,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { test, expect } from 'vitest';
|
import { test, expect } from 'vitest';
|
||||||
|
import R from 'remeda';
|
||||||
|
|
||||||
import { dux } from './Updux.js';
|
import { dux, Updux } from './Updux.js';
|
||||||
|
import { matches } from './utils.js';
|
||||||
|
|
||||||
test('basic selectors', () => {
|
test('basic selectors', () => {
|
||||||
const foo = dux({
|
const foo = dux({
|
||||||
@ -22,3 +24,46 @@ test('basic selectors', () => {
|
|||||||
|
|
||||||
expect(foo.selectors.getY({ bar: { y: 3 } })).toBe(3);
|
expect(foo.selectors.getY({ bar: { y: 3 } })).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('splat selector', async () => {
|
||||||
|
const bar = new Updux({
|
||||||
|
initial: { id: 0, label: '' },
|
||||||
|
selectors: {
|
||||||
|
getLabel: R.prop('label'),
|
||||||
|
getLabelAppended: (state) => (suffix) => state.label + ' ' + suffix,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const foo = new Updux({
|
||||||
|
initial: [],
|
||||||
|
findSelectors: {
|
||||||
|
getBar: (state) => (id) => {
|
||||||
|
return state.find(matches({ id }));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
selectors: {
|
||||||
|
getNbrBars: (state) => state.length,
|
||||||
|
},
|
||||||
|
subduxes: {
|
||||||
|
'*': bar,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const state = [
|
||||||
|
{ id: 1, label: 'one' },
|
||||||
|
{ id: 2, label: 'two' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const store = foo.createStore(state);
|
||||||
|
|
||||||
|
expect(foo.selectors.getBar(state)(2).state).toMatchObject(state[1]);
|
||||||
|
expect(store.getState.getBar(2).state).toMatchObject(state[1]);
|
||||||
|
|
||||||
|
expect(store.getState.getNbrBars()).toBe(2);
|
||||||
|
|
||||||
|
expect(store.getState.getBar(1).getLabel()).toEqual('one');
|
||||||
|
|
||||||
|
expect(store.getState.getBar(1).getLabelAppended('plus one')).toEqual(
|
||||||
|
'one plus one',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
@ -2,7 +2,7 @@ import R from 'remeda';
|
|||||||
|
|
||||||
export function buildSelectors(
|
export function buildSelectors(
|
||||||
localSelectors,
|
localSelectors,
|
||||||
splatSelector = {},
|
findSelectors = {},
|
||||||
subduxes = {},
|
subduxes = {},
|
||||||
) {
|
) {
|
||||||
const subSelectors = Object.entries(subduxes).map(
|
const subSelectors = Object.entries(subduxes).map(
|
||||||
@ -19,18 +19,22 @@ export function buildSelectors(
|
|||||||
|
|
||||||
let splat = {};
|
let splat = {};
|
||||||
|
|
||||||
for (const name in splatSelector) {
|
for (const name in findSelectors) {
|
||||||
splat[name] =
|
splat[name] =
|
||||||
(state) =>
|
(mainState) =>
|
||||||
(...args) => {
|
(...args) => {
|
||||||
const value = splatSelector[name](state)(...args);
|
const state = findSelectors[name](mainState)(...args);
|
||||||
|
|
||||||
const res = () => value;
|
return R.merge(
|
||||||
return merge(
|
{ state },
|
||||||
res,
|
R.mapValues(
|
||||||
mapValues(
|
|
||||||
subduxes['*'].selectors,
|
subduxes['*'].selectors,
|
||||||
(selector) => () => selector(value),
|
(selector) =>
|
||||||
|
(...args) => {
|
||||||
|
let value = selector(state);
|
||||||
|
if (typeof value !== 'function') return value;
|
||||||
|
return value(...args);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
6
src/utils.js
Normal file
6
src/utils.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const matches = (conditions) => (target) =>
|
||||||
|
Object.entries(conditions).every(([key, value]) =>
|
||||||
|
typeof value === 'function'
|
||||||
|
? value(target[key])
|
||||||
|
: target[key] === value,
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user