@vanomarb/animap 1.0.0 → 1.0.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/README.md CHANGED
@@ -117,7 +117,7 @@ await client.toSeries('kitsu:44607', 7, { target: 'tvdb' });
117
117
  // { provider, id, season, episode, span, source, confidence } | null
118
118
  await client.fromSeries('tt8948436', 1, 85); // [{ entry, ids, episode, source, confidence }]
119
119
  await client.series('tvdb:342329', { season: 1 }); // { series, title, images, seasons: [{ season, length, rows, issues }] }
120
- await client.search('soul land', { limit: 5 }); // EntrySummary[]
120
+ await client.search('soul land', { limit: 5 }); // EntrySummary[]; { live: false } = cached only
121
121
  await client.issues({ entry: 'kitsu:44607', type: 'count' }); // { results: Issue[], next }
122
122
  await client.history('anilist:129347'); // Revision[], newest first
123
123
  ```
@@ -149,6 +149,7 @@ await client.titleEpisodes('tt8948436', { season: 1 });
149
149
  // { season: 1, seasons: [1, 0], episodes: [{ season, episode, name, overview, released, thumbnail, runtime, rating, mapped }] }
150
150
  await client.titles({ q: 'soul land', type: 'series', genre: 'Action', sort: 'popular', limit: 24 });
151
151
  // { results: TitleSummary[], total, next } — pass `next` back as `cursor`
152
+ await client.titles({ q: 'tmdb:76572', live: false }); // an id is a lookup; live: false = server cache only, no upstream call
152
153
  await client.trending({ limit: 12 }); // TitleSummary[]
153
154
  await client.activity({ limit: 20 }); // recent mapping edits
154
155
  await client.stats(); // { titles, entries, mappedEpisodes, ranges, sources, importedAt }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanomarb/animap",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AniMap client: map Kitsu, MAL, AniList and AniDB entries to TVDB, TMDB and IMDb seasons and episodes, read titles and episodes, and enrich them in-process with your own TMDB, TVDB and Fanart.tv keys.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/client.js CHANGED
@@ -256,11 +256,13 @@ export class Client {
256
256
  }
257
257
 
258
258
  /** Entry search by title, alias or id. Returns EntrySummary[]. */
259
- async search(query, { limit } = {}) {
259
+ /** `live: false`: the server answers from its cache only, with no upstream call. */
260
+ async search(query, { limit, live } = {}) {
260
261
  if (typeof query !== 'string' || !query.trim()) throw new ClientError('invalid_argument', 'search() needs a non-empty query');
261
262
  optionalInt(limit, 'limit', 1);
262
263
  const params = new URLSearchParams({ q: query.trim() });
263
264
  if (limit !== undefined) params.set('limit', String(limit));
265
+ if (live === false) params.set('live', '0');
264
266
  const body = await this.#cached(`search:${params}`, () => this.#request('GET', `/v1/search?${params}`));
265
267
  return body.results ?? [];
266
268
  }
@@ -356,7 +358,7 @@ export class Client {
356
358
  * Browse or search titles. `q` matches names, aliases and any id.
357
359
  * Returns { results: TitleSummary[], total, next }; pass `next` back as `cursor`.
358
360
  */
359
- async titles({ q, type, format, year, genre, mapped, issues, sort, cursor, limit } = {}) {
361
+ async titles({ q, type, format, year, genre, mapped, issues, sort, cursor, limit, live } = {}) {
360
362
  optionalInt(year, 'year', 0);
361
363
  optionalInt(limit, 'limit', 1);
362
364
  const params = new URLSearchParams();
@@ -364,6 +366,7 @@ export class Client {
364
366
  if (v !== undefined && v !== null && v !== '') params.set(k, String(v).trim());
365
367
  }
366
368
  if (issues) params.set('issues', '1');
369
+ if (live === false) params.set('live', '0');
367
370
  const qs = params.toString() ? `?${params}` : '';
368
371
  return this.#cached(`titles:${qs}`, () => this.#request('GET', `/v1/titles${qs}`));
369
372
  }
@@ -439,7 +442,9 @@ export class Client {
439
442
  const core = this.#core;
440
443
  const cached = await core.providerCache.get('title', server.id, core.sig);
441
444
  if (cached) return { sources: cached, errors: [] };
442
- const findTitle = async (ref) => (await this.titles({ q: ref, limit: 1 })).results?.[0] ?? null;
445
+ // Recommendations resolve from the server's cache only: a similar title nobody has
446
+ // opened yet is left out rather than resolved live, eight times per title.
447
+ const findTitle = async (ref) => (await this.titles({ q: ref, limit: 1, live: false })).results?.[0] ?? null;
443
448
  const { sources, errors } = await fetchSources(server, core.keys, { fetch: core.fetch, findTitle, signal });
444
449
  this.#report(errors);
445
450
  if (!errors.some(isTransient) && !errors.some((e) => e.code === 'aborted')) {
package/src/index.d.ts CHANGED
@@ -48,6 +48,9 @@ export interface Images {
48
48
  }
49
49
 
50
50
  export type EntrySummary = Omit<Entry, 'ranges'> & {
51
+ names: Names;
52
+ /** On search() results: the Cinemeta-format id of the entry's title, null when none is cached. */
53
+ titleId?: string | null;
51
54
  rangeCount: number;
52
55
  issueCount: number;
53
56
  /** Targets the entry has effective ranges for, in the order tvdb, tmdb, imdb. */
@@ -151,11 +154,23 @@ export interface TitleSeason {
151
154
  poster: string | null;
152
155
  }
153
156
 
157
+ /** A title's name in three forms; each null when unknown. */
158
+ export interface Names {
159
+ /** English only (the `name` rule). */
160
+ english: string | null;
161
+ /** Kitsu's romanisation (en_jp, en_cn or en_kr). */
162
+ romaji: string | null;
163
+ /** ja_jp, zh_cn or ko_kr. */
164
+ native: string | null;
165
+ }
166
+
154
167
  export interface TitleSummary {
155
- /** Cinemeta-format id: "tt…", else "kitsu:<id>", "tmdb:<id>", "tvdb:<id>" or an entry id. */
168
+ /** Cinemeta-format id: "tt…", else "kitsu:<id>", "tmdb:<id>", "tvdb:<id>", then "mal:", "anilist:" or "anidb:". */
156
169
  id: string;
157
170
  type: TitleType;
171
+ /** names.english, else names.romaji. */
158
172
  name: string | null;
173
+ names: Names;
159
174
  year: string | null;
160
175
  format: Format;
161
176
  poster: string | null;
@@ -173,7 +188,9 @@ export interface Title {
173
188
  id: string;
174
189
  type: TitleType;
175
190
  ids: Record<SeriesProvider | AnimeProvider, string | null>;
191
+ /** names.english, else names.romaji. */
176
192
  name: string | null;
193
+ names: Names;
177
194
  originalName: string | null;
178
195
  description: string | null;
179
196
  genres: string[];
@@ -223,7 +240,7 @@ export interface TitleEpisodes {
223
240
  }
224
241
 
225
242
  export interface TitlesQuery {
226
- /** Names, aliases and any id (an anime ref resolves to its title). */
243
+ /** Names and aliases; an id (tt…, tmdb:N, kitsu:N, …) is a lookup of that id. */
227
244
  q?: string;
228
245
  type?: TitleType;
229
246
  format?: Format;
@@ -236,6 +253,8 @@ export interface TitlesQuery {
236
253
  /** `next` from the previous page. */
237
254
  cursor?: string;
238
255
  limit?: number;
256
+ /** false: the server answers from its cache only, with no upstream call. */
257
+ live?: boolean;
239
258
  }
240
259
 
241
260
  export interface TitlesPage {
@@ -567,7 +586,7 @@ export class Client {
567
586
  /** Every mapped entry of a series ("tvdb:342329"), grouped by season. */
568
587
  series(ref: string, options?: { season?: number }): Promise<SeriesResponse>;
569
588
  /** Entry search by title, alias or id. */
570
- search(query: string, options?: { limit?: number }): Promise<EntrySummary[]>;
589
+ search(query: string, options?: { limit?: number; /** false: the server's cache only, no upstream call. */ live?: boolean }): Promise<EntrySummary[]>;
571
590
  /** Mapping issues, optionally for one entry and one type. */
572
591
  issues(options?: { type?: Issue['type']; entry?: string; cursor?: string; limit?: number }): Promise<{ results: Issue[]; next: string | null }>;
573
592
  /** Edit history of an entry, newest first. */