ani-client 1.4.4 → 1.5.1

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
@@ -348,27 +348,32 @@ interface Studio {
348
348
  name: string;
349
349
  isAnimationStudio: boolean;
350
350
  siteUrl: string | null;
351
- }
352
- interface StudioConnection {
353
- nodes: Studio[];
354
- }
355
- interface StudioDetail {
356
- id: number;
357
- name: string;
358
- isAnimationStudio: boolean;
359
- siteUrl: string | null;
360
- favourites: number | null;
361
- media: {
351
+ favourites?: number | null;
352
+ media?: {
362
353
  pageInfo: PageInfo;
363
354
  nodes: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "siteUrl">[];
364
355
  } | null;
365
356
  }
357
+ interface StudioConnection {
358
+ nodes: Studio[];
359
+ }
366
360
  interface SearchStudioOptions {
367
361
  query?: string;
368
362
  page?: number;
369
363
  perPage?: number;
370
364
  }
371
365
 
366
+ declare enum UserSort {
367
+ ID = "ID",
368
+ ID_DESC = "ID_DESC",
369
+ USERNAME = "USERNAME",
370
+ USERNAME_DESC = "USERNAME_DESC",
371
+ WATCHED_TIME = "WATCHED_TIME",
372
+ WATCHED_TIME_DESC = "WATCHED_TIME_DESC",
373
+ CHAPTERS_READ = "CHAPTERS_READ",
374
+ CHAPTERS_READ_DESC = "CHAPTERS_READ_DESC",
375
+ SEARCH_MATCH = "SEARCH_MATCH"
376
+ }
372
377
  interface UserAvatar {
373
378
  large: string | null;
374
379
  medium: string | null;
@@ -398,11 +403,34 @@ interface User {
398
403
  manga: UserStatistics;
399
404
  } | null;
400
405
  }
406
+ interface SearchUserOptions {
407
+ query?: string;
408
+ sort?: UserSort[];
409
+ page?: number;
410
+ perPage?: number;
411
+ }
401
412
 
402
413
  declare enum MediaType {
403
414
  ANIME = "ANIME",
404
415
  MANGA = "MANGA"
405
416
  }
417
+ declare enum MediaSource {
418
+ ORIGINAL = "ORIGINAL",
419
+ MANGA = "MANGA",
420
+ LIGHT_NOVEL = "LIGHT_NOVEL",
421
+ VISUAL_NOVEL = "VISUAL_NOVEL",
422
+ VIDEO_GAME = "VIDEO_GAME",
423
+ OTHER = "OTHER",
424
+ NOVEL = "NOVEL",
425
+ DOUJINSHI = "DOUJINSHI",
426
+ ANIME = "ANIME",
427
+ WEB_NOVEL = "WEB_NOVEL",
428
+ LIVE_ACTION = "LIVE_ACTION",
429
+ GAME = "GAME",
430
+ COMIC = "COMIC",
431
+ MULTIMEDIA_PROJECT = "MULTIMEDIA_PROJECT",
432
+ PICTURE_BOOK = "PICTURE_BOOK"
433
+ }
406
434
  declare enum MediaFormat {
407
435
  TV = "TV",
408
436
  TV_SHORT = "TV_SHORT",
@@ -558,6 +586,13 @@ interface MediaRecommendationNode {
558
586
  rating: number | null;
559
587
  mediaRecommendation: Pick<Media, "id" | "title" | "type" | "format" | "coverImage" | "averageScore" | "siteUrl">;
560
588
  }
589
+ interface NextAiringEpisode {
590
+ id: number;
591
+ airingAt: number;
592
+ episode: number;
593
+ mediaId: number;
594
+ timeUntilAiring: number;
595
+ }
561
596
  interface Media {
562
597
  id: number;
563
598
  idMal: number | null;
@@ -576,7 +611,7 @@ interface Media {
576
611
  volumes: number | null;
577
612
  countryOfOrigin: string | null;
578
613
  isLicensed: boolean | null;
579
- source: string | null;
614
+ source: MediaSource | null;
580
615
  hashtag: string | null;
581
616
  trailer: MediaTrailer | null;
582
617
  coverImage: MediaCoverImage;
@@ -599,6 +634,7 @@ interface Media {
599
634
  recommendations?: {
600
635
  nodes: MediaRecommendationNode[];
601
636
  };
637
+ nextAiringEpisode: NextAiringEpisode | null;
602
638
  isAdult: boolean | null;
603
639
  siteUrl: string | null;
604
640
  }
@@ -609,8 +645,18 @@ interface SearchMediaOptions {
609
645
  status?: MediaStatus;
610
646
  season?: MediaSeason;
611
647
  seasonYear?: number;
648
+ /** Single genre filter (kept for backward compat) */
612
649
  genre?: string;
650
+ /** Single tag filter (kept for backward compat) */
613
651
  tag?: string;
652
+ /** Filter by multiple genres (media must match ALL) */
653
+ genres?: string[];
654
+ /** Filter by multiple tags (media must match ALL) */
655
+ tags?: string[];
656
+ /** Exclude media with any of these genres */
657
+ genresExclude?: string[];
658
+ /** Exclude media with any of these tags */
659
+ tagsExclude?: string[];
614
660
  isAdult?: boolean;
615
661
  sort?: MediaSort[];
616
662
  page?: number;
@@ -716,6 +762,96 @@ interface AiringSchedule {
716
762
  mediaId: number;
717
763
  media: Media;
718
764
  }
765
+ type DayOfWeek = "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday";
766
+ type WeeklySchedule = Record<DayOfWeek, AiringSchedule[]>;
767
+
768
+ /** Represents a forum thread on AniList. */
769
+ interface Thread {
770
+ id: number;
771
+ title: string;
772
+ body: string | null;
773
+ userId: number;
774
+ replyUserId: number | null;
775
+ replyCommentId: number | null;
776
+ replyCount: number;
777
+ viewCount: number;
778
+ isLocked: boolean;
779
+ isSticky: boolean;
780
+ isSubscribed: boolean;
781
+ repliedAt: number | null;
782
+ createdAt: number;
783
+ updatedAt: number;
784
+ siteUrl: string | null;
785
+ user: {
786
+ id: number;
787
+ name: string;
788
+ avatar: UserAvatar;
789
+ } | null;
790
+ replyUser: {
791
+ id: number;
792
+ name: string;
793
+ avatar: UserAvatar;
794
+ } | null;
795
+ categories: ThreadCategory[] | null;
796
+ mediaCategories: ThreadMediaCategory[] | null;
797
+ likes: {
798
+ id: number;
799
+ name: string;
800
+ }[] | null;
801
+ }
802
+ interface ThreadCategory {
803
+ id: number;
804
+ name: string;
805
+ }
806
+ interface ThreadMediaCategory {
807
+ id: number;
808
+ title: {
809
+ romaji: string | null;
810
+ english: string | null;
811
+ native: string | null;
812
+ userPreferred: string | null;
813
+ };
814
+ type: string;
815
+ coverImage: {
816
+ large: string | null;
817
+ medium: string | null;
818
+ } | null;
819
+ siteUrl: string | null;
820
+ }
821
+ /** Sort options for thread queries. */
822
+ declare enum ThreadSort {
823
+ ID = "ID",
824
+ ID_DESC = "ID_DESC",
825
+ TITLE = "TITLE",
826
+ TITLE_DESC = "TITLE_DESC",
827
+ CREATED_AT = "CREATED_AT",
828
+ CREATED_AT_DESC = "CREATED_AT_DESC",
829
+ UPDATED_AT = "UPDATED_AT",
830
+ UPDATED_AT_DESC = "UPDATED_AT_DESC",
831
+ REPLIED_AT = "REPLIED_AT",
832
+ REPLIED_AT_DESC = "REPLIED_AT_DESC",
833
+ REPLY_COUNT = "REPLY_COUNT",
834
+ REPLY_COUNT_DESC = "REPLY_COUNT_DESC",
835
+ VIEW_COUNT = "VIEW_COUNT",
836
+ VIEW_COUNT_DESC = "VIEW_COUNT_DESC",
837
+ IS_STICKY = "IS_STICKY",
838
+ SEARCH_MATCH = "SEARCH_MATCH"
839
+ }
840
+ /** Options for searching/listing threads. */
841
+ interface SearchThreadOptions {
842
+ /** Search query */
843
+ query?: string;
844
+ /** Filter by media ID */
845
+ mediaId?: number;
846
+ /** Filter by category ID */
847
+ categoryId?: number;
848
+ /** Sort order */
849
+ sort?: ThreadSort[];
850
+ /** Page number */
851
+ page?: number;
852
+ /** Results per page (max 50) */
853
+ perPage?: number;
854
+ }
719
855
 
720
856
  /**
721
857
  * Lightweight AniList GraphQL client with built-in caching and rate limiting.
@@ -725,7 +861,7 @@ interface AiringSchedule {
725
861
  * import { AniListClient } from "ani-client";
726
862
  *
727
863
  * const client = new AniListClient();
728
- * const anime = await client.getMedia(1); // Cowboy Bebop
864
+ * const anime = await client.getMedia(1);
729
865
  * console.log(anime.title.romaji);
730
866
  *
731
867
  * // Custom cache & rate limit options
@@ -743,17 +879,12 @@ declare class AniListClient {
743
879
  private readonly hooks;
744
880
  private readonly inFlight;
745
881
  constructor(options?: AniListClientOptions);
746
- /**
747
- * @internal
748
- */
749
- private request;
882
+ /** @internal */
883
+ request<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
750
884
  /** @internal */
751
885
  private executeRequest;
752
- /**
753
- * @internal
754
- * Shorthand for paginated queries that follow the `Page { pageInfo, <field>[] }` pattern.
755
- */
756
- private pagedRequest;
886
+ /** @internal */
887
+ pagedRequest<T>(query: string, variables: Record<string, unknown>, field: string): Promise<PagedResult<T>>;
757
888
  /**
758
889
  * Fetch a single media entry by its AniList ID.
759
890
  *
@@ -761,33 +892,6 @@ declare class AniListClient {
761
892
  *
762
893
  * @param id - The AniList media ID
763
894
  * @param include - Optional related data to include
764
- * @returns The media object
765
- *
766
- * @example
767
- * ```ts
768
- * // Basic usage — same as before (includes relations by default)
769
- * const anime = await client.getMedia(1);
770
- *
771
- * // Include characters sorted by role, 25 results
772
- * const anime = await client.getMedia(1, { characters: true });
773
- *
774
- * // Include characters with voice actors
775
- * const anime = await client.getMedia(1, { characters: { voiceActors: true } });
776
- *
777
- * // Full control
778
- * const anime = await client.getMedia(1, {
779
- * characters: { perPage: 50, sort: true },
780
- * staff: true,
781
- * relations: true,
782
- * streamingEpisodes: true,
783
- * externalLinks: true,
784
- * stats: true,
785
- * recommendations: { perPage: 5 },
786
- * });
787
- *
788
- * // Exclude relations for a lighter response
789
- * const anime = await client.getMedia(1, { characters: true, relations: false });
790
- * ```
791
895
  */
792
896
  getMedia(id: number, include?: MediaIncludeOptions): Promise<Media>;
793
897
  /**
@@ -795,335 +899,81 @@ declare class AniListClient {
795
899
  *
796
900
  * @param options - Search / filter parameters
797
901
  * @returns Paginated results with matching media
798
- *
799
- * @example
800
- * ```ts
801
- * const results = await client.searchMedia({
802
- * query: "Naruto",
803
- * type: MediaType.ANIME,
804
- * perPage: 5,
805
- * });
806
- * ```
807
902
  */
808
903
  searchMedia(options?: SearchMediaOptions): Promise<PagedResult<Media>>;
809
- /**
810
- * Get currently trending anime or manga.
811
- *
812
- * @param type - `MediaType.ANIME` or `MediaType.MANGA` (defaults to ANIME)
813
- * @param page - Page number (default 1)
814
- * @param perPage - Results per page (default 20, max 50)
815
- */
904
+ /** Get currently trending anime or manga. */
816
905
  getTrending(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
817
- /**
818
- * Fetch a character by AniList ID.
819
- *
820
- * @param id - The AniList character ID
821
- * @param include - Optional include options (e.g. voice actors)
822
- * @returns The character object
823
- *
824
- * @example
825
- * ```ts
826
- * const spike = await client.getCharacter(1);
827
- * console.log(spike.name.full); // "Spike Spiegel"
828
- *
829
- * // With voice actors
830
- * const spike = await client.getCharacter(1, { voiceActors: true });
831
- * spike.media?.edges?.forEach((e) => {
832
- * console.log(e.node.title.romaji);
833
- * e.voiceActors?.forEach((va) => console.log(` VA: ${va.name.full}`));
834
- * });
835
- * ```
836
- */
837
- getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character>;
838
- /**
839
- * Search for characters by name.
840
- *
841
- * @param options - Search / pagination parameters (includes optional `voiceActors`)
842
- * @returns Paginated results with matching characters
843
- *
844
- * @example
845
- * ```ts
846
- * const result = await client.searchCharacters({ query: "Luffy", perPage: 5 });
847
- *
848
- * // With voice actors
849
- * const result = await client.searchCharacters({ query: "Luffy", voiceActors: true });
850
- * ```
851
- */
852
- searchCharacters(options?: SearchCharacterOptions): Promise<PagedResult<Character>>;
853
- /**
854
- * Fetch a staff member by AniList ID.
855
- *
856
- * @param id - The AniList staff ID
857
- * @param include - Optional include options to fetch related data (e.g. media)
858
- * @returns The staff object
859
- *
860
- * @example
861
- * ```ts
862
- * const staff = await client.getStaff(95001);
863
- * console.log(staff.name.full);
864
- *
865
- * // With media the staff worked on
866
- * const staff = await client.getStaff(95001, { media: true });
867
- * staff.staffMedia?.nodes.forEach((m) => console.log(m.title.romaji));
868
- * ```
869
- */
870
- getStaff(id: number, include?: StaffIncludeOptions): Promise<Staff>;
871
- /**
872
- * Search for staff (voice actors, directors, etc.).
873
- *
874
- * @param options - Search / pagination parameters
875
- * @returns Paginated results with matching staff
876
- *
877
- * @example
878
- * ```ts
879
- * const result = await client.searchStaff({ query: "Miyazaki", perPage: 5 });
880
- * ```
881
- */
882
- searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
883
- /**
884
- * Fetch a user by AniList ID.
885
- *
886
- * @param id - The AniList user ID
887
- * @returns The user object
888
- *
889
- * @example
890
- * ```ts
891
- * const user = await client.getUser(1);
892
- * console.log(user.name);
893
- * ```
894
- */
895
- getUser(id: number): Promise<User>;
896
- /**
897
- * Fetch a user by username.
898
- *
899
- * @param name - The AniList username
900
- * @returns The user object
901
- *
902
- * @example
903
- * ```ts
904
- * const user = await client.getUserByName("AniList");
905
- * console.log(user.statistics);
906
- * ```
907
- */
908
- getUserByName(name: string): Promise<User>;
909
- /**
910
- * Execute an arbitrary GraphQL query against the AniList API.
911
- * Useful for advanced use-cases not covered by the built-in methods.
912
- *
913
- * @param query - A valid GraphQL query string
914
- * @param variables - Optional variables object
915
- */
916
- raw<T = unknown>(query: string, variables?: Record<string, unknown>): Promise<T>;
917
- /**
918
- * Get recently aired anime episodes.
919
- *
920
- * By default returns episodes that aired in the last 24 hours.
921
- *
922
- * @param options - Filter / pagination parameters
923
- * @returns Paginated list of airing schedule entries
924
- *
925
- * @example
926
- * ```ts
927
- * // Episodes that aired in the last 48h
928
- * const recent = await client.getAiredEpisodes({
929
- * airingAtGreater: Math.floor(Date.now() / 1000) - 48 * 3600,
930
- * });
931
- * ```
932
- */
906
+ /** Get the most popular anime or manga. */
907
+ getPopular(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
908
+ /** Get the highest-rated anime or manga. */
909
+ getTopRated(type?: MediaType, page?: number, perPage?: number): Promise<PagedResult<Media>>;
910
+ /** Get recently aired anime episodes. */
933
911
  getAiredEpisodes(options?: GetAiringOptions): Promise<PagedResult<AiringSchedule>>;
934
- /**
935
- * Get manga that are currently releasing, sorted by most recently updated.
936
- *
937
- * This is the closest equivalent to "recently released chapters" on AniList,
938
- * since the API does not expose per-chapter airing schedules for manga.
939
- *
940
- * @param options - Pagination parameters
941
- * @returns Paginated list of currently releasing manga
942
- *
943
- * @example
944
- * ```ts
945
- * const chapters = await client.getAiredChapters({ perPage: 10 });
946
- * ```
947
- */
912
+ /** Get currently releasing manga. */
948
913
  getAiredChapters(options?: GetRecentChaptersOptions): Promise<PagedResult<Media>>;
949
- /**
950
- * Get upcoming (not yet released) anime and/or manga, sorted by popularity.
951
- *
952
- * @param options - Filter / pagination parameters
953
- * @returns Paginated list of planned media
954
- *
955
- * @example
956
- * ```ts
957
- * import { MediaType } from "ani-client";
958
- *
959
- * // Most anticipated upcoming anime
960
- * const planning = await client.getPlanning({ type: MediaType.ANIME, perPage: 10 });
961
- * ```
962
- */
914
+ /** Get the detailed schedule for the current week, sorted by day. */
915
+ getWeeklySchedule(date?: Date): Promise<WeeklySchedule>;
916
+ /** Get upcoming (not yet released) media. */
963
917
  getPlanning(options?: GetPlanningOptions): Promise<PagedResult<Media>>;
964
- /**
965
- * Get recommendations for a specific media.
966
- *
967
- * Returns other anime/manga that users have recommended based on the given media.
968
- *
969
- * @param mediaId - The AniList media ID
970
- * @param options - Optional sort / pagination parameters
971
- * @returns Paginated list of recommendations
972
- *
973
- * @example
974
- * ```ts
975
- * // Get recommendations for Cowboy Bebop
976
- * const recs = await client.getRecommendations(1);
977
- * recs.results.forEach((r) =>
978
- * console.log(`${r.mediaRecommendation.title.romaji} (rating: ${r.rating})`)
979
- * );
980
- * ```
981
- */
918
+ /** Get recommendations for a specific media. */
982
919
  getRecommendations(mediaId: number, options?: Omit<GetRecommendationsOptions, "mediaId">): Promise<PagedResult<Recommendation>>;
983
- /**
984
- * Get anime (or manga) for a specific season and year.
985
- *
986
- * @param options - Season, year and optional filter / pagination parameters
987
- * @returns Paginated list of media for the given season
988
- *
989
- * @example
990
- * ```ts
991
- * import { MediaSeason } from "ani-client";
992
- *
993
- * const winter2026 = await client.getMediaBySeason({
994
- * season: MediaSeason.WINTER,
995
- * seasonYear: 2026,
996
- * perPage: 10,
997
- * });
998
- * ```
999
- */
920
+ /** Get anime (or manga) for a specific season and year. */
1000
921
  getMediaBySeason(options: GetSeasonOptions): Promise<PagedResult<Media>>;
922
+ /** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
923
+ getCharacter(id: number, include?: CharacterIncludeOptions): Promise<Character>;
924
+ /** Search for characters by name. */
925
+ searchCharacters(options?: SearchCharacterOptions): Promise<PagedResult<Character>>;
926
+ /** Fetch a staff member by AniList ID. Pass `{ media: true }` or `{ media: { perPage } }` for media credits. */
927
+ getStaff(id: number, include?: StaffIncludeOptions): Promise<Staff>;
928
+ /** Search for staff (voice actors, directors, etc.). */
929
+ searchStaff(options?: SearchStaffOptions): Promise<PagedResult<Staff>>;
1001
930
  /**
1002
- * Get a user's anime or manga list.
1003
- *
1004
- * Provide either `userId` or `userName` to identify the user.
1005
- * Requires `type` (ANIME or MANGA). Optionally filter by list status.
931
+ * Fetch a user by AniList ID or username.
1006
932
  *
1007
- * @param options - User identifier, media type, and optional filters
1008
- * @returns Paginated list of media list entries
1009
- *
1010
- * @example
1011
- * ```ts
1012
- * import { MediaType, MediaListStatus } from "ani-client";
1013
- *
1014
- * // Get a user's completed anime list
1015
- * const list = await client.getUserMediaList({
1016
- * userName: "AniList",
1017
- * type: MediaType.ANIME,
1018
- * status: MediaListStatus.COMPLETED,
1019
- * });
1020
- * list.results.forEach((entry) =>
1021
- * console.log(`${entry.media.title.romaji} — ${entry.score}/100`)
1022
- * );
1023
- * ```
933
+ * @param idOrName - The AniList user ID (number) or username (string)
1024
934
  */
935
+ getUser(idOrName: number | string): Promise<User>;
936
+ /** Search for users by name. */
937
+ searchUsers(options?: SearchUserOptions): Promise<PagedResult<User>>;
938
+ /** Get a user's anime or manga list. */
1025
939
  getUserMediaList(options: GetUserMediaListOptions): Promise<PagedResult<MediaListEntry>>;
1026
- /**
1027
- * Fetch a studio by its AniList ID.
1028
- *
1029
- * Returns studio details along with its most popular productions.
1030
- *
1031
- * @param id - The AniList studio ID
1032
- */
1033
- getStudio(id: number): Promise<StudioDetail>;
1034
- /**
1035
- * Search for studios by name.
1036
- *
1037
- * @param options - Search / pagination parameters
1038
- * @returns Paginated list of studios
1039
- *
1040
- * @example
1041
- * ```ts
1042
- * const studios = await client.searchStudios({ query: "MAPPA" });
1043
- * ```
1044
- */
1045
- searchStudios(options?: SearchStudioOptions): Promise<PagedResult<StudioDetail>>;
1046
- /**
1047
- * Get all available genres on AniList.
1048
- *
1049
- * @returns Array of genre strings (e.g. "Action", "Adventure", ...)
1050
- */
940
+ /** Fetch a studio by its AniList ID. */
941
+ getStudio(id: number): Promise<Studio>;
942
+ /** Search for studios by name. */
943
+ searchStudios(options?: SearchStudioOptions): Promise<PagedResult<Studio>>;
944
+ /** Fetch a forum thread by its AniList ID. */
945
+ getThread(id: number): Promise<Thread>;
946
+ /** Get recent forum threads, optionally filtered by search, media, or category. */
947
+ getRecentThreads(options?: SearchThreadOptions): Promise<PagedResult<Thread>>;
948
+ /** Get all available genres on AniList. */
1051
949
  getGenres(): Promise<string[]>;
1052
- /**
1053
- * Get all available media tags on AniList.
1054
- *
1055
- * @returns Array of tag objects with id, name, description, category, isAdult
1056
- */
950
+ /** Get all available media tags on AniList. */
1057
951
  getTags(): Promise<MediaTag[]>;
952
+ /** Execute an arbitrary GraphQL query against the AniList API. */
953
+ raw<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
1058
954
  /**
1059
- * Auto-paginating async iterator.
1060
- *
1061
- * Wraps any paginated method and yields individual items across all pages.
1062
- * Stops when `hasNextPage` is `false` or `maxPages` is reached.
955
+ * Auto-paginating async iterator. Yields individual items across all pages.
1063
956
  *
1064
957
  * @param fetchPage - A function that takes a page number and returns a `PagedResult<T>`
1065
958
  * @param maxPages - Maximum number of pages to fetch (default: Infinity)
1066
- * @returns An async iterable iterator of individual items
1067
- *
1068
- * @example
1069
- * ```ts
1070
- * // Iterate over all search results
1071
- * for await (const anime of client.paginate((page) =>
1072
- * client.searchMedia({ query: "Naruto", page, perPage: 10 })
1073
- * )) {
1074
- * console.log(anime.title.romaji);
1075
- * }
1076
- *
1077
- * // Limit to 3 pages
1078
- * for await (const anime of client.paginate(
1079
- * (page) => client.getTrending(MediaType.ANIME, page, 20),
1080
- * 3,
1081
- * )) {
1082
- * console.log(anime.title.romaji);
1083
- * }
1084
- * ```
1085
959
  */
1086
960
  paginate<T>(fetchPage: (page: number) => Promise<PagedResult<T>>, maxPages?: number): AsyncGenerator<T, void, undefined>;
1087
- /**
1088
- * Fetch multiple media entries in a single API request.
1089
- * Uses GraphQL aliases to batch up to 50 IDs per call.
1090
- *
1091
- * @param ids - Array of AniList media IDs
1092
- * @returns Array of media objects (same order as input IDs)
1093
- */
961
+ /** Fetch multiple media entries in a single API request. */
1094
962
  getMediaBatch(ids: number[]): Promise<Media[]>;
1095
- /**
1096
- * Fetch multiple characters in a single API request.
1097
- *
1098
- * @param ids - Array of AniList character IDs
1099
- * @returns Array of character objects (same order as input IDs)
1100
- */
963
+ /** Fetch multiple characters in a single API request. */
1101
964
  getCharacterBatch(ids: number[]): Promise<Character[]>;
1102
- /**
1103
- * Fetch multiple staff members in a single API request.
1104
- *
1105
- * @param ids - Array of AniList staff IDs
1106
- * @returns Array of staff objects (same order as input IDs)
1107
- */
965
+ /** Fetch multiple staff members in a single API request. */
1108
966
  getStaffBatch(ids: number[]): Promise<Staff[]>;
1109
967
  /** @internal */
1110
968
  private executeBatch;
1111
- /**
1112
- * Clear the entire response cache.
1113
- */
969
+ /** Clear the entire response cache. */
1114
970
  clearCache(): Promise<void>;
1115
- /**
1116
- * Number of entries currently in the cache.
1117
- * For async adapters like Redis, this may return a Promise.
1118
- */
971
+ /** Number of entries currently in the cache. */
1119
972
  get cacheSize(): number | Promise<number>;
1120
- /**
1121
- * Remove cache entries whose key matches the given pattern.
1122
- *
1123
- * @param pattern — A string (converted to RegExp) or RegExp
1124
- * @returns Number of entries removed
1125
- */
973
+ /** Remove cache entries whose key matches the given pattern. */
1126
974
  invalidateCache(pattern: string | RegExp): Promise<number>;
975
+ /** Clean up resources held by the client. */
976
+ destroy(): Promise<void>;
1127
977
  }
1128
978
 
1129
979
  /**
@@ -1160,7 +1010,10 @@ declare class MemoryCache implements CacheAdapter {
1160
1010
  /**
1161
1011
  * Remove all entries whose key matches the given pattern.
1162
1012
  *
1163
- * @param pattern A string (converted to RegExp) or RegExp.
1013
+ * - **String**: treated as a substring match (e.g. `"Media"` removes all keys containing `"Media"`).
1014
+ * - **RegExp**: tested against each key directly.
1015
+ *
1016
+ * @param pattern — A string (substring match) or RegExp.
1164
1017
  * @returns Number of entries removed.
1165
1018
  */
1166
1019
  invalidate(pattern: string | RegExp): number;
@@ -1253,8 +1106,10 @@ declare class RateLimiter {
1253
1106
  private readonly enabled;
1254
1107
  private readonly timeoutMs;
1255
1108
  private readonly retryOnNetworkError;
1256
- /** @internal */
1257
- private timestamps;
1109
+ /** @internal — sliding window: circular buffer of timestamps */
1110
+ private readonly timestamps;
1111
+ private head;
1112
+ private count;
1258
1113
  constructor(options?: RateLimitOptions);
1259
1114
  /**
1260
1115
  * Wait until it's safe to make a request (respects rate limit window).
@@ -1262,14 +1117,26 @@ declare class RateLimiter {
1262
1117
  acquire(): Promise<void>;
1263
1118
  /**
1264
1119
  * Execute a fetch with automatic retry on 429 responses and network errors.
1120
+ * Uses exponential backoff with jitter for retry delays.
1265
1121
  */
1266
1122
  fetchWithRetry(url: string, init: RequestInit, hooks?: {
1267
1123
  onRetry?: (attempt: number, reason: string, delayMs: number) => void;
1268
1124
  onRateLimit?: (retryAfterMs: number) => void;
1269
1125
  }): Promise<Response>;
1126
+ /** @internal — Exponential backoff with jitter, capped at 30s */
1127
+ private exponentialDelay;
1270
1128
  /** @internal */
1271
1129
  private fetchWithTimeout;
1272
1130
  private sleep;
1273
1131
  }
1274
1132
 
1275
- export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, 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 ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type StudioDetail, type User, type UserAvatar, type UserStatistics, type VoiceActor };
1133
+ /**
1134
+ * Parses AniList specific markdown into standard HTML.
1135
+ * Includes formatting for spoilers, images, videos (youtube/webm), and standard markdown elements.
1136
+ *
1137
+ * @param text The AniList markdown text to parse
1138
+ * @returns The parsed HTML string
1139
+ */
1140
+ declare function parseAniListMarkdown(text: string): string;
1141
+
1142
+ export { type AiringSchedule, AiringSort, AniListClient, type AniListClientOptions, AniListError, type AniListHooks, type CacheAdapter, type CacheOptions, type Character, type CharacterImage, type CharacterIncludeOptions, type CharacterMediaEdge, type CharacterName, CharacterRole, CharacterSort, type DayOfWeek, type ExternalLink, type FuzzyDate, type GetAiringOptions, type GetPlanningOptions, type GetRecentChaptersOptions, type GetRecommendationsOptions, type GetSeasonOptions, type GetUserMediaListOptions, type Media, type MediaCharacterConnection, type MediaCharacterEdge, type MediaConnection, type MediaCoverImage, type MediaEdge, MediaFormat, type MediaIncludeOptions, type MediaListEntry, MediaListSort, MediaListStatus, type MediaRecommendationNode, MediaRelationType, MediaSeason, MediaSort, MediaSource, type MediaStaffConnection, type MediaStaffEdge, type MediaStats, MediaStatus, type MediaTag, type MediaTitle, type MediaTrailer, MediaType, MemoryCache, type NextAiringEpisode, type PageInfo, type PagedResult, type RateLimitOptions, RateLimiter, type Recommendation, RecommendationSort, RedisCache, type RedisCacheOptions, type RedisLikeClient, type ScoreDistribution, type SearchCharacterOptions, type SearchMediaOptions, type SearchStaffOptions, type SearchStudioOptions, type SearchThreadOptions, type SearchUserOptions, type Staff, type StaffImage, type StaffIncludeOptions, type StaffMediaNode, type StaffName, StaffSort, type StatusDistribution, type StreamingEpisode, type Studio, type StudioConnection, type Thread, type ThreadCategory, type ThreadMediaCategory, ThreadSort, type User, type UserAvatar, UserSort, type UserStatistics, type VoiceActor, type WeeklySchedule, parseAniListMarkdown };