/
bearury
/
ui-kit-ce
Обзор
Документация
Войти
/
bearury
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
packages/styler-sync/src/utils/sequentialRequests.ts
178 строк
4 KB
Урядышев Павел Александрович
chore: устранены предупреждения eslint
25 июл 2025, 14:03
25 июл 2025, 14:03
1bad2f7
Код
Авторство
О чём код?
import { generateContextMap } from '.' import { NetworkError, ThemeProviderId } from '../types' export type ApiResponse<T = unknown> = SuccessApiResponse<T> | ErrorApiResponse export type SuccessApiResponse<T> = { /** * * @inner */ data: T /** * * @inner */ success: true } export type ErrorApiResponse = { /** * * @inner */ error: string /** * * @inner */ success: false } export type ParsedAccessKey = { /** * * @inner */ hash: string /** * * @inner */ hostname: string } export type SequentialRequestOperation<R = unknown> = { /** * * @inner */ themeProviderId: ThemeProviderId /** * * @returns */ fetchFunction: () => Promise<Response> /** * * @returns */ onSuccess?: (response: R) => void /** * * @returns */ onError?: (error: NetworkError) => void /** * * @returns */ onFinally?: () => void } | null export const API = { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types fullTheme: (baseUrl: string, hash: string) => `${baseUrl}/api/public/sync/${hash}/full`, // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types pingOverrides: (baseUrl: string, hash: string) => `${baseUrl}/api/public/sync/${hash}/overrides`, } type ApiTypes = keyof typeof API const API_TYPES = Object.keys(API) class SequentialRequestManager { private currentOperation = generateContextMap( API_TYPES, () => null as SequentialRequestOperation ) private operations = generateContextMap( API_TYPES, () => [] as SequentialRequestOperation[] ) setCurrentOperation( apiType: ApiTypes, operation: SequentialRequestOperation ) { this.currentOperation[apiType] = operation } getCurrentOperation(apiType: ApiTypes) { return this.currentOperation[apiType] } addOperation(apiType: ApiTypes, newOperation: SequentialRequestOperation) { /** Для одного provider не может быть двух и более запросов одинакового типа */ const opIndex = this.operations[apiType].findIndex( (op) => op?.themeProviderId === newOperation?.themeProviderId ) if (opIndex !== -1) { this.operations[apiType][opIndex] = newOperation return } this.operations[apiType].push(newOperation) } getOperations(apiType: ApiTypes) { return this.operations[apiType] } setCurrentOperationFromQueue(apiType: ApiTypes) { return (this.currentOperation[apiType] = this.operations[apiType].shift() || null) } } const reqManager = new SequentialRequestManager() // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const addSequentialRequest = <R = unknown>( apiType: ApiTypes, operation: SequentialRequestOperation<R> ) => { // @ts-expect-error TODO reqManager.addOperation(apiType, operation) performOperationsSequentially(apiType) } const performOperationsSequentially = (apiType: ApiTypes) => { if ( !reqManager.getOperations(apiType).length || reqManager.getCurrentOperation(apiType) ) { return } const currentOperation = reqManager.setCurrentOperationFromQueue(apiType) if (!currentOperation) { return } currentOperation .fetchFunction() .then(async (r) => { if (!r.ok) { const response = (await r.json()) as ErrorApiResponse currentOperation.onError?.({ status: r.status, message: response.error, }) return } const response = (await r.json()) as SuccessApiResponse<unknown> currentOperation.onSuccess?.(response.data) }) .catch((e) => { currentOperation.onError?.(String(e)) }) .finally(() => { currentOperation.onFinally?.() reqManager.setCurrentOperation(apiType, null) performOperationsSequentially(apiType) }) }