* Add vue-rx, rxjs and lodash as dependencies * Added vue-rx plugin integration to nuxt config * Initial settings store implementation * Add babel plugin for private class properties to for Jest * Add DispatchingStore test spec * Initial settings code * Reactive Streams for fb current user and id token * Fix typo * Migrate index and graphql pages to the new store * Migrate network strategy to the new store * Fixed Section.vue errors * Fix getSettingSubject issue * Migrate fb settings reference in components to the new state system * Add typings for lodash as dev dependency * Load setting * Load initial sync setting values * Update proxy url * Add typescript support * Rewrite Settings store to TypeScript * Port Settings page to TypeScript as reference * Move all store migrations to a separate file * Delete test file for fb.js * Add ts-jest as dev dependency * Remove firebase-mock as dependency * Remove FRAME_COLORS_ENABLED settings value
57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { Subject, BehaviorSubject } from "rxjs"
|
|
import { map } from "rxjs/operators"
|
|
import assign from "lodash/assign"
|
|
import clone from "lodash/clone"
|
|
|
|
|
|
type Dispatch<StoreType, DispatchersType extends Dispatchers<StoreType>, K extends keyof DispatchersType> = {
|
|
dispatcher: K & string,
|
|
payload: any
|
|
}
|
|
|
|
export type Dispatchers<StoreType> = {
|
|
[ key: string ]: (currentVal: StoreType, payload: any) => Partial<StoreType>
|
|
}
|
|
|
|
export default class DispatchingStore<StoreType, DispatchersType extends Dispatchers<StoreType>> {
|
|
|
|
#state$: BehaviorSubject<StoreType>
|
|
#dispatchers: Dispatchers<StoreType>
|
|
#dispatches$: Subject<Dispatch<StoreType, DispatchersType, keyof 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, keyof DispatchersType>) {
|
|
if (!this.#dispatchers[dispatcher]) throw new Error(`Undefined dispatch type '${dispatcher}'`)
|
|
|
|
this.#dispatches$.next({ dispatcher, payload })
|
|
}
|
|
}
|