@subjected/react
Advanced tools
| "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./hooks/useStateContainer.ts"),r=require("./hooks/useComputed.ts"),t=require("./hooks/useSelector.ts"),u=require("./hooks/usePerform.ts"),o=require("./hooks/useLazyPerform.ts"),n=require("./hooks/useResolvers.ts");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f=s(e),i=s(r),a=s(t),l=s(u),c=s(o),d=s(n);Object.defineProperty(exports,"useStateContainer",{enumerable:!0,get:function(){return f.default}}),Object.defineProperty(exports,"useComputed",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(exports,"useSelector",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(exports,"usePerform",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(exports,"useLazyPerform",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(exports,"useResolvers",{enumerable:!0,get:function(){return d.default}}); |
| export{default as useStateContainer}from"./hooks/useStateContainer.ts";export{default as useComputed}from"./hooks/useComputed.ts";export{default as useSelector}from"./hooks/useSelector.ts";export{default as usePerform}from"./hooks/usePerform.ts";export{default as useLazyPerform}from"./hooks/useLazyPerform.ts";export{default as useResolvers}from"./hooks/useResolvers.ts"; |
| export declare class MissingSelectorFunctionError extends Error { | ||
| constructor(); | ||
| } |
| import { ComputedSelector } from '@subjected/core'; | ||
| declare function useComputed<ComputedState>(computedSelector: ComputedSelector<ComputedState>): ComputedState; | ||
| export default useComputed; |
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| declare function useLazyPerform<S extends StateShape>(stateContainer: StateContainer<S>): { | ||
| perform: (...params: import("@subjected/core").ActionResolverFunc<S>[]) => () => S; | ||
| performAsync: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => () => Promise<S>; | ||
| performAsyncSequence: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => () => Promise<S>; | ||
| }; | ||
| export default useLazyPerform; |
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| declare function usePerform<S extends StateShape>(stateContainer: StateContainer<S>): { | ||
| perform: (...params: import("@subjected/core").ActionResolverFunc<S>[]) => S; | ||
| performAsync: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => Promise<S>; | ||
| performAsyncSequence: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => Promise<S>; | ||
| }; | ||
| export default usePerform; |
| import { StateContainer, StateShape, ResolverMapping, ResolverMappingBinding, SyncResolverList, SyncResolverBinding } from '@subjected/core'; | ||
| declare function useResolvers<S extends StateShape, M extends ResolverMapping<S>>(container: StateContainer<S>, binding: M): ResolverMappingBinding<S, M>; | ||
| declare function useResolvers<S extends StateShape, M extends SyncResolverList<S>>(container: StateContainer<S>, binding: M): SyncResolverBinding<S, M>; | ||
| export default useResolvers; |
| import { StateShape, Selector, StateContainer } from '@subjected/core'; | ||
| declare function useSelector<S extends StateShape, SelectedState>(selector: Selector<S, SelectedState>): [SelectedState, S]; | ||
| declare function useSelector<S extends StateShape, SelectedState>(container: StateContainer<S>, selectorFunc: (state: S) => SelectedState): [SelectedState, S]; | ||
| export default useSelector; |
| import { StateShape, StateContainer } from '@subjected/core'; | ||
| declare function useStateContainer<S extends StateShape>(stateContainer: StateContainer<S>): S; | ||
| export default useStateContainer; |
| import useStateContainer from './hooks/useStateContainer'; | ||
| import useComputed from './hooks/useComputed'; | ||
| import useSelector from './hooks/useSelector'; | ||
| import usePerform from './hooks/usePerform'; | ||
| import useLazyPerform from './hooks/useLazyPerform'; | ||
| import useResolvers from './hooks/useResolvers'; | ||
| export { useStateContainer, useComputed, useSelector, usePerform, useLazyPerform, useResolvers }; |
+19
-0
@@ -6,2 +6,21 @@ # Change Log | ||
| # 0.2.0 (2020-10-05) | ||
| ### Features | ||
| * add action generator recursive resolution ([c93cbd7](https://github.com/BrandonBurrus/subjected/commit/c93cbd7fd27f8716dbc48e7428a4066b85d64128)) | ||
| * added indirect state detection to useSelector ([c042aae](https://github.com/BrandonBurrus/subjected/commit/c042aaec20e74cc4b3271607520ef535214d314f)) | ||
| * added initial react bindings for core api ([2a1ee14](https://github.com/BrandonBurrus/subjected/commit/2a1ee14361a406ef5d38d94ff726dd03e5cf4e19)) | ||
| * added new selector ref management to useSelector ([5a369bb](https://github.com/BrandonBurrus/subjected/commit/5a369bb27c33eb154bbded5348772d90fbf30d21)) | ||
| * added target grouping algorithm to computed selector ([de74314](https://github.com/BrandonBurrus/subjected/commit/de74314353ea54be6747f82cdc4ea588cb28732d)) | ||
| * implemented resolver binding ([33fdd13](https://github.com/BrandonBurrus/subjected/commit/33fdd1354a28846d5105b5e55440300285cc64c4)) | ||
| * implemented resolver-centric react hooks ([82ed33b](https://github.com/BrandonBurrus/subjected/commit/82ed33ba39c9a0cf87428e3238790738aa73c3dc)) | ||
| * implemented useSelector react hook ([109a8d6](https://github.com/BrandonBurrus/subjected/commit/109a8d6cfe65db76eb6e46be5fad16e9605a472f)) | ||
| * implemented useStateContainer react hook ([f91250a](https://github.com/BrandonBurrus/subjected/commit/f91250a4fa0aede625c169b92e4baf3cfaae62e2)) | ||
| # 0.1.0 (2020-10-02) | ||
@@ -8,0 +27,0 @@ |
+18
-12
| { | ||
| "name": "@subjected/react", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "React bindings for the Subjected library", | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "main": "dist/cjs/index.js", | ||
| "module": "dist/esm/index.js", | ||
| "types": "dist/types/index.d.ts", | ||
| "author": "Brandon Burrus <brandon@burrus.io> (https://brandonburrus.com/)", | ||
| "license": "MIT", | ||
| "scripts": { | ||
| "build": "rm -rf dist && tsc -p tsconfig.json", | ||
| "prebuild": "rimraf dist", | ||
| "build": "rollup -c", | ||
| "test": "jest --verbose -e --notify", | ||
@@ -18,2 +20,7 @@ "test:w": "jest --verbose -e --notify --watch", | ||
| }, | ||
| "files": [ | ||
| "dist", | ||
| "README.md" | ||
| ], | ||
| "sideEffects": false, | ||
| "jest": { | ||
@@ -24,11 +31,11 @@ "displayName": { | ||
| }, | ||
| "preset": "ts-jest", | ||
| "preset": "ts-jest/presets/js-with-ts", | ||
| "testEnvironment": "jsdom", | ||
| "transform": { | ||
| "^.+\\.ts(x)?$": "ts-jest" | ||
| } | ||
| "transform": {} | ||
| }, | ||
| "dependencies": { | ||
| "@subjected/core": "^0.1.0", | ||
| "react": "^16.13.1" | ||
| "@babel/runtime": "^7.11.2", | ||
| "@subjected/core": "^0.2.0", | ||
| "react": "^16.13.1", | ||
| "rxjs": "^6.6.3" | ||
| }, | ||
@@ -43,4 +50,3 @@ "devDependencies": { | ||
| "react-test-renderer": "^16.13.1" | ||
| }, | ||
| "gitHead": "481f0ae798fe9196e6a64357ded473442125d222" | ||
| } | ||
| } |
| import { MissingSelectorFunctionError } from '../src/errors'; | ||
| describe('errors', () => { | ||
| describe('MissingSelectorFunctionError', () => { | ||
| test('instantiates', () => { | ||
| expect(new MissingSelectorFunctionError()).toBeInstanceOf(Error); | ||
| }); | ||
| test('displays correct messages', () => { | ||
| expect(new MissingSelectorFunctionError().message).toMatchInlineSnapshot( | ||
| `"A StateContainer was passed to useSelector without a selector function, did you mean to pass one as a second argument to useSelector?"` | ||
| ); | ||
| }); | ||
| }); | ||
| }); |
| import React from 'react'; | ||
| import useComputed from '../../src/hooks/useComputed'; | ||
| import { StateContainer, ComputedSelector } from '@subjected/core'; | ||
| import { render, fireEvent, act } from '@testing-library/react'; | ||
| describe('useComputed', () => { | ||
| type MockState = number[]; | ||
| let mockContainer: StateContainer<MockState>; | ||
| beforeEach(() => { | ||
| mockContainer = StateContainer.of([1, 2, 3]); | ||
| }); | ||
| const addItem = (item: number) => | ||
| function*(state: number[]) { | ||
| return [...state, item]; | ||
| }; | ||
| test('mounts without crashing', () => { | ||
| function MockComponent() { | ||
| const sum = useComputed( | ||
| ComputedSelector.of(mockContainer, state => | ||
| state.reduce((a: number, n: number) => a + n, 0) | ||
| ) | ||
| ); | ||
| return <p>{sum}</p>; | ||
| } | ||
| const { container } = render(<MockComponent />); | ||
| expect(container).toBeDefined(); | ||
| }); | ||
| test('rerenders from recompute when performing action resolver', () => { | ||
| function MockComponent() { | ||
| const sum = useComputed( | ||
| ComputedSelector.of(mockContainer, state => | ||
| state.reduce((a: number, n: number) => a + n, 0) | ||
| ) | ||
| ); | ||
| return ( | ||
| <> | ||
| <p>{sum}</p> | ||
| <button type='button' onClick={() => mockContainer.perform(addItem(1))}> | ||
| update | ||
| </button> | ||
| </> | ||
| ); | ||
| } | ||
| const { getByText } = render(<MockComponent />); | ||
| expect(getByText(/6/iu)).toBeDefined(); | ||
| act(() => { | ||
| fireEvent.click(getByText('update')); | ||
| }); | ||
| expect(getByText(/7/iu)).toBeDefined(); | ||
| act(() => { | ||
| fireEvent.click(getByText('update')); | ||
| }); | ||
| expect(getByText(/8/iu)).toBeDefined(); | ||
| }); | ||
| }); |
| import useLazyPerform from '../../src/hooks/useLazyPerform'; | ||
| import { StateContainer } from '@subjected/core'; | ||
| import { renderHook } from '@testing-library/react-hooks'; | ||
| describe('useLazyPerform', () => { | ||
| type MockState = { state: number }; | ||
| let container: StateContainer<MockState>; | ||
| beforeEach(() => { | ||
| container = StateContainer.of({ state: 0 }); | ||
| }); | ||
| test('mounts without crashing', () => { | ||
| const { result } = renderHook(() => useLazyPerform(container)); | ||
| expect(result.current).toBeDefined(); | ||
| }); | ||
| test('lazily defers the container perform function', () => { | ||
| const { result } = renderHook(() => useLazyPerform(container)); | ||
| expect(result.current.perform).toBeDefined(); | ||
| function* increment({ state }: MockState) { | ||
| return { state: state + 1 }; | ||
| } | ||
| const lazyPerformIncrement = result.current.perform(increment); | ||
| expect(container.state).toMatchObject({ state: 0 }); | ||
| lazyPerformIncrement(); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| test('lazily defers the container performAsync function', async () => { | ||
| const { result } = renderHook(() => useLazyPerform(container)); | ||
| expect(result.current.performAsync).toBeDefined(); | ||
| async function* incrementAsync({ state }: MockState) { | ||
| return Promise.resolve({ state: state + 1 }); | ||
| } | ||
| const lazyPerformIncrementAsync = result.current.performAsync(incrementAsync); | ||
| expect(container.state).toMatchObject({ state: 0 }); | ||
| await lazyPerformIncrementAsync(); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| test('lazily defers the container performAsyncSequence function', async () => { | ||
| const { result } = renderHook(() => useLazyPerform(container)); | ||
| expect(result.current.performAsyncSequence).toBeDefined(); | ||
| async function* incrementAsync({ state }: MockState) { | ||
| return Promise.resolve({ state: state + 1 }); | ||
| } | ||
| const lazyPerformIncrementAsyncSequence = result.current.performAsyncSequence(incrementAsync); | ||
| expect(container.state).toMatchObject({ state: 0 }); | ||
| await lazyPerformIncrementAsyncSequence(); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| }); |
| import usePerform from '../../src/hooks/usePerform'; | ||
| import { StateContainer } from '@subjected/core'; | ||
| import { renderHook } from '@testing-library/react-hooks'; | ||
| describe('usePerform', () => { | ||
| type MockState = { state: number }; | ||
| let container: StateContainer<MockState>; | ||
| beforeEach(() => { | ||
| container = StateContainer.of({ state: 0 }); | ||
| }); | ||
| test('mounts without crashing', () => { | ||
| const { result } = renderHook(() => usePerform(container)); | ||
| expect(result.current).toBeDefined(); | ||
| }); | ||
| test('defers the container perform function', () => { | ||
| const { result } = renderHook(() => usePerform(container)); | ||
| expect(result.current.perform).toBeDefined(); | ||
| function* increment({ state }: MockState) { | ||
| return { state: state + 1 }; | ||
| } | ||
| result.current.perform(increment); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| test('defers the container performAsync function', async () => { | ||
| const { result } = renderHook(() => usePerform(container)); | ||
| expect(result.current.performAsync).toBeDefined(); | ||
| async function* incrementAsync({ state }: MockState) { | ||
| return Promise.resolve({ state: state + 1 }); | ||
| } | ||
| await result.current.performAsync(incrementAsync); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| test('defers the container performAsyncSequence function', async () => { | ||
| const { result } = renderHook(() => usePerform(container)); | ||
| expect(result.current.performAsyncSequence).toBeDefined(); | ||
| async function* incrementAsync({ state }: MockState) { | ||
| return Promise.resolve({ state: state + 1 }); | ||
| } | ||
| await result.current.performAsyncSequence(incrementAsync); | ||
| expect(container.state).toMatchObject({ state: 1 }); | ||
| }); | ||
| }); |
| import useResolvers from '../../src/hooks/useResolvers'; | ||
| import { StateContainer } from '@subjected/core'; | ||
| import { renderHook } from '@testing-library/react-hooks'; | ||
| describe('useResolvers', () => { | ||
| let container: StateContainer<number[]>; | ||
| beforeEach(() => { | ||
| container = StateContainer.of([1, 2, 3]); | ||
| }); | ||
| const appendNum = (n: number) => | ||
| function*(state: number[]) { | ||
| return [...state, n]; | ||
| }; | ||
| const resetAsync = () => | ||
| async function*() { | ||
| return Promise.resolve([]); | ||
| }; | ||
| test('mounts without crashing', () => { | ||
| const { result } = renderHook(() => useResolvers(container, { appendNum })); | ||
| expect(result.current).toBeDefined(); | ||
| }); | ||
| test('mounts sync resolver list by default', () => { | ||
| const { result } = renderHook(() => useResolvers(container, { appendNum })); | ||
| expect(container.state).toMatchObject([1, 2, 3]); | ||
| result.current.appendNum(4); | ||
| expect(container.state).toMatchObject([1, 2, 3, 4]); | ||
| }); | ||
| test('mounts sync resolver list', () => { | ||
| const { result } = renderHook(() => useResolvers(container, { sync: { appendNum } })); | ||
| expect(container.state).toMatchObject([1, 2, 3]); | ||
| result.current.appendNum(4); | ||
| expect(container.state).toMatchObject([1, 2, 3, 4]); | ||
| }); | ||
| test('mounts async resolver list', async () => { | ||
| const { result } = renderHook(() => useResolvers(container, { async: { resetAsync } })); | ||
| expect(container.state).toMatchObject([1, 2, 3]); | ||
| await result.current.resetAsync(); | ||
| expect(container.state).toMatchObject([]); | ||
| }); | ||
| }); |
| import React from 'react'; | ||
| import useSelector from '../../src/hooks/useSelector'; | ||
| import { StateContainer, Selector } from '@subjected/core'; | ||
| import { render, fireEvent, act } from '@testing-library/react'; | ||
| import { renderHook } from '@testing-library/react-hooks'; | ||
| import { MissingSelectorFunctionError } from '../../src/errors'; | ||
| describe('useSelector', () => { | ||
| type MockState = { text: string }; | ||
| let mockContainer: StateContainer<MockState>; | ||
| beforeAll(() => { | ||
| // React throws console errors around the errors from this hook | ||
| jest.spyOn(console, 'error').mockImplementation(() => null); | ||
| }); | ||
| beforeEach(() => { | ||
| mockContainer = StateContainer.of({ text: 'TEST' }); | ||
| }); | ||
| const updateText = (text: string) => | ||
| function*() { | ||
| return { text }; | ||
| }; | ||
| test('mounts without crashing', () => { | ||
| function MockComponent() { | ||
| const [text] = useSelector(Selector.of(mockContainer, state => state.text)); | ||
| return <p>{text}</p>; | ||
| } | ||
| const { container } = render(<MockComponent />); | ||
| expect(container).toBeDefined(); | ||
| }); | ||
| test('rerenders when performing action resolver', () => { | ||
| function MockComponent() { | ||
| const [text] = useSelector(Selector.of(mockContainer, state => state.text)); | ||
| return ( | ||
| <> | ||
| <p>{text}</p> | ||
| <button type='button' onClick={() => mockContainer.perform(updateText('CHANGE'))}> | ||
| update | ||
| </button> | ||
| </> | ||
| ); | ||
| } | ||
| const { getByText } = render(<MockComponent />); | ||
| expect(getByText(/test/iu)).toBeDefined(); | ||
| act(() => { | ||
| fireEvent.click(getByText('update')); | ||
| }); | ||
| expect(getByText(/change/iu)).toBeDefined(); | ||
| }); | ||
| test('creates a managed reference to a selector', () => { | ||
| const { result } = renderHook(() => useSelector(mockContainer, state => state.text)); | ||
| expect(result.current[0]).toBe(mockContainer.state.text); | ||
| expect(result.current[1]).toMatchObject(mockContainer.state); | ||
| act(() => { | ||
| mockContainer.perform(updateText('CHANGE')); | ||
| }); | ||
| expect(result.current[0]).toBe(mockContainer.state.text); | ||
| expect(result.current[1]).toMatchObject(mockContainer.state); | ||
| }); | ||
| test('throws an error if no selector is passed with a state container', () => { | ||
| function MockComponent() { | ||
| useSelector(mockContainer, undefined as any); | ||
| return <p>TEST</p>; | ||
| } | ||
| expect(() => render(<MockComponent />)).toThrowError(new MissingSelectorFunctionError()); | ||
| }); | ||
| }); |
| import React from 'react'; | ||
| import useStateContainer from '../../src/hooks/useStateContainer'; | ||
| import { StateContainer } from '@subjected/core'; | ||
| import { render, fireEvent, act } from '@testing-library/react'; | ||
| describe('useStateContainer', () => { | ||
| type MockState = { text: string }; | ||
| let mockContainer: StateContainer<MockState>; | ||
| beforeEach(() => { | ||
| mockContainer = StateContainer.of({ text: 'Hello, world!' }); | ||
| }); | ||
| const updateText = (text: string) => | ||
| function* () { | ||
| return { text }; | ||
| }; | ||
| test('mounts without crashing', () => { | ||
| function MockComponent() { | ||
| const { text } = useStateContainer(mockContainer); | ||
| return <p>{text}</p>; | ||
| } | ||
| const { container } = render(<MockComponent />); | ||
| expect(container).toBeDefined(); | ||
| }); | ||
| test('rerenders when performing action resolver', () => { | ||
| function MockComponent() { | ||
| const { text } = useStateContainer(mockContainer); | ||
| return ( | ||
| <> | ||
| <p>{text}</p> | ||
| <button type='button' onClick={() => mockContainer.perform(updateText('TEST'))}> | ||
| update | ||
| </button> | ||
| </> | ||
| ); | ||
| } | ||
| const { getByText } = render(<MockComponent />); | ||
| expect(getByText('Hello, world!')).toBeDefined(); | ||
| act(() => { | ||
| fireEvent.click(getByText('update')); | ||
| }); | ||
| expect(getByText(/test/iu)).toBeDefined(); | ||
| }); | ||
| }); |
| import * as SubjectedReact from '../src/index'; // eslint-disable-line | ||
| describe('index', () => { | ||
| test('exports @subjected/react', () => { | ||
| expect(SubjectedReact).toMatchInlineSnapshot(` | ||
| Object { | ||
| "useComputed": [Function], | ||
| "useLazyPerform": [Function], | ||
| "usePerform": [Function], | ||
| "useResolvers": [Function], | ||
| "useSelector": [Function], | ||
| "useStateContainer": [Function], | ||
| } | ||
| `); | ||
| }); | ||
| }); |
| export declare class MissingSelectorFunctionError extends Error { | ||
| constructor(); | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.MissingSelectorFunctionError = void 0; | ||
| class MissingSelectorFunctionError extends Error { | ||
| constructor() { | ||
| super(); | ||
| this.message = | ||
| 'A StateContainer was passed to useSelector without a selector function, did you mean to pass one as a second argument to useSelector?'; | ||
| } | ||
| } | ||
| exports.MissingSelectorFunctionError = MissingSelectorFunctionError; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxNQUFhLDRCQUE2QixTQUFRLEtBQUs7SUFDckQ7UUFDRSxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPO1lBQ1YsdUlBQXVJLENBQUM7SUFDNUksQ0FBQztDQUNGO0FBTkQsb0VBTUMifQ== |
| import { ComputedSelector } from '@subjected/core'; | ||
| declare function useComputed<ComputedState>(computedSelector: ComputedSelector<ComputedState>): ComputedState; | ||
| export default useComputed; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const react_1 = require("react"); | ||
| const operators_1 = require("rxjs/operators"); | ||
| function useComputed(computedSelector) { | ||
| const [state, setState] = react_1.useState(computedSelector.state); | ||
| react_1.useEffect(() => { | ||
| const subscription = computedSelector.observable.pipe(operators_1.skip(1)).subscribe(nextState => { | ||
| setState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| }, []); | ||
| return state; | ||
| } | ||
| exports.default = useComputed; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlQ29tcHV0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaG9va3MvdXNlQ29tcHV0ZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBNEM7QUFFNUMsOENBQXNDO0FBTXRDLFNBQVMsV0FBVyxDQUFnQixnQkFBaUQ7SUFDbkYsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsR0FBRyxnQkFBUSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRTNELGlCQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnQkFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ25GLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0QixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUVQLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELGtCQUFlLFdBQVcsQ0FBQyJ9 |
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| declare function useLazyPerform<S extends StateShape>(stateContainer: StateContainer<S>): { | ||
| perform: (...params: import("@subjected/core").ActionResolverFunc<S>[]) => () => S; | ||
| performAsync: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => () => Promise<S>; | ||
| performAsyncSequence: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => () => Promise<S>; | ||
| }; | ||
| export default useLazyPerform; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const react_1 = require("react"); | ||
| function useLazyPerform(stateContainer) { | ||
| const perform = react_1.useCallback((...params) => () => stateContainer.perform(...params), [stateContainer]); | ||
| const performAsync = react_1.useCallback((...params) => () => stateContainer.performAsync(...params), [stateContainer]); | ||
| const performAsyncSequence = react_1.useCallback((...params) => () => stateContainer.performAsyncSequence(...params), [stateContainer]); | ||
| return { | ||
| perform, | ||
| performAsync, | ||
| performAsyncSequence, | ||
| }; | ||
| } | ||
| exports.default = useLazyPerform; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlTGF6eVBlcmZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaG9va3MvdXNlTGF6eVBlcmZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBb0M7QUFtQnBDLFNBQVMsY0FBYyxDQUF1QixjQUFpQztJQUM3RSxNQUFNLE9BQU8sR0FBRyxtQkFBVyxDQUN6QixDQUFDLEdBQUcsTUFBaUQsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQzdELGNBQWMsQ0FBQyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsRUFDbkMsQ0FBQyxjQUFjLENBQUMsQ0FDakIsQ0FBQztJQUVGLE1BQU0sWUFBWSxHQUFHLG1CQUFXLENBQzlCLENBQUMsR0FBRyxNQUFzRCxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FDbEUsY0FBYyxDQUFDLFlBQVksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUN4QyxDQUFDLGNBQWMsQ0FBQyxDQUNqQixDQUFDO0lBRUYsTUFBTSxvQkFBb0IsR0FBRyxtQkFBVyxDQUN0QyxDQUFDLEdBQUcsTUFBOEQsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQzFFLGNBQWMsQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUNoRCxDQUFDLGNBQWMsQ0FBQyxDQUNqQixDQUFDO0lBRUYsT0FBTztRQUNMLE9BQU87UUFDUCxZQUFZO1FBQ1osb0JBQW9CO0tBQ3JCLENBQUM7QUFDSixDQUFDO0FBRUQsa0JBQWUsY0FBYyxDQUFDIn0= |
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| declare function usePerform<S extends StateShape>(stateContainer: StateContainer<S>): { | ||
| perform: (...params: import("@subjected/core").ActionResolverFunc<S>[]) => S; | ||
| performAsync: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => Promise<S>; | ||
| performAsyncSequence: (...params: import("@subjected/core").AsyncActionResolverFunc<S>[]) => Promise<S>; | ||
| }; | ||
| export default usePerform; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const react_1 = require("react"); | ||
| function usePerform(stateContainer) { | ||
| const perform = react_1.useCallback((...params) => stateContainer.perform(...params), [stateContainer]); | ||
| const performAsync = react_1.useCallback((...params) => stateContainer.performAsync(...params), [stateContainer]); | ||
| const performAsyncSequence = react_1.useCallback((...params) => stateContainer.performAsyncSequence(...params), [stateContainer]); | ||
| return { | ||
| perform, | ||
| performAsync, | ||
| performAsyncSequence, | ||
| }; | ||
| } | ||
| exports.default = usePerform; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlUGVyZm9ybS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ob29rcy91c2VQZXJmb3JtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQW9DO0FBT3BDLFNBQVMsVUFBVSxDQUF1QixjQUFpQztJQUN6RSxNQUFNLE9BQU8sR0FBRyxtQkFBVyxDQUN6QixDQUFDLEdBQUcsTUFBaUQsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUMzRixDQUFDLGNBQWMsQ0FBQyxDQUNqQixDQUFDO0lBRUYsTUFBTSxZQUFZLEdBQUcsbUJBQVcsQ0FDOUIsQ0FBQyxHQUFHLE1BQXNELEVBQUUsRUFBRSxDQUM1RCxjQUFjLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQ3hDLENBQUMsY0FBYyxDQUFDLENBQ2pCLENBQUM7SUFFRixNQUFNLG9CQUFvQixHQUFHLG1CQUFXLENBQ3RDLENBQUMsR0FBRyxNQUE4RCxFQUFFLEVBQUUsQ0FDcEUsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQ2hELENBQUMsY0FBYyxDQUFDLENBQ2pCLENBQUM7SUFFRixPQUFPO1FBQ0wsT0FBTztRQUNQLFlBQVk7UUFDWixvQkFBb0I7S0FDckIsQ0FBQztBQUNKLENBQUM7QUFFRCxrQkFBZSxVQUFVLENBQUMifQ== |
| import { StateContainer, StateShape, ResolverMapping, ResolverMappingBinding, SyncResolverList, SyncResolverBinding } from '@subjected/core'; | ||
| declare function useResolvers<S extends StateShape, M extends ResolverMapping<S>>(container: StateContainer<S>, binding: M): ResolverMappingBinding<S, M>; | ||
| declare function useResolvers<S extends StateShape, M extends SyncResolverList<S>>(container: StateContainer<S>, binding: M): SyncResolverBinding<S, M>; | ||
| export default useResolvers; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const core_1 = require("@subjected/core"); | ||
| const react_1 = require("react"); | ||
| function useResolvers(container, binding) { | ||
| const bindings = react_1.useMemo(() => { | ||
| return core_1.bindResolvers(container, binding); | ||
| }, [container, binding]); | ||
| return bindings; | ||
| } | ||
| exports.default = useResolvers; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlUmVzb2x2ZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hvb2tzL3VzZVJlc29sdmVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDBDQVN5QjtBQUN6QixpQ0FBZ0M7QUFhaEMsU0FBUyxZQUFZLENBQ25CLFNBQTRCLEVBQzVCLE9BQTBCO0lBRTFCLE1BQU0sUUFBUSxHQUFHLGVBQU8sQ0FBQyxHQUFHLEVBQUU7UUFDNUIsT0FBTyxvQkFBYSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMzQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUV6QixPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQsa0JBQWUsWUFBWSxDQUFDIn0= |
| import { StateShape, Selector, StateContainer } from '@subjected/core'; | ||
| declare function useSelector<S extends StateShape, SelectedState>(selector: Selector<S, SelectedState>): [SelectedState, S]; | ||
| declare function useSelector<S extends StateShape, SelectedState>(container: StateContainer<S>, selectorFunc: (state: S) => SelectedState): [SelectedState, S]; | ||
| export default useSelector; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const react_1 = require("react"); | ||
| const core_1 = require("@subjected/core"); | ||
| const operators_1 = require("rxjs/operators"); | ||
| const errors_1 = require("../errors"); | ||
| function useSelector(selectorOrContainer, selectorFunc) { | ||
| let selector; | ||
| if (selectorOrContainer instanceof core_1.StateContainer) { | ||
| if (!selectorFunc) { | ||
| throw new errors_1.MissingSelectorFunctionError(); | ||
| } | ||
| selector = react_1.useRef(new core_1.Selector(selectorOrContainer, selectorFunc)).current; | ||
| } | ||
| else { | ||
| selector = selectorOrContainer; | ||
| } | ||
| const [state, setState] = react_1.useState(selector.state); | ||
| react_1.useEffect(() => { | ||
| const subscription = selector.observable.pipe(operators_1.skip(1)).subscribe(nextState => { | ||
| setState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| }, []); | ||
| return [state, selector.stateSource.values().next().value.state]; | ||
| } | ||
| exports.default = useSelector; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlU2VsZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaG9va3MvdXNlU2VsZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBb0Q7QUFDcEQsMENBQXVFO0FBQ3ZFLDhDQUFzQztBQUN0QyxzQ0FBeUQ7QUFZekQsU0FBUyxXQUFXLENBQ2xCLG1CQUFtRSxFQUNuRSxZQUEwQztJQUUxQyxJQUFJLFFBQW9DLENBQUM7SUFFekMsSUFBSSxtQkFBbUIsWUFBWSxxQkFBYyxFQUFFO1FBQ2pELElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDakIsTUFBTSxJQUFJLHFDQUE0QixFQUFFLENBQUM7U0FDMUM7UUFFRCxRQUFRLEdBQUcsY0FBTSxDQUFDLElBQUksZUFBUSxDQUFDLG1CQUFtQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0tBQzVFO1NBQU07UUFDTCxRQUFRLEdBQUcsbUJBQW1CLENBQUM7S0FDaEM7SUFDRCxNQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxHQUFHLGdCQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRW5ELGlCQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0JBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUMzRSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUUxQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFUCxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRCxrQkFBZSxXQUFXLENBQUMifQ== |
| import { StateShape, StateContainer } from '@subjected/core'; | ||
| declare function useStateContainer<S extends StateShape>(stateContainer: StateContainer<S>): S; | ||
| export default useStateContainer; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const react_1 = require("react"); | ||
| const operators_1 = require("rxjs/operators"); | ||
| function useStateContainer(stateContainer) { | ||
| const [state, updateState] = react_1.useState(stateContainer.state); | ||
| react_1.useEffect(() => { | ||
| const subscription = stateContainer.observable.pipe(operators_1.skip(1)).subscribe(nextState => { | ||
| updateState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| }, []); | ||
| return state; | ||
| } | ||
| exports.default = useStateContainer; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlU3RhdGVDb250YWluZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaG9va3MvdXNlU3RhdGVDb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBNEM7QUFFNUMsOENBQXNDO0FBS3RDLFNBQVMsaUJBQWlCLENBQXVCLGNBQWlDO0lBQ2hGLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEdBQUcsZ0JBQVEsQ0FBSSxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFL0QsaUJBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixNQUFNLFlBQVksR0FBRyxjQUFjLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnQkFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQ2pGLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUVQLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELGtCQUFlLGlCQUFpQixDQUFDIn0= |
| import useStateContainer from './hooks/useStateContainer'; | ||
| import useComputed from './hooks/useComputed'; | ||
| import useSelector from './hooks/useSelector'; | ||
| import usePerform from './hooks/usePerform'; | ||
| import useLazyPerform from './hooks/useLazyPerform'; | ||
| import useResolvers from './hooks/useResolvers'; | ||
| export { useStateContainer, useComputed, useSelector, usePerform, useLazyPerform, useResolvers }; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.useResolvers = exports.useLazyPerform = exports.usePerform = exports.useSelector = exports.useComputed = exports.useStateContainer = void 0; | ||
| const useStateContainer_1 = __importDefault(require("./hooks/useStateContainer")); | ||
| exports.useStateContainer = useStateContainer_1.default; | ||
| const useComputed_1 = __importDefault(require("./hooks/useComputed")); | ||
| exports.useComputed = useComputed_1.default; | ||
| const useSelector_1 = __importDefault(require("./hooks/useSelector")); | ||
| exports.useSelector = useSelector_1.default; | ||
| const usePerform_1 = __importDefault(require("./hooks/usePerform")); | ||
| exports.usePerform = usePerform_1.default; | ||
| const useLazyPerform_1 = __importDefault(require("./hooks/useLazyPerform")); | ||
| exports.useLazyPerform = useLazyPerform_1.default; | ||
| const useResolvers_1 = __importDefault(require("./hooks/useResolvers")); | ||
| exports.useResolvers = useResolvers_1.default; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsa0ZBQTBEO0FBT2pELDRCQVBGLDJCQUFpQixDQU9FO0FBTjFCLHNFQUE4QztBQU1sQixzQkFOckIscUJBQVcsQ0FNcUI7QUFMdkMsc0VBQThDO0FBS0wsc0JBTGxDLHFCQUFXLENBS2tDO0FBSnBELG9FQUE0QztBQUlVLHFCQUovQyxvQkFBVSxDQUkrQztBQUhoRSw0RUFBb0Q7QUFHYyx5QkFIM0Qsd0JBQWMsQ0FHMkQ7QUFGaEYsd0VBQWdEO0FBRWtDLHVCQUYzRSxzQkFBWSxDQUUyRSJ9 |
| Copyright 2020 Brandon Burrus | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| export class MissingSelectorFunctionError extends Error { | ||
| constructor() { | ||
| super(); | ||
| this.message = | ||
| 'A StateContainer was passed to useSelector without a selector function, did you mean to pass one as a second argument to useSelector?'; | ||
| } | ||
| } |
| import { useState, useEffect } from 'react'; | ||
| import { ComputedSelector } from '@subjected/core'; | ||
| import { skip } from 'rxjs/operators'; | ||
| /** | ||
| * Creates a subscription to a Computed Selector and returns the | ||
| * current computed value | ||
| */ | ||
| function useComputed<ComputedState>(computedSelector: ComputedSelector<ComputedState>) { | ||
| const [state, setState] = useState(computedSelector.state); | ||
| useEffect(() => { | ||
| const subscription = computedSelector.observable.pipe(skip(1)).subscribe(nextState => { | ||
| setState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, []); | ||
| return state; | ||
| } | ||
| export default useComputed; |
| import { useCallback } from 'react'; | ||
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| /** | ||
| * Exactly like usePerform, returns the perform(), performAsync(), and performAsyncSequence() | ||
| * functions from a state container, except with an additional lazy invokation. | ||
| * | ||
| * This enables something like the following example: | ||
| * ``` | ||
| * function Example() { | ||
| * const { perform } = useLazyPerform(); | ||
| * | ||
| * return <button onClick={perform(someAction())}> | ||
| * Click me! | ||
| * </button>; | ||
| * } | ||
| * ``` | ||
| * (The difference being that usePerform youd have to do onClick={() => perform()} instead) | ||
| */ | ||
| function useLazyPerform<S extends StateShape>(stateContainer: StateContainer<S>) { | ||
| const perform = useCallback( | ||
| (...params: Parameters<typeof stateContainer.perform>) => () => | ||
| stateContainer.perform(...params), | ||
| [stateContainer] | ||
| ); | ||
| const performAsync = useCallback( | ||
| (...params: Parameters<typeof stateContainer.performAsync>) => () => | ||
| stateContainer.performAsync(...params), | ||
| [stateContainer] | ||
| ); | ||
| const performAsyncSequence = useCallback( | ||
| (...params: Parameters<typeof stateContainer.performAsyncSequence>) => () => | ||
| stateContainer.performAsyncSequence(...params), | ||
| [stateContainer] | ||
| ); | ||
| return { | ||
| perform, | ||
| performAsync, | ||
| performAsyncSequence, | ||
| }; | ||
| } | ||
| export default useLazyPerform; |
| import { useCallback } from 'react'; | ||
| import { StateContainer, StateShape } from '@subjected/core'; | ||
| /** | ||
| * Returns the perform(), performAsync(), and performAsyncSequence() functions | ||
| * from a state container. | ||
| */ | ||
| function usePerform<S extends StateShape>(stateContainer: StateContainer<S>) { | ||
| const perform = useCallback( | ||
| (...params: Parameters<typeof stateContainer.perform>) => stateContainer.perform(...params), | ||
| [stateContainer] | ||
| ); | ||
| const performAsync = useCallback( | ||
| (...params: Parameters<typeof stateContainer.performAsync>) => | ||
| stateContainer.performAsync(...params), | ||
| [stateContainer] | ||
| ); | ||
| const performAsyncSequence = useCallback( | ||
| (...params: Parameters<typeof stateContainer.performAsyncSequence>) => | ||
| stateContainer.performAsyncSequence(...params), | ||
| [stateContainer] | ||
| ); | ||
| return { | ||
| perform, | ||
| performAsync, | ||
| performAsyncSequence, | ||
| }; | ||
| } | ||
| export default usePerform; |
| import { | ||
| bindResolvers, | ||
| StateContainer, | ||
| PerformBinding, | ||
| StateShape, | ||
| ResolverMapping, | ||
| ResolverMappingBinding, | ||
| SyncResolverList, | ||
| SyncResolverBinding, | ||
| } from '@subjected/core'; | ||
| import { useMemo } from 'react'; | ||
| /** | ||
| * Takes a resolver map and binds it to a specific state container | ||
| */ | ||
| function useResolvers<S extends StateShape, M extends ResolverMapping<S>>( | ||
| container: StateContainer<S>, | ||
| binding: M | ||
| ): ResolverMappingBinding<S, M>; | ||
| function useResolvers<S extends StateShape, M extends SyncResolverList<S>>( | ||
| container: StateContainer<S>, | ||
| binding: M | ||
| ): SyncResolverBinding<S, M>; | ||
| function useResolvers<S extends StateShape>( | ||
| container: StateContainer<S>, | ||
| binding: PerformBinding<S> | ||
| ) { | ||
| const bindings = useMemo(() => { | ||
| return bindResolvers(container, binding); | ||
| }, [container, binding]); | ||
| return bindings; | ||
| } | ||
| export default useResolvers; |
| import { useState, useEffect, useRef } from 'react'; | ||
| import { StateShape, Selector, StateContainer } from '@subjected/core'; | ||
| import { skip } from 'rxjs/operators'; | ||
| import { MissingSelectorFunctionError } from '../errors'; | ||
| /** | ||
| * Creates a subscription to a Selector and returns the current selected substate | ||
| */ | ||
| function useSelector<S extends StateShape, SelectedState>( | ||
| selector: Selector<S, SelectedState> | ||
| ): [SelectedState, S]; | ||
| function useSelector<S extends StateShape, SelectedState>( | ||
| container: StateContainer<S>, | ||
| selectorFunc: (state: S) => SelectedState | ||
| ): [SelectedState, S]; | ||
| function useSelector<S extends StateShape, SelectedState>( | ||
| selectorOrContainer: Selector<S, SelectedState> | StateContainer<S>, | ||
| selectorFunc?: (state: S) => SelectedState | ||
| ): [SelectedState, S] { | ||
| let selector: Selector<S, SelectedState>; | ||
| if (selectorOrContainer instanceof StateContainer) { | ||
| if (!selectorFunc) { | ||
| throw new MissingSelectorFunctionError(); | ||
| } | ||
| // eslint-disable-next-line react-hooks/rules-of-hooks | ||
| selector = useRef(new Selector(selectorOrContainer, selectorFunc)).current; | ||
| } else { | ||
| selector = selectorOrContainer; | ||
| } | ||
| const [state, setState] = useState(selector.state); | ||
| useEffect(() => { | ||
| const subscription = selector.observable.pipe(skip(1)).subscribe(nextState => { | ||
| setState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, []); | ||
| return [state, selector.stateSource.values().next().value.state]; | ||
| } | ||
| export default useSelector; |
| import { useState, useEffect } from 'react'; | ||
| import { StateShape, StateContainer } from '@subjected/core'; | ||
| import { skip } from 'rxjs/operators'; | ||
| /** | ||
| * Creates a subscription to a state container and returns the current state | ||
| */ | ||
| function useStateContainer<S extends StateShape>(stateContainer: StateContainer<S>) { | ||
| const [state, updateState] = useState<S>(stateContainer.state); | ||
| useEffect(() => { | ||
| const subscription = stateContainer.observable.pipe(skip(1)).subscribe(nextState => { | ||
| updateState(nextState); | ||
| }); | ||
| return () => subscription.unsubscribe(); | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, []); | ||
| return state; | ||
| } | ||
| export default useStateContainer; |
| import useStateContainer from './hooks/useStateContainer'; | ||
| import useComputed from './hooks/useComputed'; | ||
| import useSelector from './hooks/useSelector'; | ||
| import usePerform from './hooks/usePerform'; | ||
| import useLazyPerform from './hooks/useLazyPerform'; | ||
| import useResolvers from './hooks/useResolvers'; | ||
| export { useStateContainer, useComputed, useSelector, usePerform, useLazyPerform, useResolvers }; |
| { | ||
| "extends": "../../tsconfig.json", | ||
| "compilerOptions": { | ||
| "esModuleInterop": true, | ||
| "declaration": true, | ||
| "downlevelIteration": true, | ||
| "noEmit": false, | ||
| "sourceMap": false, | ||
| "inlineSourceMap": true, | ||
| "outDir": "dist" | ||
| }, | ||
| "include": ["./src"], | ||
| "exclude": ["__tests__", "dist", "node_modules"] | ||
| } | ||
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
8533
-77.25%4
100%13
-64.86%44
-93.57%3
50%1
Infinity%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
Updated