@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 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
- export { AnthropicApiError, ApiError, AppError, type ChatRequest, ChatRequestSchema, type ClaudeMessage, ClaudeMessageSchema, ConfigError, type LogLevel, type LogMeta, Logger, 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, isAppError, logger, parseOrThrow, retryApiCall, retryCritical, safeParse, sleep, turbopufferLogger, voyageLogger, withRetry, wrapError };
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
- export { AnthropicApiError, ApiError, AppError, type ChatRequest, ChatRequestSchema, type ClaudeMessage, ClaudeMessageSchema, ConfigError, type LogLevel, type LogMeta, Logger, 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, isAppError, logger, parseOrThrow, retryApiCall, retryCritical, safeParse, sleep, turbopufferLogger, voyageLogger, withRetry, wrapError };
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(error) {
126
- return error instanceof AppError;
125
+ function isAppError(error2) {
126
+ return error2 instanceof AppError;
127
127
  }
128
- function wrapError(error, defaultMessage = "\u041D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043E\u0448\u0438\u0431\u043A\u0430") {
129
- if (error instanceof AppError) {
130
- return error;
131
- }
132
- if (error instanceof Error) {
133
- return new AppError(error.message || defaultMessage, {
134
- cause: error,
135
- context: { originalName: error.name }
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: error }
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(error) {
192
+ function serializeError(error2) {
193
193
  return {
194
- name: error.name,
195
- message: error.message,
196
- stack: error.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, error) {
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 (error) {
224
- entry.error = serializeError(error);
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, error, meta) {
260
- const err = error instanceof Error ? error : void 0;
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, error, meta) {
285
- this.parent.error(message, error, { ...this.context, ...meta });
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(error) {
313
- if (isAppError(error) && error.retryable) {
312
+ function defaultShouldRetry(error2) {
313
+ if (isAppError(error2) && error2.retryable) {
314
314
  return true;
315
315
  }
316
- if (error instanceof Error) {
317
- const message = error.message.toLowerCase();
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 (error) {
351
- lastError = error;
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`, error);
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(error, attempt)) {
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: error instanceof Error ? error.message : String(error)
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: error instanceof Error ? error.message : String(error),
364
+ errorMessage: error2 instanceof Error ? error2.message : String(error2),
365
365
  delayMs
366
366
  });
367
- onRetry?.(error, attempt, delayMs);
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