103 lines
2.9 KiB
TypeScript
103 lines
2.9 KiB
TypeScript
import { Observable } from "rxjs"
|
|
import DispatchingStore from "@hoppscotch/common/newstore/DispatchingStore"
|
|
|
|
export type DispatchersOf<T extends DispatchingStore<any, any>> =
|
|
T extends DispatchingStore<any, infer U>
|
|
? U extends Record<infer D, any>
|
|
? D
|
|
: never
|
|
: never
|
|
|
|
export type StoreSyncDefinitionOf<T extends DispatchingStore<any, any>> = {
|
|
[x in DispatchersOf<T>]?: T extends DispatchingStore<any, infer U>
|
|
? U extends Record<x, any>
|
|
? U[x] extends (x: any, y: infer Y) => any
|
|
? (payload: Y) => void
|
|
: never
|
|
: never
|
|
: never
|
|
}
|
|
|
|
let _isRunningDispatchWithoutSyncing = true
|
|
|
|
export function runDispatchWithOutSyncing(func: () => void) {
|
|
_isRunningDispatchWithoutSyncing = false
|
|
func()
|
|
_isRunningDispatchWithoutSyncing = true
|
|
}
|
|
|
|
export const getSyncInitFunction = <T extends DispatchingStore<any, any>>(
|
|
store: T,
|
|
storeSyncDefinition: StoreSyncDefinitionOf<T>,
|
|
shouldSyncValue: () => boolean,
|
|
shouldSyncObservable?: Observable<boolean>
|
|
) => {
|
|
let startSubscriptions: () => () => void | undefined
|
|
let stopSubscriptions: () => void | undefined
|
|
|
|
let oldSyncStatus = shouldSyncValue()
|
|
|
|
// Start and stop the subscriptions according to the sync settings from profile
|
|
shouldSyncObservable &&
|
|
shouldSyncObservable.subscribe((newSyncStatus) => {
|
|
if (oldSyncStatus === true && newSyncStatus === false) {
|
|
stopListeningToSubscriptions()
|
|
} else if (oldSyncStatus === false && newSyncStatus === true) {
|
|
startListeningToSubscriptions()
|
|
}
|
|
|
|
oldSyncStatus = newSyncStatus
|
|
})
|
|
|
|
function startStoreSync() {
|
|
store.dispatches$.subscribe((actionParams) => {
|
|
// typescript cannot understand that the dispatcher can be the index, so casting to any
|
|
if ((storeSyncDefinition as any)[actionParams.dispatcher]) {
|
|
const dispatcher = actionParams.dispatcher
|
|
const payload = actionParams.payload
|
|
|
|
const operationMapperFunction = (storeSyncDefinition as any)[dispatcher]
|
|
|
|
if (
|
|
operationMapperFunction &&
|
|
_isRunningDispatchWithoutSyncing &&
|
|
shouldSyncValue()
|
|
) {
|
|
operationMapperFunction(payload)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
function setupSubscriptions(func: () => () => void) {
|
|
startSubscriptions = func
|
|
}
|
|
|
|
function startListeningToSubscriptions() {
|
|
if (!startSubscriptions) {
|
|
console.warn(
|
|
"We don't have a function to start subscriptions. Please use `setupSubscriptions` to setup the start function."
|
|
)
|
|
}
|
|
|
|
stopSubscriptions = startSubscriptions()
|
|
}
|
|
|
|
function stopListeningToSubscriptions() {
|
|
if (!stopSubscriptions) {
|
|
console.warn(
|
|
"We don't have a function to unsubscribe. make sure you return the unsubscribe function when using setupSubscriptions"
|
|
)
|
|
}
|
|
|
|
stopSubscriptions()
|
|
}
|
|
|
|
return {
|
|
startStoreSync,
|
|
setupSubscriptions,
|
|
startListeningToSubscriptions,
|
|
stopListeningToSubscriptions,
|
|
}
|
|
}
|