Update DispatchingStore to provide better typing for dispatch function parameters
This commit is contained in:
@@ -3,28 +3,37 @@ import { map } from "rxjs/operators"
|
||||
import assign from "lodash/assign"
|
||||
import clone from "lodash/clone"
|
||||
|
||||
export type Dispatchers<StoreType> = {
|
||||
[key: string]: (currentVal: StoreType, payload: any) => Partial<StoreType>
|
||||
}
|
||||
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 Dispatchers<StoreType>,
|
||||
K extends keyof DispatchersType
|
||||
DispatchersType extends Record<string, dispatcherFunc<StoreType>>
|
||||
> = {
|
||||
dispatcher: K & string
|
||||
dispatcher: keyof DispatchersType
|
||||
payload: any
|
||||
}
|
||||
|
||||
export default class DispatchingStore<
|
||||
StoreType,
|
||||
DispatchersType extends Dispatchers<StoreType>
|
||||
DispatchersType extends Record<string, dispatcherFunc<StoreType>>
|
||||
> {
|
||||
#state$: BehaviorSubject<StoreType>
|
||||
#dispatchers: Dispatchers<StoreType>
|
||||
#dispatches$: Subject<
|
||||
Dispatch<StoreType, DispatchersType, keyof DispatchersType>
|
||||
> = new Subject()
|
||||
#dispatchers: DispatchersType
|
||||
#dispatches$: Subject<Dispatch<StoreType, DispatchersType>> = new Subject()
|
||||
|
||||
constructor(initialValue: StoreType, dispatchers: DispatchersType) {
|
||||
this.#state$ = new BehaviorSubject(initialValue)
|
||||
@@ -56,10 +65,7 @@ export default class DispatchingStore<
|
||||
return this.#dispatches$
|
||||
}
|
||||
|
||||
dispatch({
|
||||
dispatcher,
|
||||
payload,
|
||||
}: Dispatch<StoreType, DispatchersType, keyof DispatchersType>) {
|
||||
dispatch({ dispatcher, payload }: Dispatch<StoreType, DispatchersType>) {
|
||||
if (!this.#dispatchers[dispatcher])
|
||||
throw new Error(`Undefined dispatch type '${dispatcher}'`)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import eq from "lodash/eq"
|
||||
import { pluck } from "rxjs/operators"
|
||||
import DispatchingStore, { Dispatchers } from "./DispatchingStore"
|
||||
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
||||
|
||||
export const defaultRESTHistoryState = {
|
||||
state: [] as any[],
|
||||
@@ -15,18 +15,21 @@ export const HISTORY_LIMIT = 50
|
||||
type RESTHistoryType = typeof defaultRESTHistoryState
|
||||
type GraphqlHistoryType = typeof defaultGraphqlHistoryState
|
||||
|
||||
const HistoryDispatcher: Dispatchers<RESTHistoryType | GraphqlHistoryType> = {
|
||||
setEntries(_, { entries }: { entries: any[] }) {
|
||||
const HistoryDispatcher = defineDispatchers({
|
||||
setEntries(
|
||||
_: RESTHistoryType | GraphqlHistoryType,
|
||||
{ entries }: { entries: any[] }
|
||||
) {
|
||||
return {
|
||||
state: entries,
|
||||
}
|
||||
},
|
||||
addEntry(currentVal, { entry }) {
|
||||
addEntry(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
||||
return {
|
||||
state: [entry, ...currentVal.state].slice(0, HISTORY_LIMIT),
|
||||
}
|
||||
},
|
||||
deleteEntry(currentVal, { entry }) {
|
||||
deleteEntry(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
||||
return {
|
||||
state: currentVal.state.filter((e) => !eq(e, entry)),
|
||||
}
|
||||
@@ -36,7 +39,7 @@ const HistoryDispatcher: Dispatchers<RESTHistoryType | GraphqlHistoryType> = {
|
||||
state: [],
|
||||
}
|
||||
},
|
||||
toggleStar(currentVal, { entry }) {
|
||||
toggleStar(currentVal: RESTHistoryType | GraphqlHistoryType, { entry }) {
|
||||
return {
|
||||
state: currentVal.state.map((e) => {
|
||||
if (eq(e, entry) && e.star !== undefined) {
|
||||
@@ -49,7 +52,7 @@ const HistoryDispatcher: Dispatchers<RESTHistoryType | GraphqlHistoryType> = {
|
||||
}),
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
export const restHistoryStore = new DispatchingStore(
|
||||
defaultRESTHistoryState,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { pluck, distinctUntilChanged } from "rxjs/operators"
|
||||
import has from "lodash/has"
|
||||
import { Observable } from "rxjs"
|
||||
import DispatchingStore from "./DispatchingStore"
|
||||
import type { Dispatchers } from "./DispatchingStore"
|
||||
import DispatchingStore, { defineDispatchers } from "./DispatchingStore"
|
||||
import type { KeysMatching } from "~/types/ts-utils"
|
||||
|
||||
export const defaultSettings = {
|
||||
@@ -28,12 +27,15 @@ export type SettingsType = typeof defaultSettings
|
||||
|
||||
const validKeys = Object.keys(defaultSettings)
|
||||
|
||||
const dispatchers: Dispatchers<SettingsType> = {
|
||||
bulkApplySettings(_currentState, payload: Partial<SettingsType>) {
|
||||
const dispatchers = defineDispatchers({
|
||||
bulkApplySettings(
|
||||
_currentState: SettingsType,
|
||||
payload: Partial<SettingsType>
|
||||
) {
|
||||
return payload
|
||||
},
|
||||
toggleSetting(
|
||||
currentState,
|
||||
currentState: SettingsType,
|
||||
{ settingKey }: { settingKey: KeysMatching<SettingsType, boolean> }
|
||||
) {
|
||||
if (!has(currentState, settingKey)) {
|
||||
@@ -80,7 +82,7 @@ const dispatchers: Dispatchers<SettingsType> = {
|
||||
|
||||
return result
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
export const settingsStore = new DispatchingStore(defaultSettings, dispatchers)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user