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/README.md +317 -296
- package/dist/index.d.mts +170 -11
- package/dist/index.d.ts +170 -11
- package/dist/index.js +347 -115
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +347 -116
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -15
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 };
|