Skip to content

Commit

Permalink
feat(selector): add createSelector and useSelector
Browse files Browse the repository at this point in the history
  • Loading branch information
smmoosavi committed Jun 18, 2020
1 parent ca0e3a0 commit 75024ba
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/selector/create-selector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { createWire } from '../wire/create-wire';
import { createSelector } from './create-selector';

describe('create-wire', () => {
it('should return wire', () => {
const wire = createWire(4);
const selector = createSelector({
get: ({ get }) => get(wire) * 2,
});
expect(selector.getValue()).toBe(8);
});
it('should change value', () => {
const wire = createWire(4);
const selector = createSelector({
get: ({ get }) => get(wire) * 2,
});
wire.setValue(3);
expect(selector.getValue()).toBe(6);
});
it('should update wire value', () => {
const wire = createWire(4);
const selector = createSelector({
get: ({ get }) => get(wire) * 2,
set: ({ set }, value: number) => set(wire, value / 2),
});
selector.setValue(6);
expect(wire.getValue()).toBe(3);
});
it('should return wire', () => {
const fn = jest.fn();
const wire = createWire(4);
const selector = createSelector({
get: ({ get }) => get(wire) * 2,
});
selector.subscribe(value => {
fn(value);
});
wire.setValue(3);
expect(fn).toBeCalledWith(6);
});
});
24 changes: 24 additions & 0 deletions src/selector/create-selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { createFnsWire } from '../fn-wire/create-fns-wire';
import {
createStateSelector,
ReadOnlySelectorOptions,
SelectorOptions,
WritableSelectorOptions,
} from '../state-selector/create-state-selector';
import { ReadonlyWire, Wire } from '../wire/wire';

export function createSelector<V, Fns = {}>(
options: WritableSelectorOptions<V>,
): Wire<V, Fns>;
export function createSelector<V, Fns = {}>(
options: ReadOnlySelectorOptions<V>,
): ReadonlyWire<V, Fns>;
export function createSelector<V, Fns = {}>(
options: SelectorOptions<V>,
): ReadonlyWire<V, Fns> | Wire<V, Fns> {
const [fnsWire, connectFnsWire] = createFnsWire<Fns>({});
const [stateSelector, connectStateSelector] = createStateSelector<V>(options);
connectFnsWire();
connectStateSelector();
return { ...fnsWire, ...stateSelector };
}
15 changes: 15 additions & 0 deletions src/selector/use-selector.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { renderHook } from '@testing-library/react-hooks';
import { useWire } from '../wire/use-wire';
import { useSelector } from './use-selector';

describe('use-selector', () => {
it('should return wire', () => {
const { result } = renderHook(() => {
const wire = useWire(null, 3);
const selector = useSelector({ get: ({ get }) => get(wire) * 2 });
return { selector };
});

expect(result.current.selector.getValue()).toBe(6);
});
});
23 changes: 23 additions & 0 deletions src/selector/use-selector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useMemo } from 'react';
import { useFnsWire } from '../fn-wire/use-fns-wire';
import {
ReadOnlySelectorOptions,
SelectorOptions,
WritableSelectorOptions,
} from '../state-selector/create-state-selector';
import { useStateSelector } from '../state-selector/use-state-selector';
import { ReadonlyWire, Wire } from '../wire/wire';

export function useSelector<V, Fns = {}>(
options: WritableSelectorOptions<V>,
): Wire<V, Fns>;
export function useSelector<V, Fns = {}>(
options: ReadOnlySelectorOptions<V>,
): ReadonlyWire<V, Fns>;
export function useSelector<V, Fns = {}>(
options: SelectorOptions<V>,
): ReadonlyWire<V, Fns> | Wire<V, Fns> {
const fnsWire = useFnsWire<Fns>(null);
const selector = useStateSelector<V>(options);
return useMemo(() => ({ ...fnsWire, ...selector }), [fnsWire, selector]);
}

0 comments on commit 75024ba

Please sign in to comment.