@media-engine/core 0.1.0 → 1.0.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.
Files changed (121) hide show
  1. package/README.md +40 -255
  2. package/README.ru.md +80 -0
  3. package/dist/cache/memory.d.ts +5 -0
  4. package/dist/cache/memory.js +43 -3
  5. package/dist/cache/memory.js.map +1 -1
  6. package/dist/cache/types.d.ts +2 -0
  7. package/dist/details/types.d.ts +6 -0
  8. package/dist/engine/availability.d.ts +6 -0
  9. package/dist/engine/availability.js +137 -0
  10. package/dist/engine/availability.js.map +1 -0
  11. package/dist/engine/circuit-breaker.d.ts +37 -0
  12. package/dist/engine/circuit-breaker.js +174 -0
  13. package/dist/engine/circuit-breaker.js.map +1 -0
  14. package/dist/engine/concurrency-limiter.d.ts +13 -0
  15. package/dist/engine/concurrency-limiter.js +109 -0
  16. package/dist/engine/concurrency-limiter.js.map +1 -0
  17. package/dist/engine/engine.d.ts +15 -5
  18. package/dist/engine/engine.js +510 -848
  19. package/dist/engine/engine.js.map +1 -1
  20. package/dist/engine/in-flight.d.ts +15 -0
  21. package/dist/engine/in-flight.js +80 -0
  22. package/dist/engine/in-flight.js.map +1 -0
  23. package/dist/engine/operation.d.ts +7 -0
  24. package/dist/engine/operation.js +49 -0
  25. package/dist/engine/operation.js.map +1 -0
  26. package/dist/engine/provider-calls.d.ts +52 -0
  27. package/dist/engine/provider-calls.js +262 -0
  28. package/dist/engine/provider-calls.js.map +1 -0
  29. package/dist/engine/query.d.ts +26 -0
  30. package/dist/engine/query.js +430 -0
  31. package/dist/engine/query.js.map +1 -0
  32. package/dist/engine/response-meta.d.ts +15 -0
  33. package/dist/engine/response-meta.js +33 -0
  34. package/dist/engine/response-meta.js.map +1 -0
  35. package/dist/engine/runtime.d.ts +5 -0
  36. package/dist/engine/runtime.js +48 -0
  37. package/dist/engine/runtime.js.map +1 -0
  38. package/dist/engine/search-discovery.d.ts +3 -0
  39. package/dist/engine/search-discovery.js +35 -0
  40. package/dist/engine/search-discovery.js.map +1 -0
  41. package/dist/engine/search-enrichment-shared.d.ts +23 -0
  42. package/dist/engine/search-enrichment-shared.js +68 -0
  43. package/dist/engine/search-enrichment-shared.js.map +1 -0
  44. package/dist/engine/search-enrichment.d.ts +42 -0
  45. package/dist/engine/search-enrichment.js +150 -0
  46. package/dist/engine/search-enrichment.js.map +1 -0
  47. package/dist/engine/search-identity-snapshot.d.ts +15 -0
  48. package/dist/engine/search-identity-snapshot.js +101 -0
  49. package/dist/engine/search-identity-snapshot.js.map +1 -0
  50. package/dist/engine/search-outcomes.d.ts +32 -0
  51. package/dist/engine/search-outcomes.js +118 -0
  52. package/dist/engine/search-outcomes.js.map +1 -0
  53. package/dist/engine/search-poster-enrichment.d.ts +31 -0
  54. package/dist/engine/search-poster-enrichment.js +93 -0
  55. package/dist/engine/search-poster-enrichment.js.map +1 -0
  56. package/dist/engine/search-result-freeze.d.ts +13 -0
  57. package/dist/engine/search-result-freeze.js +155 -0
  58. package/dist/engine/search-result-freeze.js.map +1 -0
  59. package/dist/engine/stale-fallback.d.ts +11 -0
  60. package/dist/engine/stale-fallback.js +60 -0
  61. package/dist/engine/stale-fallback.js.map +1 -0
  62. package/dist/engine/timeout-budget.d.ts +7 -0
  63. package/dist/engine/timeout-budget.js +31 -0
  64. package/dist/engine/timeout-budget.js.map +1 -0
  65. package/dist/engine/torrents.d.ts +22 -0
  66. package/dist/engine/torrents.js +188 -0
  67. package/dist/engine/torrents.js.map +1 -0
  68. package/dist/engine/types.d.ts +35 -0
  69. package/dist/errors/types.d.ts +1 -1
  70. package/dist/errors/types.js.map +1 -1
  71. package/dist/index.d.ts +2 -1
  72. package/dist/index.js +1 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/media/types.d.ts +1 -1
  75. package/dist/merge/details-identity.d.ts +5 -0
  76. package/dist/merge/details-identity.js +63 -0
  77. package/dist/merge/details-identity.js.map +1 -0
  78. package/dist/merge/diversity.d.ts +15 -0
  79. package/dist/merge/diversity.js +52 -0
  80. package/dist/merge/diversity.js.map +1 -0
  81. package/dist/merge/fields.d.ts +25 -0
  82. package/dist/merge/fields.js +364 -0
  83. package/dist/merge/fields.js.map +1 -0
  84. package/dist/merge/grouping.d.ts +3 -0
  85. package/dist/merge/grouping.js +143 -0
  86. package/dist/merge/grouping.js.map +1 -0
  87. package/dist/merge/identity.d.ts +5 -0
  88. package/dist/merge/identity.js +21 -0
  89. package/dist/merge/identity.js.map +1 -0
  90. package/dist/merge/internal.d.ts +22 -0
  91. package/dist/merge/internal.js +15 -0
  92. package/dist/merge/internal.js.map +1 -0
  93. package/dist/merge/media-type.d.ts +5 -0
  94. package/dist/merge/media-type.js +15 -0
  95. package/dist/merge/media-type.js.map +1 -0
  96. package/dist/merge/priority.d.ts +9 -0
  97. package/dist/merge/priority.js +63 -0
  98. package/dist/merge/priority.js.map +1 -0
  99. package/dist/merge/scoring.d.ts +15 -0
  100. package/dist/merge/scoring.js +364 -0
  101. package/dist/merge/scoring.js.map +1 -0
  102. package/dist/merge/strategy.js +66 -955
  103. package/dist/merge/strategy.js.map +1 -1
  104. package/dist/merge/title.d.ts +4 -0
  105. package/dist/merge/title.js +22 -0
  106. package/dist/merge/title.js.map +1 -0
  107. package/dist/providers/registry.d.ts +4 -2
  108. package/dist/providers/registry.js +11 -2
  109. package/dist/providers/registry.js.map +1 -1
  110. package/dist/providers/types.d.ts +4 -0
  111. package/dist/response/types.d.ts +21 -0
  112. package/dist/search/types.d.ts +34 -0
  113. package/dist/testing/providers.js +2 -0
  114. package/dist/testing/providers.js.map +1 -1
  115. package/dist/torrent/index.d.ts +1 -0
  116. package/dist/torrent/index.js +2 -0
  117. package/dist/torrent/index.js.map +1 -0
  118. package/dist/torrent/types.d.ts +132 -0
  119. package/dist/torrent/types.js +2 -0
  120. package/dist/torrent/types.js.map +1 -0
  121. package/package.json +13 -4
@@ -0,0 +1,364 @@
1
+ import { hasSharedStrongId } from "./identity.js";
2
+ import { normalizeTitle, titleCandidates } from "./title.js";
3
+ // Calculates a public score from match strength, query relevance, and popularity signals.
4
+ // Вычисляет публичную оценку по силе совпадения, релевантности запросу и популярности.
5
+ export function scoreGroup(group, entries, context) {
6
+ return rankSearchGroup(group, entries, context).score;
7
+ }
8
+ // Calculates the public score and its debug explanation from the same normalized signals.
9
+ // Вычисляет публичный score и его debug-объяснение из одних и тех же сигналов.
10
+ export function rankSearchGroup(group, entries, context) {
11
+ const query = context.query;
12
+ const queryIds = "ids" in (query ?? {}) ? query?.ids : undefined;
13
+ const queryTitle = "title" in (query ?? {}) ? query?.title : undefined;
14
+ if (queryIds && entries.some((entry) => hasSharedStrongId(queryIds, entry.result.item.ids))) {
15
+ return createRankResult("external_id", group, 1, emptyTitleMatch(), {
16
+ base: signal(1, 1),
17
+ });
18
+ }
19
+ if (!queryTitle?.trim()) {
20
+ const baseScore = baseGroupScore(group, entries);
21
+ return createRankResult("non_text", group, baseScore, emptyTitleMatch(), {
22
+ base: signal(baseScore, 1),
23
+ });
24
+ }
25
+ const baseScore = baseTextSearchScore(group, entries);
26
+ const titleMatch = titleRelevanceEvidence(entries, queryTitle);
27
+ const titleScore = titleMatch.score;
28
+ const exactPrimaryTitleScore = hasExactPrimaryTitle(entries, queryTitle) ? 1 : 0;
29
+ const popularityScore = ratingVotesScore(entries);
30
+ const ratingScore = normalizedRatingScore(entries);
31
+ const idScore = externalIdCompletenessScore(entries);
32
+ const sourceScore = sourceCoverageScore(entries);
33
+ const authorityScore = sourceAuthorityScore(entries);
34
+ const signals = {
35
+ base: signal(baseScore, 1),
36
+ title: signal(titleScore, 0.2),
37
+ // Prefer exact primary/original intent over prefix and incidental-alias noise while
38
+ // still allowing overwhelmingly corroborated canonical results for broad short queries.
39
+ exactPrimaryTitle: signal(exactPrimaryTitleScore, 0.3),
40
+ popularity: signal(popularityScore, 0.15),
41
+ rating: signal(ratingScore, 0.03),
42
+ externalIds: signal(idScore, 0.2),
43
+ sourceCoverage: signal(sourceScore, 0.02),
44
+ sourceAuthority: signal(authorityScore, 0.1),
45
+ };
46
+ const preBoundedScore = Object.values(signals).reduce((total, rankingSignal) => total + rankingSignal.contribution, 0);
47
+ return createRankResult("text", group, boundedTextScore(preBoundedScore), titleMatch, signals);
48
+ }
49
+ // Distinguishes exact primary/original titles from incidental alternative aliases.
50
+ // Отличает точные основные/оригинальные названия от случайных alternative aliases.
51
+ export function hasExactPrimaryTitle(entries, queryTitle) {
52
+ const normalizedQuery = normalizeTitle(queryTitle);
53
+ return entries.some((entry) => [entry.result.item.title, entry.result.item.originalTitle]
54
+ .filter((title) => Boolean(title))
55
+ .some((title) => normalizeTitle(title) === normalizedQuery));
56
+ }
57
+ // Scores how well result titles match the user's text query.
58
+ // Оценивает, насколько названия результатов совпадают с текстовым запросом пользователя.
59
+ export function titleRelevanceScore(entries, queryTitle) {
60
+ return titleRelevanceEvidence(entries, queryTitle).score;
61
+ }
62
+ // Returns the strongest deterministic title match used by ranking and debug evidence.
63
+ // Возвращает сильнейшее детерминированное title match для ranking и debug evidence.
64
+ export function titleRelevanceEvidence(entries, queryTitle) {
65
+ const normalizedQuery = normalizeTitle(queryTitle);
66
+ if (!normalizedQuery) {
67
+ return emptyTitleMatch();
68
+ }
69
+ let best = { kind: "none", score: 0 };
70
+ for (const entry of entries) {
71
+ const primaryTitles = new Set([entry.result.item.title, entry.result.item.originalTitle]
72
+ .filter((title) => Boolean(title))
73
+ .map(normalizeTitle));
74
+ for (const title of titleCandidates(entry.result.item)) {
75
+ const match = scoreNormalizedTitle(normalizeTitle(title), normalizedQuery);
76
+ if (match.score > best.score) {
77
+ best = {
78
+ kind: match.kind === "exact"
79
+ ? primaryTitles.has(normalizeTitle(title))
80
+ ? "exact_primary"
81
+ : "exact_alias"
82
+ : match.kind,
83
+ score: match.score,
84
+ matchedTitle: title,
85
+ };
86
+ }
87
+ }
88
+ }
89
+ return best;
90
+ }
91
+ // Keeps legacy scores for non-title searches where no relevance ranking is possible.
92
+ // Сохраняет прежние оценки для поиска без title, где нельзя посчитать релевантность.
93
+ function baseGroupScore(group, entries) {
94
+ switch (group.matchStrength) {
95
+ case "exact_id":
96
+ return 1;
97
+ case "exact_title_year_type":
98
+ return 0.9;
99
+ case "normalized_title_year_type":
100
+ return 0.8;
101
+ case "weak":
102
+ return 0.4;
103
+ case "none":
104
+ return clampScore(entries[0]?.result.confidence ?? 0.5);
105
+ }
106
+ }
107
+ // Starts text-search scoring below 1 so popularity and relevance can break exact-ID ties.
108
+ // Начинает оценку текстового поиска ниже 1, чтобы популярность и релевантность разбивали tie по ID.
109
+ function baseTextSearchScore(group, entries) {
110
+ switch (group.matchStrength) {
111
+ case "exact_id":
112
+ return 0.44 + bestProviderConfidence(entries) * 0.18;
113
+ case "exact_title_year_type":
114
+ return 0.62;
115
+ case "normalized_title_year_type":
116
+ return 0.52;
117
+ case "weak":
118
+ return 0.25;
119
+ case "none":
120
+ return bestProviderConfidence(entries) * 0.45;
121
+ }
122
+ }
123
+ // Uses the strongest provider confidence inside a merged group.
124
+ // Использует самый сильный confidence провайдера внутри объединенной группы.
125
+ function bestProviderConfidence(entries) {
126
+ return Math.max(...entries.map((entry) => clampScore(entry.result.confidence ?? 0.5)));
127
+ }
128
+ // Scores one normalized title against one normalized query.
129
+ // Оценивает одно нормализованное название против одного нормализованного запроса.
130
+ function scoreNormalizedTitle(title, query) {
131
+ if (!title) {
132
+ return { kind: "none", score: 0 };
133
+ }
134
+ if (title === query) {
135
+ return { kind: "exact", score: 1 };
136
+ }
137
+ if (title.replace(/\s+/g, "") === query.replace(/\s+/g, "")) {
138
+ return { kind: "joined", score: 0.98 };
139
+ }
140
+ if (title.startsWith(`${query} `)) {
141
+ return { kind: "prefix", score: adjustPartialTitleScore(0.92, title, query) };
142
+ }
143
+ if (title.includes(` ${query} `) || title.endsWith(` ${query}`)) {
144
+ return { kind: "contains", score: adjustPartialTitleScore(0.75, title, query) };
145
+ }
146
+ const queryTokens = query.split(" ").filter(Boolean);
147
+ if (queryTokens.length > 0 && queryTokens.every((token) => title.includes(token))) {
148
+ return { kind: "all_tokens", score: adjustPartialTitleScore(0.55, title, query) };
149
+ }
150
+ const titleTokens = title.split(" ").filter(Boolean);
151
+ const fuzzyTokenScores = queryTokens.map((queryToken) => Math.max(...titleTokens.map((titleToken) => fuzzyTokenSimilarity(queryToken, titleToken)), 0));
152
+ const minimumFuzzyScore = queryTokens.length >= 3 ? 0.7 : 0.75;
153
+ if (fuzzyTokenScores.length > 0 &&
154
+ fuzzyTokenScores.every((score) => score >= minimumFuzzyScore)) {
155
+ return {
156
+ kind: "fuzzy",
157
+ score: adjustPartialTitleScore((fuzzyTokenScores.reduce((sum, score) => sum + score, 0) / fuzzyTokenScores.length) * 0.7, title, query),
158
+ };
159
+ }
160
+ return { kind: "none", score: 0 };
161
+ }
162
+ function createRankResult(formula, group, score, titleMatch, partialSignals) {
163
+ const zero = signal(0, 0);
164
+ const signals = {
165
+ base: partialSignals.base ?? zero,
166
+ title: partialSignals.title ?? zero,
167
+ exactPrimaryTitle: partialSignals.exactPrimaryTitle ?? zero,
168
+ popularity: partialSignals.popularity ?? zero,
169
+ rating: partialSignals.rating ?? zero,
170
+ externalIds: partialSignals.externalIds ?? zero,
171
+ sourceCoverage: partialSignals.sourceCoverage ?? zero,
172
+ sourceAuthority: partialSignals.sourceAuthority ?? zero,
173
+ };
174
+ return {
175
+ score,
176
+ evidence: {
177
+ formula,
178
+ matchStrength: group.matchStrength,
179
+ titleMatch,
180
+ signals,
181
+ preBoundedScore: Object.values(signals).reduce((total, rankingSignal) => total + rankingSignal.contribution, 0),
182
+ },
183
+ };
184
+ }
185
+ function signal(value, weight) {
186
+ return { value, weight, contribution: value * weight };
187
+ }
188
+ function emptyTitleMatch() {
189
+ return { kind: "not_applicable", score: 0 };
190
+ }
191
+ // Prefers the closest title completion for multi-word prefix and fuzzy matches.
192
+ // Предпочитает ближайшее продолжение title для multi-word prefix и fuzzy matches.
193
+ function adjustPartialTitleScore(score, title, query) {
194
+ const queryTokenCount = query.split(" ").filter(Boolean).length;
195
+ if (queryTokenCount < 2) {
196
+ return score;
197
+ }
198
+ const titleTokenCount = title.split(" ").filter(Boolean).length;
199
+ const tokenRatio = Math.min(queryTokenCount, titleTokenCount) / Math.max(queryTokenCount, titleTokenCount);
200
+ return score * (0.5 + tokenRatio * 0.5);
201
+ }
202
+ // Allows one small typo in meaningful words while keeping short tokens exact.
203
+ // Допускает одну небольшую опечатку в значимых словах, сохраняя короткие токены точными.
204
+ function fuzzyTokenSimilarity(left, right) {
205
+ if (left === right) {
206
+ return 1;
207
+ }
208
+ if (Math.min(left.length, right.length) < 4) {
209
+ return 0;
210
+ }
211
+ if (isSingleAdjacentTransposition(left, right)) {
212
+ return 1 - 1 / Math.max(left.length, right.length);
213
+ }
214
+ const variants = [right, ...(right.endsWith("s") ? [right.slice(0, -1)] : [])];
215
+ const distance = Math.min(...variants
216
+ .filter((variant) => Math.abs(left.length - variant.length) <= 1)
217
+ .map((variant) => levenshteinDistance(left, variant, 1)));
218
+ if (distance <= 1) {
219
+ return 1 - distance / Math.max(left.length, right.length);
220
+ }
221
+ if (Math.min(left.length, right.length) >= 6 && isTranspositionPlusOneEdit(left, right)) {
222
+ return 1 - 2 / Math.max(left.length, right.length);
223
+ }
224
+ return 0;
225
+ }
226
+ // Allows one adjacent swap plus one insertion, deletion, or substitution in long words.
227
+ // Допускает перестановку соседних символов и еще одну правку в длинных словах.
228
+ function isTranspositionPlusOneEdit(left, right) {
229
+ for (let index = 0; index < right.length - 1; index += 1) {
230
+ const swapped = right.slice(0, index) + right[index + 1] + right[index] + right.slice(index + 2);
231
+ if (Math.abs(left.length - swapped.length) <= 1 && levenshteinDistance(left, swapped, 1) <= 1) {
232
+ return true;
233
+ }
234
+ }
235
+ return false;
236
+ }
237
+ // Recognizes a single swapped adjacent character, a common typing error Levenshtein counts as two.
238
+ // Распознает перестановку соседних символов, которую Levenshtein считает двумя ошибками.
239
+ function isSingleAdjacentTransposition(left, right) {
240
+ if (left.length !== right.length) {
241
+ return false;
242
+ }
243
+ let firstDifference = -1;
244
+ for (let index = 0; index < left.length; index += 1) {
245
+ if (left[index] === right[index]) {
246
+ continue;
247
+ }
248
+ if (firstDifference !== -1) {
249
+ return (index === firstDifference + 1 &&
250
+ left[firstDifference] === right[index] &&
251
+ left[index] === right[firstDifference] &&
252
+ left.slice(index + 1) === right.slice(index + 1));
253
+ }
254
+ firstDifference = index;
255
+ }
256
+ return false;
257
+ }
258
+ function levenshteinDistance(left, right, maxDistance) {
259
+ let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
260
+ for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
261
+ const current = [leftIndex];
262
+ let rowMinimum = leftIndex;
263
+ for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {
264
+ const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;
265
+ const value = Math.min(current[rightIndex - 1] + 1, previous[rightIndex] + 1, previous[rightIndex - 1] + substitutionCost);
266
+ current.push(value);
267
+ rowMinimum = Math.min(rowMinimum, value);
268
+ }
269
+ if (rowMinimum > maxDistance) {
270
+ return maxDistance + 1;
271
+ }
272
+ previous = current;
273
+ }
274
+ return previous[right.length] ?? maxDistance + 1;
275
+ }
276
+ // Scores popularity from the largest available vote count.
277
+ // Оценивает популярность по самому большому доступному числу голосов.
278
+ function ratingVotesScore(entries) {
279
+ const maxVotes = maxRatingVotes(entries);
280
+ return Math.min(1, Math.max(0, (Math.log10(maxVotes + 1) - 3) / 4));
281
+ }
282
+ // Scores normalized rating values across providers.
283
+ // Оценивает нормализованные значения рейтингов от провайдеров.
284
+ function normalizedRatingScore(entries) {
285
+ const values = entries.flatMap((entry) => entry.result.item.ratings
286
+ ?.map((rating) => {
287
+ const value = rating.value / rating.max;
288
+ return value * ratingVoteConfidence(rating.votes);
289
+ })
290
+ .filter((value) => Number.isFinite(value)) ?? []);
291
+ return values.length === 0 ? 0 : Math.max(...values.map((value) => clampScore(value)));
292
+ }
293
+ // Rewards results that carry strong external IDs for better follow-up details lookup.
294
+ // Поощряет результаты с сильными внешними ID для более надежной загрузки деталей.
295
+ function externalIdCompletenessScore(entries) {
296
+ const ids = entries.map((entry) => entry.result.item.ids);
297
+ const hasCatalogAnimeId = ids.some((value) => value?.shikimori || value?.myAnimeList || value?.aniList);
298
+ const animeCatalogScore = hasCatalogAnimeId ? (maxRatingVotes(entries) >= 100_000 ? 1 : 0.5) : 0;
299
+ return Math.max(0, ids.some((value) => value?.imdb) ? 1 : 0, ids.some((value) => value?.kinopoisk) ? 0.9 : 0, ids.some((value) => value?.tmdb) ? 0.8 : 0, animeCatalogScore, ids.some((value) => value?.worldArt) ? 0.3 : 0);
300
+ }
301
+ function maxRatingVotes(entries) {
302
+ return Math.max(0, ...entries.flatMap((entry) => entry.result.item.ratings?.map((rating) => rating.votes ?? 0) ?? []));
303
+ }
304
+ function ratingVoteConfidence(votes) {
305
+ if (votes === undefined) {
306
+ return 0.2;
307
+ }
308
+ if (votes < 1_000) {
309
+ return 0.3;
310
+ }
311
+ if (votes < 100_000) {
312
+ return 0.6;
313
+ }
314
+ return 1;
315
+ }
316
+ // Rewards results confirmed by multiple providers.
317
+ // Поощряет результаты, подтвержденные несколькими провайдерами.
318
+ function sourceCoverageScore(entries) {
319
+ return Math.min(1, new Set(entries.map((entry) => entry.result.provider)).size / 3);
320
+ }
321
+ // Adds a small authority signal for sources that usually imply broader popularity.
322
+ // Добавляет небольшой сигнал авторитетности для источников, которые обычно отражают популярность.
323
+ function sourceAuthorityScore(entries) {
324
+ const providers = [...new Set(entries.map((entry) => entry.result.provider))];
325
+ return (providers.reduce((total, provider) => total + providerAuthority(provider), 0) /
326
+ Math.max(1, providers.length));
327
+ }
328
+ // Scores provider authority for broad text search ranking.
329
+ // Оценивает авторитетность провайдера для ранжирования широкого текстового поиска.
330
+ function providerAuthority(provider) {
331
+ switch (provider) {
332
+ case "wikidata":
333
+ return 0.9;
334
+ case "tmdb":
335
+ return 0.95;
336
+ case "cinemeta":
337
+ return 0.75;
338
+ case "tvmaze":
339
+ return 0.75;
340
+ case "kinobd":
341
+ return 0.75;
342
+ case "imdb":
343
+ return 0.65;
344
+ case "kinopoisk":
345
+ return 0.6;
346
+ case "shikimori":
347
+ return 0.9;
348
+ case "anilist":
349
+ return 0.9;
350
+ default:
351
+ return 0.3;
352
+ }
353
+ }
354
+ // Keeps text-search scores comparable without flattening many strong matches to exactly 1.
355
+ // Сохраняет сравнимость text-search score без схлопывания сильных совпадений ровно в 1.
356
+ function boundedTextScore(score) {
357
+ return 0.5 + clampScore(score / (score + 1)) * 0.5;
358
+ }
359
+ // Restricts a score value to the public 0..1 range.
360
+ // Ограничивает значение score публичным диапазоном 0..1.
361
+ function clampScore(score) {
362
+ return Math.max(0, Math.min(1, score));
363
+ }
364
+ //# sourceMappingURL=scoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scoring.js","sourceRoot":"","sources":["../../src/merge/scoring.ts"],"names":[],"mappings":"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"}