wikitongues-db 0.2.2 → 0.2.4

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.mjs CHANGED
@@ -217,7 +217,13 @@ var MULTILINGUAL_ALIASES = {
217
217
  sw: "swh",
218
218
  so: "som",
219
219
  zu: "zul",
220
- xh: "xho"
220
+ xh: "xho",
221
+ et: "est",
222
+ az: "aze",
223
+ lv: "lav",
224
+ ne: "nep",
225
+ ff: "ful",
226
+ mg: "mlg"
221
227
  };
222
228
  var MACROLANGUAGE_EXPANSIONS = {
223
229
  fas: ["fas", "pes", "prs"],
@@ -266,7 +272,10 @@ var MACROLANGUAGE_EXPANSIONS = {
266
272
  est: ["est", "ekk", "vro"],
267
273
  aka: ["aka", "twi", "fat"],
268
274
  nep: ["nep", "npi"],
269
- ful: ["ful", "fuf", "fuh", "fub", "fuq"]
275
+ ful: ["ful", "fuf", "fuh", "fub", "fuq"],
276
+ lav: ["lav", "lvs", "ltg"],
277
+ mon: ["mon", "khk", "mvf"],
278
+ mlg: ["mlg", "plt", "skg", "tkg"]
270
279
  };
271
280
  var LanguageResolver = class {
272
281
  isoToName = /* @__PURE__ */ new Map();
@@ -308,6 +317,14 @@ var LanguageResolver = class {
308
317
  this.aliases.set(prefix, iso);
309
318
  }
310
319
  }
320
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
321
+ if (part1 && !this.aliases.has(part1)) {
322
+ this.aliases.set(part1, iso);
323
+ }
324
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
325
+ if (macro && !this.aliases.has(macro)) {
326
+ this.aliases.set(macro, iso);
327
+ }
311
328
  const gc = lang.glottocode;
312
329
  this.glottoToIso.set(gc, iso);
313
330
  this.isoToGlotto.set(iso, gc);
@@ -373,7 +390,7 @@ var LanguageResolver = class {
373
390
  }
374
391
  }
375
392
  }
376
- if (matchedIsos.size === 0) {
393
+ if (matchedIsos.size === 0 && norm.length >= 4) {
377
394
  for (const [autoKey, isoSet] of this.autonymToIso.entries()) {
378
395
  if (autoKey.includes(norm)) {
379
396
  for (const iso of isoSet) {
@@ -9900,6 +9917,7 @@ var ReferenceHydrator = class {
9900
9917
  }
9901
9918
  const resolved = { tag: raw, primarySubtag: primary, variantSubtags: [] };
9902
9919
  if (lang.description) resolved.description = lang.description;
9920
+ if (lang.macrolanguage) resolved.macrolanguage = lang.macrolanguage;
9903
9921
  let state = 0;
9904
9922
  for (const sub of parts.slice(1)) {
9905
9923
  const lower = sub.toLowerCase();
@@ -9997,6 +10015,21 @@ var Language = class _Language {
9997
10015
  if (this.speakerClaim) out.push(this.speakerClaim);
9998
10016
  return out;
9999
10017
  }
10018
+ /**
10019
+ * Check if this language matches the given code by ISO 639-3, ISO 639-1 part1,
10020
+ * BCP-47 (exact or prefix), macrolanguage, or Glottocode.
10021
+ */
10022
+ matchesCode(code) {
10023
+ const c = code.trim().toLowerCase();
10024
+ if (!c) return false;
10025
+ if (this.iso639_3.toLowerCase() === c) return true;
10026
+ if (this.standards.iso639_3.part1?.toLowerCase() === c) return true;
10027
+ if (this.standards.bcp47.macrolanguage?.toLowerCase() === c) return true;
10028
+ const bcp = this.bcp47.toLowerCase();
10029
+ if (bcp === c || bcp.startsWith(`${c}-`)) return true;
10030
+ if (this.glottocode.toLowerCase() === c) return true;
10031
+ return false;
10032
+ }
10000
10033
  toDict() {
10001
10034
  return {
10002
10035
  standards: {
@@ -10181,6 +10214,8 @@ var Video = class _Video {
10181
10214
  const set = /* @__PURE__ */ new Set();
10182
10215
  for (const lang of this.allLanguages) {
10183
10216
  if (lang.iso639_3) set.add(lang.iso639_3);
10217
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10218
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10184
10219
  }
10185
10220
  return set;
10186
10221
  }
@@ -10191,6 +10226,9 @@ var Video = class _Video {
10191
10226
  const set = /* @__PURE__ */ new Set();
10192
10227
  for (const lang of this.allLanguages) {
10193
10228
  if (lang.bcp47) set.add(lang.bcp47);
10229
+ if (lang.iso639_3) set.add(lang.iso639_3);
10230
+ if (lang.standards.iso639_3.part1) set.add(lang.standards.iso639_3.part1);
10231
+ if (lang.standards.bcp47.macrolanguage) set.add(lang.standards.bcp47.macrolanguage);
10194
10232
  }
10195
10233
  return set;
10196
10234
  }
@@ -10228,6 +10266,8 @@ var Video = class _Video {
10228
10266
  const qNorm = normalizeText(q);
10229
10267
  for (const lang of this.allLanguages) {
10230
10268
  if (lang.iso639_3 === qLower) return true;
10269
+ if (lang.standards.iso639_3.part1?.toLowerCase() === qLower) return true;
10270
+ if (lang.standards.bcp47.macrolanguage?.toLowerCase() === qLower) return true;
10231
10271
  const bcp = lang.bcp47.toLowerCase();
10232
10272
  if (bcp === qLower || bcp.startsWith(`${qLower}-`)) return true;
10233
10273
  if (lang.glottocode === qLower) return true;
@@ -10236,7 +10276,8 @@ var Video = class _Video {
10236
10276
  const labelNorm = normalizeText(label);
10237
10277
  if (labelNorm === qNorm || ` ${labelNorm} `.includes(` ${qNorm} `)) return true;
10238
10278
  }
10239
- if (lang.autonym.toLowerCase().includes(qLower)) return true;
10279
+ const autoLower = lang.autonym.toLowerCase();
10280
+ if (autoLower === qLower || qLower.length >= 4 && autoLower.includes(qLower)) return true;
10240
10281
  }
10241
10282
  return false;
10242
10283
  }
@@ -10344,6 +10385,12 @@ var VideoCollection = class _VideoCollection {
10344
10385
  }
10345
10386
  return this._videos.some((v) => v.id === item.id);
10346
10387
  }
10388
+ /**
10389
+ * Check if any video in the collection matches the given language query.
10390
+ */
10391
+ hasLanguage(query) {
10392
+ return this._videos.some((v) => v.hasLanguage(query));
10393
+ }
10347
10394
  // -------------------------------------------------------------------------
10348
10395
  // Aggregation & Summary Properties
10349
10396
  // -------------------------------------------------------------------------
@@ -10649,7 +10696,7 @@ var DatasetIndex = class {
10649
10696
  const list = map.get(key);
10650
10697
  if (!list) {
10651
10698
  map.set(key, [video]);
10652
- } else {
10699
+ } else if (!list.some((v) => v.id === video.id)) {
10653
10700
  list.push(video);
10654
10701
  }
10655
10702
  }
@@ -10662,12 +10709,30 @@ var DatasetIndex = class {
10662
10709
  if (plIso) {
10663
10710
  this.appendToMap(this.byIsoPrimary, plIso, video);
10664
10711
  this.appendToMap(this.byIso, plIso, video);
10712
+ const part1 = video.primaryLanguage.standards.iso639_3.part1?.toLowerCase();
10713
+ if (part1 && part1 !== plIso) {
10714
+ this.appendToMap(this.byIsoPrimary, part1, video);
10715
+ this.appendToMap(this.byIso, part1, video);
10716
+ }
10717
+ const macro = video.primaryLanguage.standards.bcp47.macrolanguage?.toLowerCase();
10718
+ if (macro && macro !== plIso && macro !== part1) {
10719
+ this.appendToMap(this.byIsoPrimary, macro, video);
10720
+ this.appendToMap(this.byIso, macro, video);
10721
+ }
10665
10722
  }
10666
10723
  for (const addLang of video.additionalLanguages) {
10667
10724
  const aIso = addLang.iso639_3;
10668
- if (aIso && aIso !== plIso) {
10725
+ if (aIso) {
10669
10726
  this.appendToMap(this.byIso, aIso, video);
10670
10727
  }
10728
+ const part1 = addLang.standards.iso639_3.part1?.toLowerCase();
10729
+ if (part1 && part1 !== aIso) {
10730
+ this.appendToMap(this.byIso, part1, video);
10731
+ }
10732
+ const macro = addLang.standards.bcp47.macrolanguage?.toLowerCase();
10733
+ if (macro && macro !== aIso && macro !== part1) {
10734
+ this.appendToMap(this.byIso, macro, video);
10735
+ }
10671
10736
  }
10672
10737
  for (const lang of video.allLanguages) {
10673
10738
  const bcp = lang.bcp47.toLowerCase().trim();
@@ -10678,6 +10743,18 @@ var DatasetIndex = class {
10678
10743
  this.appendToMap(this.byBcp47, prefix, video);
10679
10744
  }
10680
10745
  }
10746
+ const iso = lang.iso639_3?.toLowerCase().trim();
10747
+ if (iso && iso !== bcp) {
10748
+ this.appendToMap(this.byBcp47, iso, video);
10749
+ }
10750
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase().trim();
10751
+ if (part1 && part1 !== bcp && part1 !== iso) {
10752
+ this.appendToMap(this.byBcp47, part1, video);
10753
+ }
10754
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase().trim();
10755
+ if (macro && macro !== bcp && macro !== iso && macro !== part1) {
10756
+ this.appendToMap(this.byBcp47, macro, video);
10757
+ }
10681
10758
  }
10682
10759
  for (const lang of video.allLanguages) {
10683
10760
  this.appendToMap(this.byGlottocode, lang.glottocode, video);
@@ -10920,6 +10997,14 @@ var QueryBuilder = class _QueryBuilder {
10920
10997
  if (matchedIsos.has(lIso) || lIso === rawLower) {
10921
10998
  return true;
10922
10999
  }
11000
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
11001
+ if (part1 && (matchedIsos.has(part1) || part1 === rawLower)) {
11002
+ return true;
11003
+ }
11004
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
11005
+ if (macro && (matchedIsos.has(macro) || macro === rawLower)) {
11006
+ return true;
11007
+ }
10923
11008
  const lBcp = lang.bcp47.toLowerCase();
10924
11009
  if (lBcp === rawLower || lBcp.startsWith(`${rawLower}-`)) {
10925
11010
  return true;
@@ -10932,7 +11017,9 @@ var QueryBuilder = class _QueryBuilder {
10932
11017
  const lNorm = normalizeText(label);
10933
11018
  if (lNorm === norm || pattern && pattern.test(lNorm)) return true;
10934
11019
  }
10935
- if (lang.autonym.toLowerCase().includes(rawLower)) return true;
11020
+ const autoLower = lang.autonym.toLowerCase();
11021
+ if (autoLower === rawLower) return true;
11022
+ if (rawLower.length >= 4 && autoLower.includes(rawLower)) return true;
10936
11023
  }
10937
11024
  return false;
10938
11025
  };
@@ -10955,13 +11042,17 @@ var QueryBuilder = class _QueryBuilder {
10955
11042
  iso(code, includeAdditional = true) {
10956
11043
  const codeClean = code.trim().toLowerCase();
10957
11044
  const predicate = (v) => {
10958
- if (v.primaryLanguage.iso639_3.toLowerCase() === codeClean) {
11045
+ const matchIso = (l) => {
11046
+ if (l.iso639_3.toLowerCase() === codeClean) return true;
11047
+ if (l.standards.iso639_3.part1?.toLowerCase() === codeClean) return true;
11048
+ if (l.standards.bcp47.macrolanguage?.toLowerCase() === codeClean) return true;
11049
+ return false;
11050
+ };
11051
+ if (matchIso(v.primaryLanguage)) {
10959
11052
  return true;
10960
11053
  }
10961
11054
  if (includeAdditional) {
10962
- return v.additionalLanguages.some(
10963
- (al) => al.iso639_3.toLowerCase() === codeClean
10964
- );
11055
+ return v.additionalLanguages.some(matchIso);
10965
11056
  }
10966
11057
  return false;
10967
11058
  };
@@ -10973,10 +11064,13 @@ var QueryBuilder = class _QueryBuilder {
10973
11064
  const predicate = (v) => {
10974
11065
  for (const lang of v.allLanguages) {
10975
11066
  const lTag = lang.bcp47.toLowerCase();
11067
+ const lIso = lang.iso639_3.toLowerCase();
11068
+ const part1 = lang.standards.iso639_3.part1?.toLowerCase();
11069
+ const macro = lang.standards.bcp47.macrolanguage?.toLowerCase();
10976
11070
  if (exact) {
10977
- if (lTag === tagClean) return true;
11071
+ if (lTag === tagClean || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10978
11072
  } else {
10979
- if (lTag === tagClean || lTag.startsWith(`${tagClean}-`)) return true;
11073
+ if (lTag === tagClean || lTag.startsWith(`${tagClean}-`) || lIso === tagClean || part1 === tagClean || macro === tagClean) return true;
10980
11074
  }
10981
11075
  }
10982
11076
  return false;
@@ -66507,6 +66601,16 @@ var WikitonguesDB = class _WikitonguesDB {
66507
66601
  findByLanguage(languageQuery, includeAdditional = true) {
66508
66602
  return this.query().language(languageQuery, includeAdditional).all();
66509
66603
  }
66604
+ /**
66605
+ * Check if the database contains any video matching the language query
66606
+ * (by ISO 639-3, ISO 639-1, BCP 47, macrolanguage, or name).
66607
+ */
66608
+ hasLanguage(query) {
66609
+ const qClean = query.trim().toLowerCase();
66610
+ if (this.index.byIso.has(qClean)) return true;
66611
+ if (this.index.byBcp47.has(qClean)) return true;
66612
+ return this.findByLanguage(query).length > 0;
66613
+ }
66510
66614
  /**
66511
66615
  * Shortcut method to filter videos by common criteria.
66512
66616
  */