ani-client 1.2.0 → 1.3.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
@@ -283,10 +283,6 @@ interface SearchStaffOptions {
283
283
  page?: number;
284
284
  perPage?: number;
285
285
  }
286
- interface PaginatedOptions {
287
- page?: number;
288
- perPage?: number;
289
- }
290
286
  interface PagedResult<T> {
291
287
  pageInfo: PageInfo;
292
288
  results: T[];
@@ -439,6 +435,39 @@ interface SearchStudioOptions {
439
435
  page?: number;
440
436
  perPage?: number;
441
437
  }
438
+ /**
439
+ * Interface that all cache adapters must implement.
440
+ * Methods may return sync values or Promises — the client awaits all calls.
441
+ */
442
+ interface CacheAdapter {
443
+ /** Retrieve a cached value, or `undefined` if missing / expired. */
444
+ get<T>(key: string): T | undefined | Promise<T | undefined>;
445
+ /** Store a value in the cache. */
446
+ set<T>(key: string, data: T): void | Promise<void>;
447
+ /** Remove a specific entry. Returns `true` if the key existed. */
448
+ delete(key: string): boolean | Promise<boolean>;
449
+ /** Clear the entire cache. */
450
+ clear(): void | Promise<void>;
451
+ /** Number of entries currently stored (sync). Returns -1 if unknown. */
452
+ readonly size: number;
453
+ /** Return all cache keys. */
454
+ keys(): IterableIterator<string> | string[] | Promise<string[]>;
455
+ /** Bulk-remove entries matching a pattern. Optional — the client provides a fallback. */
456
+ invalidate?(pattern: string | RegExp): number | Promise<number>;
457
+ }
458
+ /** Event hooks for logging, debugging, and monitoring. */
459
+ interface AniListHooks {
460
+ /** Called before every API request. */
461
+ onRequest?: (query: string, variables: Record<string, unknown>) => void;
462
+ /** Called when a response is served from cache. */
463
+ onCacheHit?: (key: string) => void;
464
+ /** Called when the rate limiter enforces a wait (429 received). */
465
+ onRateLimit?: (retryAfterMs: number) => void;
466
+ /** Called when a request is retried (429 or network error). */
467
+ onRetry?: (attempt: number, reason: string, delayMs: number) => void;
468
+ /** Called when a request completes. */
469
+ onResponse?: (query: string, durationMs: number, fromCache: boolean) => void;
470
+ }
442
471
  interface AniListClientOptions {
443
472
  /** Optional AniList OAuth token for authenticated requests */
444
473
  token?: string;
@@ -453,6 +482,8 @@ interface AniListClientOptions {
453
482
  /** Set to false to disable caching entirely */
454
483
  enabled?: boolean;
455
484
  };
485
+ /** Custom cache adapter (e.g. RedisCache). Takes precedence over `cache`. */
486
+ cacheAdapter?: CacheAdapter;
456
487
  /** Rate limiter configuration (enabled by default, 85 req/min) */
457
488
  rateLimit?: {
458
489
  /** Max requests per window (default: 85) */
@@ -465,7 +496,13 @@ interface AniListClientOptions {
465
496
  retryDelayMs?: number;
466
497
  /** Set to false to disable rate limiting entirely */
467
498
  enabled?: boolean;
499
+ /** Timeout per request in ms (default: 30 000). 0 = no timeout. */
500
+ timeoutMs?: number;
501
+ /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
502
+ retryOnNetworkError?: boolean;
468
503
  };
504
+ /** Event hooks for logging, debugging, and monitoring */
505
+ hooks?: AniListHooks;
469
506
  }
470
507
 
471
508
  /**
@@ -489,13 +526,22 @@ interface AniListClientOptions {
489
526
  declare class AniListClient {
490
527
  private readonly apiUrl;
491
528
  private readonly headers;
492
- private readonly cache;
529
+ private readonly cacheAdapter;
493
530
  private readonly rateLimiter;
531
+ private readonly hooks;
532
+ private readonly inFlight;
494
533
  constructor(options?: AniListClientOptions);
495
534
  /**
496
535
  * @internal
497
536
  */
498
537
  private request;
538
+ /** @internal */
539
+ private executeRequest;
540
+ /**
541
+ * @internal
542
+ * Shorthand for paginated queries that follow the `Page { pageInfo, <field>[] }` pattern.
543
+ */
544
+ private pagedRequest;
499
545
  /**
500
546
  * Fetch a single media entry by its AniList ID.
501
547
  *
@@ -729,14 +775,48 @@ declare class AniListClient {
729
775
  * ```
730
776
  */
731
777
  paginate<T>(fetchPage: (page: number) => Promise<PagedResult<T>>, maxPages?: number): AsyncGenerator<T, void, undefined>;
778
+ /**
779
+ * Fetch multiple media entries in a single API request.
780
+ * Uses GraphQL aliases to batch up to 50 IDs per call.
781
+ *
782
+ * @param ids - Array of AniList media IDs
783
+ * @returns Array of media objects (same order as input IDs)
784
+ */
785
+ getMediaBatch(ids: number[]): Promise<Media[]>;
786
+ /**
787
+ * Fetch multiple characters in a single API request.
788
+ *
789
+ * @param ids - Array of AniList character IDs
790
+ * @returns Array of character objects (same order as input IDs)
791
+ */
792
+ getCharacterBatch(ids: number[]): Promise<Character[]>;
793
+ /**
794
+ * Fetch multiple staff members in a single API request.
795
+ *
796
+ * @param ids - Array of AniList staff IDs
797
+ * @returns Array of staff objects (same order as input IDs)
798
+ */
799
+ getStaffBatch(ids: number[]): Promise<Staff[]>;
800
+ /** @internal */
801
+ private executeBatch;
802
+ /** @internal */
803
+ private chunk;
732
804
  /**
733
805
  * Clear the entire response cache.
734
806
  */
735
- clearCache(): void;
807
+ clearCache(): Promise<void>;
736
808
  /**
737
- * Number of entries currently in the cache.
809
+ * Number of entries currently in the cache (sync).
810
+ * For async adapters like Redis, this may be approximate.
738
811
  */
739
812
  get cacheSize(): number;
813
+ /**
814
+ * Remove cache entries whose key matches the given pattern.
815
+ *
816
+ * @param pattern — A string (converted to RegExp) or RegExp
817
+ * @returns Number of entries removed
818
+ */
819
+ invalidateCache(pattern: string | RegExp): Promise<number>;
740
820
  }
741
821
 
742
822
  /**
@@ -762,7 +842,7 @@ interface CacheOptions {
762
842
  /** Disable caching entirely (default: false) */
763
843
  enabled?: boolean;
764
844
  }
765
- declare class MemoryCache {
845
+ declare class MemoryCache implements CacheAdapter {
766
846
  private readonly ttl;
767
847
  private readonly maxSize;
768
848
  private readonly enabled;
@@ -780,6 +860,74 @@ declare class MemoryCache {
780
860
  clear(): void;
781
861
  /** Number of entries currently stored. */
782
862
  get size(): number;
863
+ /** Return an iterator over all cache keys. */
864
+ keys(): IterableIterator<string>;
865
+ /**
866
+ * Remove all entries whose key matches the given pattern.
867
+ *
868
+ * @param pattern — A string (converted to RegExp) or RegExp.
869
+ * @returns Number of entries removed.
870
+ */
871
+ invalidate(pattern: string | RegExp): number;
872
+ }
873
+
874
+ /**
875
+ * Minimal interface representing a Redis client.
876
+ * Compatible with both `ioredis` and `redis` (node-redis v4+).
877
+ */
878
+ interface RedisLikeClient {
879
+ get(key: string): Promise<string | null>;
880
+ set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
881
+ del(...keys: (string | string[])[]): Promise<number>;
882
+ keys(pattern: string): Promise<string[]>;
883
+ }
884
+ interface RedisCacheOptions {
885
+ /** A Redis client instance (ioredis or node-redis). */
886
+ client: RedisLikeClient;
887
+ /** Key prefix to namespace ani-client entries (default: `"ani:"`) */
888
+ prefix?: string;
889
+ /** TTL in seconds (default: 86 400 = 24 h) */
890
+ ttl?: number;
891
+ }
892
+ /**
893
+ * Redis-backed cache adapter for AniListClient.
894
+ *
895
+ * @example
896
+ * ```ts
897
+ * import Redis from "ioredis";
898
+ * import { AniListClient, RedisCache } from "ani-client";
899
+ *
900
+ * const redis = new Redis();
901
+ * const client = new AniListClient({
902
+ * cacheAdapter: new RedisCache({ client: redis }),
903
+ * });
904
+ * ```
905
+ */
906
+ declare class RedisCache implements CacheAdapter {
907
+ private readonly client;
908
+ private readonly prefix;
909
+ private readonly ttl;
910
+ constructor(options: RedisCacheOptions);
911
+ private prefixedKey;
912
+ get<T>(key: string): Promise<T | undefined>;
913
+ set<T>(key: string, data: T): Promise<void>;
914
+ delete(key: string): Promise<boolean>;
915
+ clear(): Promise<void>;
916
+ /**
917
+ * Returns -1 because Redis keys can expire silently via TTL.
918
+ * Use `getSize()` for an accurate count.
919
+ */
920
+ get size(): number;
921
+ /** Get the actual number of keys with this prefix in Redis. */
922
+ getSize(): Promise<number>;
923
+ keys(): Promise<string[]>;
924
+ /**
925
+ * Remove all entries whose key matches the given glob pattern.
926
+ *
927
+ * @param pattern — A glob pattern (e.g. `"*Media*"`)
928
+ * @returns Number of entries removed.
929
+ */
930
+ invalidate(pattern: string): Promise<number>;
783
931
  }
784
932
 
785
933
  /**
@@ -800,6 +948,10 @@ interface RateLimitOptions {
800
948
  retryDelayMs?: number;
801
949
  /** Disable rate limiting entirely (default: false) */
802
950
  enabled?: boolean;
951
+ /** Timeout per request in milliseconds (default: 30 000). 0 = no timeout. */
952
+ timeoutMs?: number;
953
+ /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
954
+ retryOnNetworkError?: boolean;
803
955
  }
804
956
  declare class RateLimiter {
805
957
  private readonly maxRequests;
@@ -807,6 +959,8 @@ declare class RateLimiter {
807
959
  private readonly maxRetries;
808
960
  private readonly retryDelayMs;
809
961
  private readonly enabled;
962
+ private readonly timeoutMs;
963
+ private readonly retryOnNetworkError;
810
964
  /** @internal */
811
965
  private timestamps;
812
966
  constructor(options?: RateLimitOptions);
@@ -815,10 +969,15 @@ declare class RateLimiter {
815
969
  */
816
970
  acquire(): Promise<void>;
817
971
  /**
818
- * Execute a fetch with automatic retry on 429 responses.
972
+ * Execute a fetch with automatic retry on 429 responses and network errors.
819
973
  */
820
- fetchWithRetry(url: string, init: RequestInit): Promise<Response>;
974
+ fetchWithRetry(url: string, init: RequestInit, hooks?: {
975
+ onRetry?: (attempt: number, reason: string, delayMs: number) => void;
976
+ onRateLimit?: (retryAfterMs: number) => void;
977
+ }): Promise<Response>;
978
+ /** @internal */
979
+ private fetchWithTimeout;
821
980
  private sleep;
822
981
  }
823
982
 
824
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type PaginatedOptions, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
983
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
package/dist/index.d.ts CHANGED
@@ -283,10 +283,6 @@ interface SearchStaffOptions {
283
283
  page?: number;
284
284
  perPage?: number;
285
285
  }
286
- interface PaginatedOptions {
287
- page?: number;
288
- perPage?: number;
289
- }
290
286
  interface PagedResult<T> {
291
287
  pageInfo: PageInfo;
292
288
  results: T[];
@@ -439,6 +435,39 @@ interface SearchStudioOptions {
439
435
  page?: number;
440
436
  perPage?: number;
441
437
  }
438
+ /**
439
+ * Interface that all cache adapters must implement.
440
+ * Methods may return sync values or Promises — the client awaits all calls.
441
+ */
442
+ interface CacheAdapter {
443
+ /** Retrieve a cached value, or `undefined` if missing / expired. */
444
+ get<T>(key: string): T | undefined | Promise<T | undefined>;
445
+ /** Store a value in the cache. */
446
+ set<T>(key: string, data: T): void | Promise<void>;
447
+ /** Remove a specific entry. Returns `true` if the key existed. */
448
+ delete(key: string): boolean | Promise<boolean>;
449
+ /** Clear the entire cache. */
450
+ clear(): void | Promise<void>;
451
+ /** Number of entries currently stored (sync). Returns -1 if unknown. */
452
+ readonly size: number;
453
+ /** Return all cache keys. */
454
+ keys(): IterableIterator<string> | string[] | Promise<string[]>;
455
+ /** Bulk-remove entries matching a pattern. Optional — the client provides a fallback. */
456
+ invalidate?(pattern: string | RegExp): number | Promise<number>;
457
+ }
458
+ /** Event hooks for logging, debugging, and monitoring. */
459
+ interface AniListHooks {
460
+ /** Called before every API request. */
461
+ onRequest?: (query: string, variables: Record<string, unknown>) => void;
462
+ /** Called when a response is served from cache. */
463
+ onCacheHit?: (key: string) => void;
464
+ /** Called when the rate limiter enforces a wait (429 received). */
465
+ onRateLimit?: (retryAfterMs: number) => void;
466
+ /** Called when a request is retried (429 or network error). */
467
+ onRetry?: (attempt: number, reason: string, delayMs: number) => void;
468
+ /** Called when a request completes. */
469
+ onResponse?: (query: string, durationMs: number, fromCache: boolean) => void;
470
+ }
442
471
  interface AniListClientOptions {
443
472
  /** Optional AniList OAuth token for authenticated requests */
444
473
  token?: string;
@@ -453,6 +482,8 @@ interface AniListClientOptions {
453
482
  /** Set to false to disable caching entirely */
454
483
  enabled?: boolean;
455
484
  };
485
+ /** Custom cache adapter (e.g. RedisCache). Takes precedence over `cache`. */
486
+ cacheAdapter?: CacheAdapter;
456
487
  /** Rate limiter configuration (enabled by default, 85 req/min) */
457
488
  rateLimit?: {
458
489
  /** Max requests per window (default: 85) */
@@ -465,7 +496,13 @@ interface AniListClientOptions {
465
496
  retryDelayMs?: number;
466
497
  /** Set to false to disable rate limiting entirely */
467
498
  enabled?: boolean;
499
+ /** Timeout per request in ms (default: 30 000). 0 = no timeout. */
500
+ timeoutMs?: number;
501
+ /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
502
+ retryOnNetworkError?: boolean;
468
503
  };
504
+ /** Event hooks for logging, debugging, and monitoring */
505
+ hooks?: AniListHooks;
469
506
  }
470
507
 
471
508
  /**
@@ -489,13 +526,22 @@ interface AniListClientOptions {
489
526
  declare class AniListClient {
490
527
  private readonly apiUrl;
491
528
  private readonly headers;
492
- private readonly cache;
529
+ private readonly cacheAdapter;
493
530
  private readonly rateLimiter;
531
+ private readonly hooks;
532
+ private readonly inFlight;
494
533
  constructor(options?: AniListClientOptions);
495
534
  /**
496
535
  * @internal
497
536
  */
498
537
  private request;
538
+ /** @internal */
539
+ private executeRequest;
540
+ /**
541
+ * @internal
542
+ * Shorthand for paginated queries that follow the `Page { pageInfo, <field>[] }` pattern.
543
+ */
544
+ private pagedRequest;
499
545
  /**
500
546
  * Fetch a single media entry by its AniList ID.
501
547
  *
@@ -729,14 +775,48 @@ declare class AniListClient {
729
775
  * ```
730
776
  */
731
777
  paginate<T>(fetchPage: (page: number) => Promise<PagedResult<T>>, maxPages?: number): AsyncGenerator<T, void, undefined>;
778
+ /**
779
+ * Fetch multiple media entries in a single API request.
780
+ * Uses GraphQL aliases to batch up to 50 IDs per call.
781
+ *
782
+ * @param ids - Array of AniList media IDs
783
+ * @returns Array of media objects (same order as input IDs)
784
+ */
785
+ getMediaBatch(ids: number[]): Promise<Media[]>;
786
+ /**
787
+ * Fetch multiple characters in a single API request.
788
+ *
789
+ * @param ids - Array of AniList character IDs
790
+ * @returns Array of character objects (same order as input IDs)
791
+ */
792
+ getCharacterBatch(ids: number[]): Promise<Character[]>;
793
+ /**
794
+ * Fetch multiple staff members in a single API request.
795
+ *
796
+ * @param ids - Array of AniList staff IDs
797
+ * @returns Array of staff objects (same order as input IDs)
798
+ */
799
+ getStaffBatch(ids: number[]): Promise<Staff[]>;
800
+ /** @internal */
801
+ private executeBatch;
802
+ /** @internal */
803
+ private chunk;
732
804
  /**
733
805
  * Clear the entire response cache.
734
806
  */
735
- clearCache(): void;
807
+ clearCache(): Promise<void>;
736
808
  /**
737
- * Number of entries currently in the cache.
809
+ * Number of entries currently in the cache (sync).
810
+ * For async adapters like Redis, this may be approximate.
738
811
  */
739
812
  get cacheSize(): number;
813
+ /**
814
+ * Remove cache entries whose key matches the given pattern.
815
+ *
816
+ * @param pattern — A string (converted to RegExp) or RegExp
817
+ * @returns Number of entries removed
818
+ */
819
+ invalidateCache(pattern: string | RegExp): Promise<number>;
740
820
  }
741
821
 
742
822
  /**
@@ -762,7 +842,7 @@ interface CacheOptions {
762
842
  /** Disable caching entirely (default: false) */
763
843
  enabled?: boolean;
764
844
  }
765
- declare class MemoryCache {
845
+ declare class MemoryCache implements CacheAdapter {
766
846
  private readonly ttl;
767
847
  private readonly maxSize;
768
848
  private readonly enabled;
@@ -780,6 +860,74 @@ declare class MemoryCache {
780
860
  clear(): void;
781
861
  /** Number of entries currently stored. */
782
862
  get size(): number;
863
+ /** Return an iterator over all cache keys. */
864
+ keys(): IterableIterator<string>;
865
+ /**
866
+ * Remove all entries whose key matches the given pattern.
867
+ *
868
+ * @param pattern — A string (converted to RegExp) or RegExp.
869
+ * @returns Number of entries removed.
870
+ */
871
+ invalidate(pattern: string | RegExp): number;
872
+ }
873
+
874
+ /**
875
+ * Minimal interface representing a Redis client.
876
+ * Compatible with both `ioredis` and `redis` (node-redis v4+).
877
+ */
878
+ interface RedisLikeClient {
879
+ get(key: string): Promise<string | null>;
880
+ set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
881
+ del(...keys: (string | string[])[]): Promise<number>;
882
+ keys(pattern: string): Promise<string[]>;
883
+ }
884
+ interface RedisCacheOptions {
885
+ /** A Redis client instance (ioredis or node-redis). */
886
+ client: RedisLikeClient;
887
+ /** Key prefix to namespace ani-client entries (default: `"ani:"`) */
888
+ prefix?: string;
889
+ /** TTL in seconds (default: 86 400 = 24 h) */
890
+ ttl?: number;
891
+ }
892
+ /**
893
+ * Redis-backed cache adapter for AniListClient.
894
+ *
895
+ * @example
896
+ * ```ts
897
+ * import Redis from "ioredis";
898
+ * import { AniListClient, RedisCache } from "ani-client";
899
+ *
900
+ * const redis = new Redis();
901
+ * const client = new AniListClient({
902
+ * cacheAdapter: new RedisCache({ client: redis }),
903
+ * });
904
+ * ```
905
+ */
906
+ declare class RedisCache implements CacheAdapter {
907
+ private readonly client;
908
+ private readonly prefix;
909
+ private readonly ttl;
910
+ constructor(options: RedisCacheOptions);
911
+ private prefixedKey;
912
+ get<T>(key: string): Promise<T | undefined>;
913
+ set<T>(key: string, data: T): Promise<void>;
914
+ delete(key: string): Promise<boolean>;
915
+ clear(): Promise<void>;
916
+ /**
917
+ * Returns -1 because Redis keys can expire silently via TTL.
918
+ * Use `getSize()` for an accurate count.
919
+ */
920
+ get size(): number;
921
+ /** Get the actual number of keys with this prefix in Redis. */
922
+ getSize(): Promise<number>;
923
+ keys(): Promise<string[]>;
924
+ /**
925
+ * Remove all entries whose key matches the given glob pattern.
926
+ *
927
+ * @param pattern — A glob pattern (e.g. `"*Media*"`)
928
+ * @returns Number of entries removed.
929
+ */
930
+ invalidate(pattern: string): Promise<number>;
783
931
  }
784
932
 
785
933
  /**
@@ -800,6 +948,10 @@ interface RateLimitOptions {
800
948
  retryDelayMs?: number;
801
949
  /** Disable rate limiting entirely (default: false) */
802
950
  enabled?: boolean;
951
+ /** Timeout per request in milliseconds (default: 30 000). 0 = no timeout. */
952
+ timeoutMs?: number;
953
+ /** Retry on network errors like ECONNRESET / ETIMEDOUT (default: true) */
954
+ retryOnNetworkError?: boolean;
803
955
  }
804
956
  declare class RateLimiter {
805
957
  private readonly maxRequests;
@@ -807,6 +959,8 @@ declare class RateLimiter {
807
959
  private readonly maxRetries;
808
960
  private readonly retryDelayMs;
809
961
  private readonly enabled;
962
+ private readonly timeoutMs;
963
+ private readonly retryOnNetworkError;
810
964
  /** @internal */
811
965
  private timestamps;
812
966
  constructor(options?: RateLimitOptions);
@@ -815,10 +969,15 @@ declare class RateLimiter {
815
969
  */
816
970
  acquire(): Promise<void>;
817
971
  /**
818
- * Execute a fetch with automatic retry on 429 responses.
972
+ * Execute a fetch with automatic retry on 429 responses and network errors.
819
973
  */
820
- fetchWithRetry(url: string, init: RequestInit): Promise<Response>;
974
+ fetchWithRetry(url: string, init: RequestInit, hooks?: {
975
+ onRetry?: (attempt: number, reason: string, delayMs: number) => void;
976
+ onRateLimit?: (retryAfterMs: number) => void;
977
+ }): Promise<Response>;
978
+ /** @internal */
979
+ private fetchWithTimeout;
821
980
  private sleep;
822
981
  }
823
982
 
824
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type PaginatedOptions, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };
983
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterName, CharacterSort, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaListEntry, MediaListSort, MediaListStatus, MediaRelationType, MediaSeason, MediaSort, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffName, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics };