From 6d605cd32529be9962a91deb7692f22278367324 Mon Sep 17 00:00:00 2001 From: Kilin Mikhail Date: Sat, 26 Dec 2020 00:20:01 +0300 Subject: [PATCH] add createService (#6) --- .../auth-response/components/page/Page.tsx | 6 ++-- src/pages/main/components/page/Page.tsx | 23 ++++++++++++ src/utils/createService.ts | 36 +++++++++++++++++++ src/utils/useStream.ts | 4 +-- 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 src/utils/createService.ts diff --git a/src/pages/auth-response/components/page/Page.tsx b/src/pages/auth-response/components/page/Page.tsx index 1785c02..c287361 100644 --- a/src/pages/auth-response/components/page/Page.tsx +++ b/src/pages/auth-response/components/page/Page.tsx @@ -1,9 +1,7 @@ -import {format} from 'date-fns'; -import {parse} from 'querystring'; import React, {memo} from 'react'; import {numberParser, QueryParsers, stringParser, useQuery} from '../../../../common/hooks/useQuery'; -import {QueryResponse, QueryResponseError} from '../../types'; +// eslint-disable-next-line const enum PersonType { One = 'one', Two = 'two' @@ -24,7 +22,7 @@ const parsers: QueryParsers = { const AuthResponsePage: React.FC = () => { const query = useQuery(parsers); return ( -
Auth Page
+
Auth Page {query.name}
); }; diff --git a/src/pages/main/components/page/Page.tsx b/src/pages/main/components/page/Page.tsx index be8afc0..4f9c1a9 100644 --- a/src/pages/main/components/page/Page.tsx +++ b/src/pages/main/components/page/Page.tsx @@ -2,16 +2,39 @@ import React, {memo} from 'react'; import {AuthService} from '../../../../services/AuthService'; import {useStream} from '../../../../utils/useStream'; import ComponentStream from '../component-stream/ComponentStream'; +import {createService} from '../../../../utils/createService'; + +const service = createService(1, { + changeWithStr: (state: number, val: string) => { + const parsedNumber = Number(val); + if (Number.isNaN(val)) { + return state; + } + + return parsedNumber; + }, + add: (state: number) => { + return state + 1; + }, + sub: (state: number) => { + return state - 1; + } +}); const MainPage: React.FC = () => { const {isAuth} = useStream(AuthService.state$, AuthService.initState); const toggle = () => AuthService.handleChangeAuth(!isAuth); + const data = useStream(service.stream$, 0); + return (
Main Page Auth: {isAuth ? 'yes' : 'no'} +
{data}
+ +
); }; diff --git a/src/utils/createService.ts b/src/utils/createService.ts new file mode 100644 index 0000000..f0f7efb --- /dev/null +++ b/src/utils/createService.ts @@ -0,0 +1,36 @@ +import {startWith} from '@most/core'; +import {createAdapter} from '@most/adapter'; +import {pipe} from 'fp-ts/es6/pipeable'; + +type ServiceAction = (data: State, val?: ValType) => State; + +type ServiceActions>> = { + [Key in keyof T]: T[Key] extends ServiceAction + ? D extends void | undefined + ? () => State + : (val: D) => State + : never; +}; + +// eslint-disable-next-line +export const createService = >>( + initData: State, + actions: Actions +) => { + const [handler, adapterStream$] = createAdapter(); + let currValue = initData; + const currStream$ = pipe(adapterStream$, startWith(initData)); + const currActions = Object.entries(actions).reduce((acc, [key, func]) => { + // eslint-disable-next-line + (acc as any)[key] = (val: unknown) => { + currValue = func(currValue, val); + handler(currValue); + }; + return acc; + }, {} as ServiceActions); + return { + stream$: currStream$, + actions: currActions, + initialState: initData + }; +}; diff --git a/src/utils/useStream.ts b/src/utils/useStream.ts index dd7549b..6c070a5 100644 --- a/src/utils/useStream.ts +++ b/src/utils/useStream.ts @@ -3,7 +3,7 @@ import {Stream, Sink} from '@most/types'; import {newDefaultScheduler} from '@most/scheduler'; import {pending, RemoteData} from '@devexperts/remote-data-ts'; -// eslint-disable-next-line no-empty-function +// eslint-disable-next-line const emptyFunc = () => {}; export const useStream = (stream$: Stream, defaultValue: T): T => { @@ -22,7 +22,7 @@ export const useStream = (stream$: Stream, defaultValue: T): T => { return () => { effect$.dispose(); }; - }, []); + }, [stream$]); return state; };