Files
hoppscotch/packages/hoppscotch-common/src/newstore/DispatchingStore.ts
Akash K 8c57d81718 chore: bump dependencies (#3258)
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
2023-08-21 09:06:30 +05:30

79 lines
2.0 KiB
TypeScript

import { Subject, BehaviorSubject } from "rxjs"
import { map } from "rxjs/operators"
import { assign, clone } from "lodash-es"
type DispatcherFunc<StoreType, PayloadType> = (
currentVal: StoreType,
payload: PayloadType
) => Partial<StoreType>
/**
* Defines a dispatcher.
*
* This function exists to provide better typing for dispatch function.
* As you can see, its pretty much an identity function.
*/
export const defineDispatchers = <
StoreType,
T extends { [x: string]: DispatcherFunc<StoreType, any> },
>(
// eslint-disable-next-line no-unused-vars
dispatchers: T
) => dispatchers
type Dispatch<
StoreType,
DispatchersType extends { [x: string]: DispatcherFunc<StoreType, any> },
> = {
[Dispatcher in keyof DispatchersType]: {
dispatcher: Dispatcher
payload: Parameters<DispatchersType[Dispatcher]>[1]
}
}[keyof DispatchersType]
export default class DispatchingStore<
StoreType,
DispatchersType extends { [x: string]: DispatcherFunc<StoreType, any> },
> {
#state$: BehaviorSubject<StoreType>
#dispatchers: DispatchersType
#dispatches$: Subject<Dispatch<StoreType, DispatchersType>> = new Subject()
constructor(initialValue: StoreType, dispatchers: DispatchersType) {
this.#state$ = new BehaviorSubject(initialValue)
this.#dispatchers = dispatchers
this.#dispatches$
.pipe(
map(({ dispatcher, payload }) =>
this.#dispatchers[dispatcher](this.value, payload)
)
)
.subscribe((val) => {
const data = clone(this.value)
assign(data, val)
this.#state$.next(data)
})
}
get subject$() {
return this.#state$
}
get value() {
return this.subject$.value
}
get dispatches$() {
return this.#dispatches$
}
dispatch({ dispatcher, payload }: Dispatch<StoreType, DispatchersType>) {
if (!this.#dispatchers[dispatcher])
throw new Error(`Undefined dispatch type '${String(dispatcher)}'`)
this.#dispatches$.next({ dispatcher, payload })
}
}