chore: split app to commons and web (squash commit)
This commit is contained in:
73
packages/hoppscotch-common/src/newstore/DispatchingStore.ts
Normal file
73
packages/hoppscotch-common/src/newstore/DispatchingStore.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Subject, BehaviorSubject } from "rxjs"
|
||||
import { map } from "rxjs/operators"
|
||||
import { assign, clone } from "lodash-es"
|
||||
|
||||
type dispatcherFunc<StoreType> = (
|
||||
currentVal: StoreType,
|
||||
payload: any
|
||||
) => 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>(
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
dispatchers: { [_ in keyof T]: dispatcherFunc<StoreType> }
|
||||
) => dispatchers
|
||||
|
||||
type Dispatch<
|
||||
StoreType,
|
||||
DispatchersType extends Record<string, dispatcherFunc<StoreType>>
|
||||
> = {
|
||||
dispatcher: keyof DispatchersType
|
||||
payload: any
|
||||
}
|
||||
|
||||
export default class DispatchingStore<
|
||||
StoreType,
|
||||
DispatchersType extends Record<string, dispatcherFunc<StoreType>>
|
||||
> {
|
||||
#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 '${dispatcher}'`)
|
||||
|
||||
this.#dispatches$.next({ dispatcher, payload })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user