Files
hoppscotch/packages/hoppscotch-selfhost-web/src/lib/sync/index.ts

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,
}
}