@adpal/shared-lib 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +168 -1
- package/dist/index.d.ts +168 -1
- package/dist/index.js +136 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +130 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -292,6 +292,74 @@ declare function retryApiCall<T>(fn: () => Promise<T>, options?: Pick<RetryOptio
|
|
|
292
292
|
* );
|
|
293
293
|
*/
|
|
294
294
|
declare function retryCritical<T>(fn: () => Promise<T>, options?: Pick<RetryOptions, 'logger' | 'onRetry'>): Promise<T>;
|
|
295
|
+
/**
|
|
296
|
+
* Опции для withFallback
|
|
297
|
+
*/
|
|
298
|
+
interface FallbackOptions<T> extends RetryOptions {
|
|
299
|
+
/** Значение по умолчанию при неудаче */
|
|
300
|
+
fallback: T | (() => T);
|
|
301
|
+
/** Не логировать ошибку (используется когда fallback ожидаем) */
|
|
302
|
+
silent?: boolean;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Выполнить функцию с retry и fallback значением при неудаче
|
|
306
|
+
*
|
|
307
|
+
* Используется для graceful degradation — когда операция может упасть,
|
|
308
|
+
* но мы хотим продолжить работу с дефолтным значением.
|
|
309
|
+
*
|
|
310
|
+
* @param fn - Асинхронная функция для выполнения
|
|
311
|
+
* @param options - Опции с обязательным fallback
|
|
312
|
+
* @returns Результат выполнения или fallback значение
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* // Rerank с fallback на исходные результаты
|
|
316
|
+
* const reranked = await withFallback(
|
|
317
|
+
* () => rerankResults(query, results),
|
|
318
|
+
* {
|
|
319
|
+
* fallback: results,
|
|
320
|
+
* maxAttempts: 2,
|
|
321
|
+
* logger: voyageLogger,
|
|
322
|
+
* }
|
|
323
|
+
* );
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* // Получить настройки с fallback на defaults
|
|
327
|
+
* const settings = await withFallback(
|
|
328
|
+
* () => fetchUserSettings(userId),
|
|
329
|
+
* {
|
|
330
|
+
* fallback: () => DEFAULT_SETTINGS,
|
|
331
|
+
* silent: true, // Не логировать, если настройки не найдены
|
|
332
|
+
* }
|
|
333
|
+
* );
|
|
334
|
+
*/
|
|
335
|
+
declare function withFallback<T>(fn: () => Promise<T>, options: FallbackOptions<T>): Promise<T>;
|
|
336
|
+
/**
|
|
337
|
+
* Результат операции с информацией об использовании fallback
|
|
338
|
+
*/
|
|
339
|
+
interface FallbackResult<T> {
|
|
340
|
+
/** Результат (данные или fallback) */
|
|
341
|
+
data: T;
|
|
342
|
+
/** true если использован fallback */
|
|
343
|
+
usedFallback: boolean;
|
|
344
|
+
/** Ошибка, если была */
|
|
345
|
+
error?: Error;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Версия withFallback, которая возвращает информацию об использовании fallback
|
|
349
|
+
*
|
|
350
|
+
* Полезно когда нужно знать, пришли ли данные из источника или из fallback.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* const { data, usedFallback } = await withFallbackInfo(
|
|
354
|
+
* () => fetchLiveData(),
|
|
355
|
+
* { fallback: cachedData }
|
|
356
|
+
* );
|
|
357
|
+
*
|
|
358
|
+
* if (usedFallback) {
|
|
359
|
+
* console.log('Показываем кэшированные данные');
|
|
360
|
+
* }
|
|
361
|
+
*/
|
|
362
|
+
declare function withFallbackInfo<T>(fn: () => Promise<T>, options: FallbackOptions<T>): Promise<FallbackResult<T>>;
|
|
295
363
|
|
|
296
364
|
/**
|
|
297
365
|
* Zod схемы для валидации API ответов
|
|
@@ -773,4 +841,103 @@ declare function safeParse<T>(schema: z.ZodType<T>, data: unknown): T | null;
|
|
|
773
841
|
*/
|
|
774
842
|
declare function parseOrThrow<T>(schema: z.ZodType<T>, data: unknown, errorMessage?: string): T;
|
|
775
843
|
|
|
776
|
-
|
|
844
|
+
/**
|
|
845
|
+
* Стандартизированные типы API ответов
|
|
846
|
+
*
|
|
847
|
+
* Обеспечивает единый формат для всех API endpoints.
|
|
848
|
+
*
|
|
849
|
+
* @module api-response
|
|
850
|
+
*/
|
|
851
|
+
/**
|
|
852
|
+
* Успешный ответ API
|
|
853
|
+
*/
|
|
854
|
+
interface ApiSuccessResponse<T> {
|
|
855
|
+
success: true;
|
|
856
|
+
data: T;
|
|
857
|
+
meta?: {
|
|
858
|
+
requestId?: string;
|
|
859
|
+
timestamp?: string;
|
|
860
|
+
duration_ms?: number;
|
|
861
|
+
pagination?: PaginationMeta;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Ответ API с ошибкой
|
|
866
|
+
*/
|
|
867
|
+
interface ApiErrorResponse {
|
|
868
|
+
success: false;
|
|
869
|
+
error: {
|
|
870
|
+
code: string;
|
|
871
|
+
message: string;
|
|
872
|
+
details?: unknown;
|
|
873
|
+
};
|
|
874
|
+
meta?: {
|
|
875
|
+
requestId?: string;
|
|
876
|
+
timestamp?: string;
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Объединённый тип ответа API
|
|
881
|
+
*/
|
|
882
|
+
type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;
|
|
883
|
+
/**
|
|
884
|
+
* Метаданные пагинации
|
|
885
|
+
*/
|
|
886
|
+
interface PaginationMeta {
|
|
887
|
+
page: number;
|
|
888
|
+
pageSize: number;
|
|
889
|
+
totalItems: number;
|
|
890
|
+
totalPages: number;
|
|
891
|
+
hasMore: boolean;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Создать успешный ответ
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* return Response.json(success(users, { pagination }));
|
|
898
|
+
*/
|
|
899
|
+
declare function success<T>(data: T, meta?: ApiSuccessResponse<T>['meta']): ApiSuccessResponse<T>;
|
|
900
|
+
/**
|
|
901
|
+
* Создать ответ с ошибкой
|
|
902
|
+
*
|
|
903
|
+
* @example
|
|
904
|
+
* return Response.json(error('NOT_FOUND', 'User not found'), { status: 404 });
|
|
905
|
+
*/
|
|
906
|
+
declare function error(code: string, message: string, details?: unknown, requestId?: string): ApiErrorResponse;
|
|
907
|
+
/**
|
|
908
|
+
* Создать метаданные пагинации
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* const pagination = paginate(1, 20, 100);
|
|
912
|
+
* // { page: 1, pageSize: 20, totalItems: 100, totalPages: 5, hasMore: true }
|
|
913
|
+
*/
|
|
914
|
+
declare function paginate(page: number, pageSize: number, totalItems: number): PaginationMeta;
|
|
915
|
+
/**
|
|
916
|
+
* Ответ со списком и пагинацией
|
|
917
|
+
*/
|
|
918
|
+
interface ListResponse<T> {
|
|
919
|
+
items: T[];
|
|
920
|
+
pagination: PaginationMeta;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Создать ответ со списком
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* return Response.json(success(list(users, 1, 20, 100)));
|
|
927
|
+
*/
|
|
928
|
+
declare function list<T>(items: T[], page: number, pageSize: number, totalItems: number): ListResponse<T>;
|
|
929
|
+
declare const ErrorCodes: {
|
|
930
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
931
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
932
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
933
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
934
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
935
|
+
readonly RATE_LIMITED: "RATE_LIMITED";
|
|
936
|
+
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
937
|
+
readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
|
|
938
|
+
readonly EXTERNAL_API_ERROR: "EXTERNAL_API_ERROR";
|
|
939
|
+
readonly DATABASE_ERROR: "DATABASE_ERROR";
|
|
940
|
+
};
|
|
941
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
942
|
+
|
|
943
|
+
export { AnthropicApiError, ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, AppError, type ChatRequest, ChatRequestSchema, type ClaudeMessage, ClaudeMessageSchema, ConfigError, type ErrorCode, ErrorCodes, type FallbackOptions, type FallbackResult, type ListResponse, type LogLevel, type LogMeta, Logger, type PaginationMeta, type RetryOptions, type RetryResult, type Source, SourceSchema, TurbopufferApiError, type TurbopufferSearchResult, TurbopufferSearchResultSchema, ValidationError, type VectorAttributes, VectorAttributesSchema, VoyageApiError, type VoyageEmbeddingResponse, VoyageEmbeddingResponseSchema, type VoyageRerankResponse, VoyageRerankResponseSchema, anthropicLogger, apiLogger, createTimer, error, isAppError, list, logger, paginate, parseOrThrow, retryApiCall, retryCritical, safeParse, sleep, success, turbopufferLogger, voyageLogger, withFallback, withFallbackInfo, withRetry, wrapError };
|
package/dist/index.d.ts
CHANGED
|
@@ -292,6 +292,74 @@ declare function retryApiCall<T>(fn: () => Promise<T>, options?: Pick<RetryOptio
|
|
|
292
292
|
* );
|
|
293
293
|
*/
|
|
294
294
|
declare function retryCritical<T>(fn: () => Promise<T>, options?: Pick<RetryOptions, 'logger' | 'onRetry'>): Promise<T>;
|
|
295
|
+
/**
|
|
296
|
+
* Опции для withFallback
|
|
297
|
+
*/
|
|
298
|
+
interface FallbackOptions<T> extends RetryOptions {
|
|
299
|
+
/** Значение по умолчанию при неудаче */
|
|
300
|
+
fallback: T | (() => T);
|
|
301
|
+
/** Не логировать ошибку (используется когда fallback ожидаем) */
|
|
302
|
+
silent?: boolean;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Выполнить функцию с retry и fallback значением при неудаче
|
|
306
|
+
*
|
|
307
|
+
* Используется для graceful degradation — когда операция может упасть,
|
|
308
|
+
* но мы хотим продолжить работу с дефолтным значением.
|
|
309
|
+
*
|
|
310
|
+
* @param fn - Асинхронная функция для выполнения
|
|
311
|
+
* @param options - Опции с обязательным fallback
|
|
312
|
+
* @returns Результат выполнения или fallback значение
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* // Rerank с fallback на исходные результаты
|
|
316
|
+
* const reranked = await withFallback(
|
|
317
|
+
* () => rerankResults(query, results),
|
|
318
|
+
* {
|
|
319
|
+
* fallback: results,
|
|
320
|
+
* maxAttempts: 2,
|
|
321
|
+
* logger: voyageLogger,
|
|
322
|
+
* }
|
|
323
|
+
* );
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* // Получить настройки с fallback на defaults
|
|
327
|
+
* const settings = await withFallback(
|
|
328
|
+
* () => fetchUserSettings(userId),
|
|
329
|
+
* {
|
|
330
|
+
* fallback: () => DEFAULT_SETTINGS,
|
|
331
|
+
* silent: true, // Не логировать, если настройки не найдены
|
|
332
|
+
* }
|
|
333
|
+
* );
|
|
334
|
+
*/
|
|
335
|
+
declare function withFallback<T>(fn: () => Promise<T>, options: FallbackOptions<T>): Promise<T>;
|
|
336
|
+
/**
|
|
337
|
+
* Результат операции с информацией об использовании fallback
|
|
338
|
+
*/
|
|
339
|
+
interface FallbackResult<T> {
|
|
340
|
+
/** Результат (данные или fallback) */
|
|
341
|
+
data: T;
|
|
342
|
+
/** true если использован fallback */
|
|
343
|
+
usedFallback: boolean;
|
|
344
|
+
/** Ошибка, если была */
|
|
345
|
+
error?: Error;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Версия withFallback, которая возвращает информацию об использовании fallback
|
|
349
|
+
*
|
|
350
|
+
* Полезно когда нужно знать, пришли ли данные из источника или из fallback.
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* const { data, usedFallback } = await withFallbackInfo(
|
|
354
|
+
* () => fetchLiveData(),
|
|
355
|
+
* { fallback: cachedData }
|
|
356
|
+
* );
|
|
357
|
+
*
|
|
358
|
+
* if (usedFallback) {
|
|
359
|
+
* console.log('Показываем кэшированные данные');
|
|
360
|
+
* }
|
|
361
|
+
*/
|
|
362
|
+
declare function withFallbackInfo<T>(fn: () => Promise<T>, options: FallbackOptions<T>): Promise<FallbackResult<T>>;
|
|
295
363
|
|
|
296
364
|
/**
|
|
297
365
|
* Zod схемы для валидации API ответов
|
|
@@ -773,4 +841,103 @@ declare function safeParse<T>(schema: z.ZodType<T>, data: unknown): T | null;
|
|
|
773
841
|
*/
|
|
774
842
|
declare function parseOrThrow<T>(schema: z.ZodType<T>, data: unknown, errorMessage?: string): T;
|
|
775
843
|
|
|
776
|
-
|
|
844
|
+
/**
|
|
845
|
+
* Стандартизированные типы API ответов
|
|
846
|
+
*
|
|
847
|
+
* Обеспечивает единый формат для всех API endpoints.
|
|
848
|
+
*
|
|
849
|
+
* @module api-response
|
|
850
|
+
*/
|
|
851
|
+
/**
|
|
852
|
+
* Успешный ответ API
|
|
853
|
+
*/
|
|
854
|
+
interface ApiSuccessResponse<T> {
|
|
855
|
+
success: true;
|
|
856
|
+
data: T;
|
|
857
|
+
meta?: {
|
|
858
|
+
requestId?: string;
|
|
859
|
+
timestamp?: string;
|
|
860
|
+
duration_ms?: number;
|
|
861
|
+
pagination?: PaginationMeta;
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Ответ API с ошибкой
|
|
866
|
+
*/
|
|
867
|
+
interface ApiErrorResponse {
|
|
868
|
+
success: false;
|
|
869
|
+
error: {
|
|
870
|
+
code: string;
|
|
871
|
+
message: string;
|
|
872
|
+
details?: unknown;
|
|
873
|
+
};
|
|
874
|
+
meta?: {
|
|
875
|
+
requestId?: string;
|
|
876
|
+
timestamp?: string;
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* Объединённый тип ответа API
|
|
881
|
+
*/
|
|
882
|
+
type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;
|
|
883
|
+
/**
|
|
884
|
+
* Метаданные пагинации
|
|
885
|
+
*/
|
|
886
|
+
interface PaginationMeta {
|
|
887
|
+
page: number;
|
|
888
|
+
pageSize: number;
|
|
889
|
+
totalItems: number;
|
|
890
|
+
totalPages: number;
|
|
891
|
+
hasMore: boolean;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Создать успешный ответ
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* return Response.json(success(users, { pagination }));
|
|
898
|
+
*/
|
|
899
|
+
declare function success<T>(data: T, meta?: ApiSuccessResponse<T>['meta']): ApiSuccessResponse<T>;
|
|
900
|
+
/**
|
|
901
|
+
* Создать ответ с ошибкой
|
|
902
|
+
*
|
|
903
|
+
* @example
|
|
904
|
+
* return Response.json(error('NOT_FOUND', 'User not found'), { status: 404 });
|
|
905
|
+
*/
|
|
906
|
+
declare function error(code: string, message: string, details?: unknown, requestId?: string): ApiErrorResponse;
|
|
907
|
+
/**
|
|
908
|
+
* Создать метаданные пагинации
|
|
909
|
+
*
|
|
910
|
+
* @example
|
|
911
|
+
* const pagination = paginate(1, 20, 100);
|
|
912
|
+
* // { page: 1, pageSize: 20, totalItems: 100, totalPages: 5, hasMore: true }
|
|
913
|
+
*/
|
|
914
|
+
declare function paginate(page: number, pageSize: number, totalItems: number): PaginationMeta;
|
|
915
|
+
/**
|
|
916
|
+
* Ответ со списком и пагинацией
|
|
917
|
+
*/
|
|
918
|
+
interface ListResponse<T> {
|
|
919
|
+
items: T[];
|
|
920
|
+
pagination: PaginationMeta;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Создать ответ со списком
|
|
924
|
+
*
|
|
925
|
+
* @example
|
|
926
|
+
* return Response.json(success(list(users, 1, 20, 100)));
|
|
927
|
+
*/
|
|
928
|
+
declare function list<T>(items: T[], page: number, pageSize: number, totalItems: number): ListResponse<T>;
|
|
929
|
+
declare const ErrorCodes: {
|
|
930
|
+
readonly BAD_REQUEST: "BAD_REQUEST";
|
|
931
|
+
readonly UNAUTHORIZED: "UNAUTHORIZED";
|
|
932
|
+
readonly FORBIDDEN: "FORBIDDEN";
|
|
933
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
934
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
935
|
+
readonly RATE_LIMITED: "RATE_LIMITED";
|
|
936
|
+
readonly INTERNAL_ERROR: "INTERNAL_ERROR";
|
|
937
|
+
readonly SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
|
|
938
|
+
readonly EXTERNAL_API_ERROR: "EXTERNAL_API_ERROR";
|
|
939
|
+
readonly DATABASE_ERROR: "DATABASE_ERROR";
|
|
940
|
+
};
|
|
941
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
942
|
+
|
|
943
|
+
export { AnthropicApiError, ApiError, type ApiErrorResponse, type ApiResponse, type ApiSuccessResponse, AppError, type ChatRequest, ChatRequestSchema, type ClaudeMessage, ClaudeMessageSchema, ConfigError, type ErrorCode, ErrorCodes, type FallbackOptions, type FallbackResult, type ListResponse, type LogLevel, type LogMeta, Logger, type PaginationMeta, type RetryOptions, type RetryResult, type Source, SourceSchema, TurbopufferApiError, type TurbopufferSearchResult, TurbopufferSearchResultSchema, ValidationError, type VectorAttributes, VectorAttributesSchema, VoyageApiError, type VoyageEmbeddingResponse, VoyageEmbeddingResponseSchema, type VoyageRerankResponse, VoyageRerankResponseSchema, anthropicLogger, apiLogger, createTimer, error, isAppError, list, logger, paginate, parseOrThrow, retryApiCall, retryCritical, safeParse, sleep, success, turbopufferLogger, voyageLogger, withFallback, withFallbackInfo, withRetry, wrapError };
|
package/dist/index.js
CHANGED
|
@@ -122,21 +122,21 @@ var ConfigError = class extends AppError {
|
|
|
122
122
|
function isRetryableStatus(statusCode) {
|
|
123
123
|
return [408, 429, 500, 502, 503, 504].includes(statusCode);
|
|
124
124
|
}
|
|
125
|
-
function isAppError(
|
|
126
|
-
return
|
|
125
|
+
function isAppError(error2) {
|
|
126
|
+
return error2 instanceof AppError;
|
|
127
127
|
}
|
|
128
|
-
function wrapError(
|
|
129
|
-
if (
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
if (
|
|
133
|
-
return new AppError(
|
|
134
|
-
cause:
|
|
135
|
-
context: { originalName:
|
|
128
|
+
function wrapError(error2, defaultMessage = "\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043E\u0448\u0438\u0431\u043A\u0430") {
|
|
129
|
+
if (error2 instanceof AppError) {
|
|
130
|
+
return error2;
|
|
131
|
+
}
|
|
132
|
+
if (error2 instanceof Error) {
|
|
133
|
+
return new AppError(error2.message || defaultMessage, {
|
|
134
|
+
cause: error2,
|
|
135
|
+
context: { originalName: error2.name }
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
return new AppError(defaultMessage, {
|
|
139
|
-
context: { originalError:
|
|
139
|
+
context: { originalError: error2 }
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -189,11 +189,11 @@ function formatLogEntry(entry) {
|
|
|
189
189
|
}
|
|
190
190
|
return JSON.stringify(entry);
|
|
191
191
|
}
|
|
192
|
-
function serializeError(
|
|
192
|
+
function serializeError(error2) {
|
|
193
193
|
return {
|
|
194
|
-
name:
|
|
195
|
-
message:
|
|
196
|
-
stack:
|
|
194
|
+
name: error2.name,
|
|
195
|
+
message: error2.message,
|
|
196
|
+
stack: error2.stack
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
var Logger = class {
|
|
@@ -212,7 +212,7 @@ var Logger = class {
|
|
|
212
212
|
/**
|
|
213
213
|
* Записать лог
|
|
214
214
|
*/
|
|
215
|
-
log(level, message, meta,
|
|
215
|
+
log(level, message, meta, error2) {
|
|
216
216
|
if (!this.isEnabled(level)) return;
|
|
217
217
|
const entry = {
|
|
218
218
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -220,8 +220,8 @@ var Logger = class {
|
|
|
220
220
|
message,
|
|
221
221
|
meta: { module: this.module, ...meta }
|
|
222
222
|
};
|
|
223
|
-
if (
|
|
224
|
-
entry.error = serializeError(
|
|
223
|
+
if (error2) {
|
|
224
|
+
entry.error = serializeError(error2);
|
|
225
225
|
}
|
|
226
226
|
const formatted = formatLogEntry(entry);
|
|
227
227
|
switch (level) {
|
|
@@ -256,8 +256,8 @@ var Logger = class {
|
|
|
256
256
|
/**
|
|
257
257
|
* Error уровень — ошибки
|
|
258
258
|
*/
|
|
259
|
-
error(message,
|
|
260
|
-
const err =
|
|
259
|
+
error(message, error2, meta) {
|
|
260
|
+
const err = error2 instanceof Error ? error2 : void 0;
|
|
261
261
|
this.log("error", message, meta, err);
|
|
262
262
|
}
|
|
263
263
|
/**
|
|
@@ -281,8 +281,8 @@ var ChildLogger = class {
|
|
|
281
281
|
warn(message, meta) {
|
|
282
282
|
this.parent.warn(message, { ...this.context, ...meta });
|
|
283
283
|
}
|
|
284
|
-
error(message,
|
|
285
|
-
this.parent.error(message,
|
|
284
|
+
error(message, error2, meta) {
|
|
285
|
+
this.parent.error(message, error2, { ...this.context, ...meta });
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
288
|
var voyageLogger = new Logger("voyage");
|
|
@@ -309,12 +309,12 @@ function calculateDelay(attempt, baseDelayMs, maxDelayMs, jitter) {
|
|
|
309
309
|
const jitterAmount = cappedDelay * jitter * Math.random();
|
|
310
310
|
return Math.round(cappedDelay + jitterAmount);
|
|
311
311
|
}
|
|
312
|
-
function defaultShouldRetry(
|
|
313
|
-
if (isAppError(
|
|
312
|
+
function defaultShouldRetry(error2) {
|
|
313
|
+
if (isAppError(error2) && error2.retryable) {
|
|
314
314
|
return true;
|
|
315
315
|
}
|
|
316
|
-
if (
|
|
317
|
-
const message =
|
|
316
|
+
if (error2 instanceof Error) {
|
|
317
|
+
const message = error2.message.toLowerCase();
|
|
318
318
|
const networkErrors = [
|
|
319
319
|
"fetch failed",
|
|
320
320
|
"network error",
|
|
@@ -347,24 +347,24 @@ async function withRetry(fn, options = {}) {
|
|
|
347
347
|
attempts: attempt,
|
|
348
348
|
totalTimeMs: Math.round(performance.now() - startTime)
|
|
349
349
|
};
|
|
350
|
-
} catch (
|
|
351
|
-
lastError =
|
|
350
|
+
} catch (error2) {
|
|
351
|
+
lastError = error2;
|
|
352
352
|
if (attempt >= maxAttempts) {
|
|
353
|
-
logger2?.error(`\u0412\u0441\u0435 ${maxAttempts} \u043F\u043E\u043F\u044B\u0442\u043E\u043A \u0438\u0441\u0447\u0435\u0440\u043F\u0430\u043D\u044B`,
|
|
353
|
+
logger2?.error(`\u0412\u0441\u0435 ${maxAttempts} \u043F\u043E\u043F\u044B\u0442\u043E\u043A \u0438\u0441\u0447\u0435\u0440\u043F\u0430\u043D\u044B`, error2);
|
|
354
354
|
break;
|
|
355
355
|
}
|
|
356
|
-
if (!shouldRetry(
|
|
356
|
+
if (!shouldRetry(error2, attempt)) {
|
|
357
357
|
logger2?.warn(`\u041E\u0448\u0438\u0431\u043A\u0430 \u043D\u0435 \u043F\u043E\u0434\u043B\u0435\u0436\u0438\u0442 \u043F\u043E\u0432\u0442\u043E\u0440\u0435\u043D\u0438\u044E \u043D\u0430 \u043F\u043E\u043F\u044B\u0442\u043A\u0435 ${attempt}`, {
|
|
358
|
-
errorMessage:
|
|
358
|
+
errorMessage: error2 instanceof Error ? error2.message : String(error2)
|
|
359
359
|
});
|
|
360
360
|
break;
|
|
361
361
|
}
|
|
362
362
|
const delayMs = calculateDelay(attempt, baseDelayMs, maxDelayMs, jitter);
|
|
363
363
|
logger2?.info(`\u041F\u043E\u043F\u044B\u0442\u043A\u0430 ${attempt}/${maxAttempts} \u043D\u0435 \u0443\u0434\u0430\u043B\u0430\u0441\u044C, \u043F\u043E\u0432\u0442\u043E\u0440 \u0447\u0435\u0440\u0435\u0437 ${delayMs}\u043C\u0441`, {
|
|
364
|
-
errorMessage:
|
|
364
|
+
errorMessage: error2 instanceof Error ? error2.message : String(error2),
|
|
365
365
|
delayMs
|
|
366
366
|
});
|
|
367
|
-
onRetry?.(
|
|
367
|
+
onRetry?.(error2, attempt, delayMs);
|
|
368
368
|
await sleep(delayMs);
|
|
369
369
|
}
|
|
370
370
|
}
|
|
@@ -394,6 +394,43 @@ async function retryCritical(fn, options = {}) {
|
|
|
394
394
|
});
|
|
395
395
|
return result.data;
|
|
396
396
|
}
|
|
397
|
+
async function withFallback(fn, options) {
|
|
398
|
+
const { fallback, silent = false, logger: logger2, ...retryOptions } = options;
|
|
399
|
+
try {
|
|
400
|
+
const result = await withRetry(fn, { ...retryOptions, logger: logger2 });
|
|
401
|
+
return result.data;
|
|
402
|
+
} catch (error2) {
|
|
403
|
+
if (!silent && logger2) {
|
|
404
|
+
logger2.warn("\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u043D\u0435 \u0443\u0434\u0430\u043B\u0430\u0441\u044C, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C fallback", {
|
|
405
|
+
errorMessage: error2 instanceof Error ? error2.message : String(error2),
|
|
406
|
+
errorType: error2 instanceof Error ? error2.constructor.name : typeof error2
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return typeof fallback === "function" ? fallback() : fallback;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function withFallbackInfo(fn, options) {
|
|
413
|
+
const { fallback, silent = false, logger: logger2, ...retryOptions } = options;
|
|
414
|
+
try {
|
|
415
|
+
const result = await withRetry(fn, { ...retryOptions, logger: logger2 });
|
|
416
|
+
return {
|
|
417
|
+
data: result.data,
|
|
418
|
+
usedFallback: false
|
|
419
|
+
};
|
|
420
|
+
} catch (error2) {
|
|
421
|
+
if (!silent && logger2) {
|
|
422
|
+
logger2.warn("\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u044F \u043D\u0435 \u0443\u0434\u0430\u043B\u0430\u0441\u044C, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C fallback", {
|
|
423
|
+
errorMessage: error2 instanceof Error ? error2.message : String(error2)
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
const fallbackValue = typeof fallback === "function" ? fallback() : fallback;
|
|
427
|
+
return {
|
|
428
|
+
data: fallbackValue,
|
|
429
|
+
usedFallback: true,
|
|
430
|
+
error: error2 instanceof Error ? error2 : new Error(String(error2))
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
}
|
|
397
434
|
var VoyageEmbeddingResponseSchema = zod.z.object({
|
|
398
435
|
/** Массив эмбеддингов */
|
|
399
436
|
data: zod.z.array(
|
|
@@ -544,12 +581,72 @@ function parseOrThrow(schema, data, errorMessage = "Validation failed") {
|
|
|
544
581
|
return result.data;
|
|
545
582
|
}
|
|
546
583
|
|
|
584
|
+
// src/api-response.ts
|
|
585
|
+
function success(data, meta) {
|
|
586
|
+
return {
|
|
587
|
+
success: true,
|
|
588
|
+
data,
|
|
589
|
+
meta: {
|
|
590
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
591
|
+
...meta
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
function error(code, message, details, requestId) {
|
|
596
|
+
const errorObj = { code, message };
|
|
597
|
+
if (details !== void 0) {
|
|
598
|
+
errorObj.details = details;
|
|
599
|
+
}
|
|
600
|
+
const meta = {
|
|
601
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
602
|
+
};
|
|
603
|
+
if (requestId) {
|
|
604
|
+
meta.requestId = requestId;
|
|
605
|
+
}
|
|
606
|
+
return {
|
|
607
|
+
success: false,
|
|
608
|
+
error: errorObj,
|
|
609
|
+
meta
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
function paginate(page, pageSize, totalItems) {
|
|
613
|
+
const totalPages = Math.ceil(totalItems / pageSize);
|
|
614
|
+
return {
|
|
615
|
+
page,
|
|
616
|
+
pageSize,
|
|
617
|
+
totalItems,
|
|
618
|
+
totalPages,
|
|
619
|
+
hasMore: page < totalPages
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
function list(items, page, pageSize, totalItems) {
|
|
623
|
+
return {
|
|
624
|
+
items,
|
|
625
|
+
pagination: paginate(page, pageSize, totalItems)
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
var ErrorCodes = {
|
|
629
|
+
// Client errors (4xx)
|
|
630
|
+
BAD_REQUEST: "BAD_REQUEST",
|
|
631
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
632
|
+
FORBIDDEN: "FORBIDDEN",
|
|
633
|
+
NOT_FOUND: "NOT_FOUND",
|
|
634
|
+
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
635
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
636
|
+
// Server errors (5xx)
|
|
637
|
+
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
638
|
+
SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE",
|
|
639
|
+
EXTERNAL_API_ERROR: "EXTERNAL_API_ERROR",
|
|
640
|
+
DATABASE_ERROR: "DATABASE_ERROR"
|
|
641
|
+
};
|
|
642
|
+
|
|
547
643
|
exports.AnthropicApiError = AnthropicApiError;
|
|
548
644
|
exports.ApiError = ApiError;
|
|
549
645
|
exports.AppError = AppError;
|
|
550
646
|
exports.ChatRequestSchema = ChatRequestSchema;
|
|
551
647
|
exports.ClaudeMessageSchema = ClaudeMessageSchema;
|
|
552
648
|
exports.ConfigError = ConfigError;
|
|
649
|
+
exports.ErrorCodes = ErrorCodes;
|
|
553
650
|
exports.Logger = Logger;
|
|
554
651
|
exports.SourceSchema = SourceSchema;
|
|
555
652
|
exports.TurbopufferApiError = TurbopufferApiError;
|
|
@@ -562,15 +659,21 @@ exports.VoyageRerankResponseSchema = VoyageRerankResponseSchema;
|
|
|
562
659
|
exports.anthropicLogger = anthropicLogger;
|
|
563
660
|
exports.apiLogger = apiLogger;
|
|
564
661
|
exports.createTimer = createTimer;
|
|
662
|
+
exports.error = error;
|
|
565
663
|
exports.isAppError = isAppError;
|
|
664
|
+
exports.list = list;
|
|
566
665
|
exports.logger = logger;
|
|
666
|
+
exports.paginate = paginate;
|
|
567
667
|
exports.parseOrThrow = parseOrThrow;
|
|
568
668
|
exports.retryApiCall = retryApiCall;
|
|
569
669
|
exports.retryCritical = retryCritical;
|
|
570
670
|
exports.safeParse = safeParse;
|
|
571
671
|
exports.sleep = sleep;
|
|
672
|
+
exports.success = success;
|
|
572
673
|
exports.turbopufferLogger = turbopufferLogger;
|
|
573
674
|
exports.voyageLogger = voyageLogger;
|
|
675
|
+
exports.withFallback = withFallback;
|
|
676
|
+
exports.withFallbackInfo = withFallbackInfo;
|
|
574
677
|
exports.withRetry = withRetry;
|
|
575
678
|
exports.wrapError = wrapError;
|
|
576
679
|
//# sourceMappingURL=index.js.map
|