ani-client 2.3.0 → 2.4.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 +2 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +77 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,60 @@
|
|
|
1
|
+
// src/utils/dataloader.ts
|
|
2
|
+
var BatchLoader = class {
|
|
3
|
+
constructor(batchFetch, maxWaitMs = 50) {
|
|
4
|
+
this.batchFetch = batchFetch;
|
|
5
|
+
this.maxWaitMs = maxWaitMs;
|
|
6
|
+
}
|
|
7
|
+
queue = /* @__PURE__ */ new Map();
|
|
8
|
+
timeout = null;
|
|
9
|
+
/**
|
|
10
|
+
* Queue an ID to be fetched in the next batch.
|
|
11
|
+
* Returns a Promise that resolves when the batch request completes.
|
|
12
|
+
*/
|
|
13
|
+
async load(id) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
let callbacks = this.queue.get(id);
|
|
16
|
+
if (!callbacks) {
|
|
17
|
+
callbacks = [];
|
|
18
|
+
this.queue.set(id, callbacks);
|
|
19
|
+
}
|
|
20
|
+
callbacks.push({ resolve, reject });
|
|
21
|
+
if (this.timeout === null) {
|
|
22
|
+
this.timeout = setTimeout(() => this.dispatch(), this.maxWaitMs);
|
|
23
|
+
if (typeof this.timeout.unref === "function") {
|
|
24
|
+
this.timeout.unref();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async dispatch() {
|
|
30
|
+
this.timeout = null;
|
|
31
|
+
if (this.queue.size === 0) return;
|
|
32
|
+
const currentQueue = this.queue;
|
|
33
|
+
this.queue = /* @__PURE__ */ new Map();
|
|
34
|
+
const ids = Array.from(currentQueue.keys());
|
|
35
|
+
try {
|
|
36
|
+
const results = await this.batchFetch(ids);
|
|
37
|
+
const resultMap = /* @__PURE__ */ new Map();
|
|
38
|
+
for (const item of results) {
|
|
39
|
+
resultMap.set(item.id, item);
|
|
40
|
+
}
|
|
41
|
+
for (const [id, callbacks] of currentQueue.entries()) {
|
|
42
|
+
const result = resultMap.get(id);
|
|
43
|
+
if (result) {
|
|
44
|
+
for (const cb of callbacks) cb.resolve(result);
|
|
45
|
+
} else {
|
|
46
|
+
const err = new Error(`Item with ID ${id} not found in batch response`);
|
|
47
|
+
for (const cb of callbacks) cb.reject(err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
for (const callbacks of currentQueue.values()) {
|
|
52
|
+
for (const cb of callbacks) cb.reject(err);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
1
58
|
// src/utils/markdown.ts
|
|
2
59
|
function isSafeUrl(url) {
|
|
3
60
|
return /^https?:\/\//i.test(url);
|
|
@@ -2529,7 +2586,7 @@ function mapFavorites(fav) {
|
|
|
2529
2586
|
|
|
2530
2587
|
// src/client/index.ts
|
|
2531
2588
|
var DEFAULT_API_URL = "https://graphql.anilist.co";
|
|
2532
|
-
var LIB_VERSION = "2.
|
|
2589
|
+
var LIB_VERSION = "2.4.0" ;
|
|
2533
2590
|
var AniListClient = class {
|
|
2534
2591
|
apiUrl;
|
|
2535
2592
|
headers;
|
|
@@ -2541,6 +2598,9 @@ var AniListClient = class {
|
|
|
2541
2598
|
inFlight = /* @__PURE__ */ new Map();
|
|
2542
2599
|
_rateLimitInfo;
|
|
2543
2600
|
_lastRequestMeta;
|
|
2601
|
+
mediaLoader;
|
|
2602
|
+
characterLoader;
|
|
2603
|
+
staffLoader;
|
|
2544
2604
|
constructor(options = {}) {
|
|
2545
2605
|
this.apiUrl = options.apiUrl ?? DEFAULT_API_URL;
|
|
2546
2606
|
this.headers = {
|
|
@@ -2556,6 +2616,9 @@ var AniListClient = class {
|
|
|
2556
2616
|
this.hooks = options.hooks ?? {};
|
|
2557
2617
|
this.logger = options.logger;
|
|
2558
2618
|
this.signal = options.signal;
|
|
2619
|
+
this.mediaLoader = new BatchLoader((ids) => this.getMediaBatch(ids), 50);
|
|
2620
|
+
this.characterLoader = new BatchLoader((ids) => this.getCharacterBatch(ids), 50);
|
|
2621
|
+
this.staffLoader = new BatchLoader((ids) => this.getStaffBatch(ids), 50);
|
|
2559
2622
|
}
|
|
2560
2623
|
/**
|
|
2561
2624
|
* The current rate limit information from the last API response.
|
|
@@ -2686,6 +2749,9 @@ var AniListClient = class {
|
|
|
2686
2749
|
* @param include - Optional related data to include
|
|
2687
2750
|
*/
|
|
2688
2751
|
async getMedia(id, include) {
|
|
2752
|
+
if (!include) {
|
|
2753
|
+
return this.mediaLoader.load(id);
|
|
2754
|
+
}
|
|
2689
2755
|
return getMedia(this, id, include);
|
|
2690
2756
|
}
|
|
2691
2757
|
async getMediaCharacters(mediaId, options = {}) {
|
|
@@ -2754,6 +2820,9 @@ var AniListClient = class {
|
|
|
2754
2820
|
}
|
|
2755
2821
|
/** Fetch a character by AniList ID. Pass `{ voiceActors: true }` to include VA data. */
|
|
2756
2822
|
async getCharacter(id, include) {
|
|
2823
|
+
if (!include) {
|
|
2824
|
+
return this.characterLoader.load(id);
|
|
2825
|
+
}
|
|
2757
2826
|
return getCharacter(this, id, include);
|
|
2758
2827
|
}
|
|
2759
2828
|
/** Search for characters by name. */
|
|
@@ -2762,6 +2831,9 @@ var AniListClient = class {
|
|
|
2762
2831
|
}
|
|
2763
2832
|
/** Fetch a staff member by AniList ID. Pass `{ media: true }` or `{ media: { perPage } }` for media credits. */
|
|
2764
2833
|
async getStaff(id, include) {
|
|
2834
|
+
if (!include) {
|
|
2835
|
+
return this.staffLoader.load(id);
|
|
2836
|
+
}
|
|
2765
2837
|
return getStaff(this, id, include);
|
|
2766
2838
|
}
|
|
2767
2839
|
/** Search for staff (voice actors, directors, etc.). */
|
|
@@ -2881,7 +2953,7 @@ var AniListClient = class {
|
|
|
2881
2953
|
if (ids.length === 0) return [];
|
|
2882
2954
|
validateIds(ids, "mediaId");
|
|
2883
2955
|
const [singleMediaId] = ids;
|
|
2884
|
-
if (ids.length === 1 && singleMediaId !== void 0) return [await
|
|
2956
|
+
if (ids.length === 1 && singleMediaId !== void 0) return [await getMedia(this, singleMediaId)];
|
|
2885
2957
|
return this.executeBatch(ids, buildBatchMediaQuery, "m");
|
|
2886
2958
|
}
|
|
2887
2959
|
/** Fetch multiple characters in a single API request. */
|
|
@@ -2889,7 +2961,8 @@ var AniListClient = class {
|
|
|
2889
2961
|
if (ids.length === 0) return [];
|
|
2890
2962
|
validateIds(ids, "characterId");
|
|
2891
2963
|
const [singleCharId] = ids;
|
|
2892
|
-
if (ids.length === 1 && singleCharId !== void 0)
|
|
2964
|
+
if (ids.length === 1 && singleCharId !== void 0)
|
|
2965
|
+
return [await getCharacter(this, singleCharId)];
|
|
2893
2966
|
return this.executeBatch(ids, buildBatchCharacterQuery, "c");
|
|
2894
2967
|
}
|
|
2895
2968
|
/** Fetch multiple staff members in a single API request. */
|
|
@@ -2897,7 +2970,7 @@ var AniListClient = class {
|
|
|
2897
2970
|
if (ids.length === 0) return [];
|
|
2898
2971
|
validateIds(ids, "staffId");
|
|
2899
2972
|
const [singleStaffId] = ids;
|
|
2900
|
-
if (ids.length === 1 && singleStaffId !== void 0) return [await
|
|
2973
|
+
if (ids.length === 1 && singleStaffId !== void 0) return [await getStaff(this, singleStaffId)];
|
|
2901
2974
|
return this.executeBatch(ids, buildBatchStaffQuery, "s");
|
|
2902
2975
|
}
|
|
2903
2976
|
/** @internal */
|