import { createHttpInterceptorWorker } from '../interceptorWorker/factory'; import LocalHttpInterceptorWorker from '../interceptorWorker/LocalHttpInterceptorWorker'; import RemoteHttpInterceptorWorker from '../interceptorWorker/RemoteHttpInterceptorWorker'; import { LocalHttpInterceptorWorkerOptions, RemoteHttpInterceptorWorkerOptions, } from '../interceptorWorker/types/options'; import { AnyHttpInterceptorImplementation } from './HttpInterceptorImplementation'; interface RemoteWorkerKeyOptions { auth: RemoteHttpInterceptorWorkerOptions['auth']; } class HttpInterceptorStore { private static _localWorker?: LocalHttpInterceptorWorker; private static runningLocalInterceptors = new Set(); private static remoteWorkers = new Map(); private static runningRemoteInterceptors = new Map>(); private class = HttpInterceptorStore; get localWorker() { return this.class._localWorker; } private getRemoteWorkerKey(baseURL: URL, options: RemoteWorkerKeyOptions) { const key = [`${baseURL.origin}${baseURL.pathname}`]; if (options.auth) { key.push(options.auth.token); } return key.join(':'); } remoteWorker(baseURL: URL, options: RemoteWorkerKeyOptions) { const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options); return this.class.remoteWorkers.get(remoteWorkerKey); } get numberOfRunningLocalInterceptors() { return this.class.runningLocalInterceptors.size; } numberOfRunningRemoteInterceptors(baseURL: URL) { const runningInterceptors = this.class.runningRemoteInterceptors.get(baseURL.origin); return runningInterceptors?.size ?? 0; } markLocalInterceptorAsRunning(interceptor: AnyHttpInterceptorImplementation, isRunning: boolean) { if (isRunning) { this.class.runningLocalInterceptors.add(interceptor); } else { this.class.runningLocalInterceptors.delete(interceptor); } } markRemoteInterceptorAsRunning(interceptor: AnyHttpInterceptorImplementation, isRunning: boolean, baseURL: URL) { const runningInterceptors = this.class.runningRemoteInterceptors.get(baseURL.origin) ?? this.createRunningInterceptorsSet(baseURL); if (isRunning) { runningInterceptors.add(interceptor); } else { runningInterceptors.delete(interceptor); } } private createRunningInterceptorsSet(baseURL: URL) { const runningInterceptors = new Set(); this.class.runningRemoteInterceptors.set(baseURL.origin, runningInterceptors); return runningInterceptors; } getOrCreateLocalWorker(workerOptions: Omit) { const existingWorker = this.class._localWorker; if (existingWorker) { return existingWorker; } const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: 'local' }); this.class._localWorker = createdWorker; return createdWorker; } deleteLocalWorker() { this.class._localWorker = undefined; } getOrCreateRemoteWorker(workerOptions: Omit) { const remoteWorkerKey = this.getRemoteWorkerKey(workerOptions.serverURL, { auth: workerOptions.auth }); const existingWorker = this.class.remoteWorkers.get(remoteWorkerKey); if (existingWorker) { return existingWorker; } const createdWorker = createHttpInterceptorWorker({ ...workerOptions, type: 'remote' }); this.class.remoteWorkers.set(remoteWorkerKey, createdWorker); return createdWorker; } deleteRemoteWorker(baseURL: URL, options: RemoteWorkerKeyOptions) { const remoteWorkerKey = this.getRemoteWorkerKey(baseURL, options); this.class.remoteWorkers.delete(remoteWorkerKey); } } export default HttpInterceptorStore;