@finbheara/archive-client 0.53.0 → 0.53.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
@@ -124,6 +124,7 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
124
124
  | `schools.registry` | `schools.list` | 260 |
125
125
  | `schools.prints`, `schools.redirects` | `schools.prints`; `schools.redirects` | 184 |
126
126
  | `schools.lineage` | `schools.links`, `schools.line`, `schools.lineage` | 184 |
127
+ | `school-graph` | the tables `schools.redirects`, `schools.lineage`, `schools.links`, `schools.line` and a dancer question's lineage read in place of the jsonl, the same answers; the jsonl, never refused, without them | none yet |
127
128
  | `schools.associations` | `schools.associations` | 215 |
128
129
 
129
130
  A spec is `pinned` (the default: the user-local pin, else the latest), `latest`, a cut number
@@ -325,6 +326,20 @@ await rel.schools.associations({ school_id: "<id>" });
325
326
  // association_type, src_type, src, candidate_school_id, candidate_rung, ... }] }
326
327
  ```
327
328
 
329
+ THE SCHOOL GRAPH'S TABLES (feature `school-graph`): a release whose `results.sqlite` carries
330
+ `school_nodes`, `school_edges` and `school_aliases` answers `redirects`, `lineage`, `links`,
331
+ `line` and a dancer question's lineage from them, and one without them from
332
+ `school-redirects.jsonl` and `school-lineage.jsonl`, as before. The answers are the same rows in
333
+ the same order: a redirect is an alias of kind `fold` or `reslug`, or a former school (a node
334
+ with `closed_into`) to the school that absorbed it, each landing on a live school in one hop; a
335
+ lineage edge is a `school_edges` row of a lineage kind (`rename`, `absorb`, `merger`, `split`,
336
+ `branch`, `related`) with no `lag_months`, given as its two ends, its `decision` the first of its
337
+ `decision_rows`. A former school's absorbed-by line (the one with `lag_months`), a `distinct`,
338
+ `disbanded`, banner or tie line, and a `shelf`, `site_fold`, path, print or `retired` alias are
339
+ none of these, as the jsonl publishes none of them: an id the tables hold only that way answers
340
+ nothing, never a guess. The tables round a `confidence` to 6 places, and the jsonl writes
341
+ `1 - posterior` unrounded, so the two can differ past the sixth place.
342
+
328
343
  `prints` is every (print, school id) pair the release's result rows attach in an event-year (the
329
344
  print trimmed), with the rows that carry it: an event's (case-blind), a year's, both or every one.
330
345
  A row attached to no school is in no pair, and a team result's school is `rel.teams.results`'.
@@ -382,6 +397,8 @@ r.unlinked; // rows printing a matched name that the release linked to no dan
382
397
  await rel.dancers.search({ surname: "Quellan" }); // or { like: "a* quellan" }, or { name }
383
398
  // at most `limit` (default 50, 0 for all);
384
399
  // `truncated` counts the rest
400
+ // a surname folds as the print's key does:
401
+ // `Karłowska` and `Karlowska` ask one key
385
402
  await rel.dancers.get(1001); // every print and school of one dancer
386
403
  ```
387
404
 
@@ -409,13 +426,14 @@ names package's Spanish reading (`createNameKinship({ spanishNames: true })`), a
409
426
  relates is a candidate at `nameLevel: "spanish"`. A release with no `spanish_names` reads every
410
427
  school the default way. A name the release already finds answers exactly as before.
411
428
 
412
- THE LINEAGE is the release's `school-lineage.jsonl`: every line joins its `id` and its `other`,
429
+ THE LINEAGE is the release's `school-lineage.jsonl` (or its `school_edges`, where it carries the
430
+ school graph's tables, the same edges): every line joins its `id` and its `other`,
413
431
  whatever its direction (`precedes`, `succeeds`) or shape (a rename, a split, a merger, an absorb,
414
432
  a relation), so a file carrying one end of an edge reads as one carrying both. The whole line
415
433
  joins: every school reached through any number of edges, in either direction (the two halves of a
416
434
  split are joined through their predecessor, the schools of a merger through their successor). An
417
435
  earlier row at a joined school alone is no match. `r.school.lineage` lists the ids joined to the
418
- asked ones. A release that publishes no lineage (feature `schools.lineage`) joins
436
+ asked ones. A release that publishes no lineage (feature `schools.lineage`, nor `school-graph`) joins
419
437
  nothing and its answer carries no `lineage`, never refused. The line is read on the same school
420
438
  graph as `rel.schools.line` (`@finbheara/domain/school-graph`): untimed, every path, and as of a
421
439
  year, every path none of whose steps is dated after it, a rename at any year (`LINE_AS_OF`).
@@ -141,7 +141,6 @@ import {
141
141
  } from "@finbheara/domain/title";
142
142
  import {
143
143
  composeNames,
144
- foldNameKey,
145
144
  nameBlockKeys,
146
145
  nameKinship as nameKinship2,
147
146
  surnameBlock
@@ -1079,6 +1078,25 @@ var FEATURES2 = [
1079
1078
  since: 184,
1080
1079
  calls: "schools.redirects"
1081
1080
  },
1081
+ {
1082
+ feature: "school-graph",
1083
+ needs: [
1084
+ ...["alias", "kind", "node_id", "school_id"].map((c) => `results:school_aliases.${c}`),
1085
+ ...["node_id", "kind", "minted_reslug_from", "minted_reslug_pass", "closed_into"].map((c) => `results:school_nodes.${c}`),
1086
+ ...[
1087
+ "from_id",
1088
+ "to_id",
1089
+ "kind",
1090
+ "valid_from",
1091
+ "provisional",
1092
+ "confidence",
1093
+ "decision_rows",
1094
+ "lag_months"
1095
+ ].map((c) => `results:school_edges.${c}`)
1096
+ ],
1097
+ since: 365,
1098
+ calls: "schools.redirects, schools.lineage, schools.links, schools.line and the `lineage` school evidence of dancers.resolve and dancers.search read the tables, the same answers as the jsonl; without them, the jsonl, never refused"
1099
+ },
1082
1100
  {
1083
1101
  feature: "schools.associations",
1084
1102
  needs: ["observed-associations.jsonl"],
@@ -1823,6 +1841,81 @@ class MajorsFinder2 {
1823
1841
  import {
1824
1842
  schoolGraph
1825
1843
  } from "@finbheara/domain/school-graph";
1844
+
1845
+ var SCHOOL_GRAPH_FEATURE = "school-graph";
1846
+ var LINEAGE_KINDS = [
1847
+ "rename",
1848
+ "absorb",
1849
+ "merger",
1850
+ "split",
1851
+ "branch",
1852
+ "related"
1853
+ ];
1854
+ async function schoolTables(rel) {
1855
+ if ((await rel.capability(SCHOOL_GRAPH_FEATURE)).state !== "full")
1856
+ return null;
1857
+ await rel.fetch("results");
1858
+ return rel.db("results");
1859
+ }
1860
+ var num = (v) => typeof v === "number" ? v : null;
1861
+ var cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
1862
+ var suffixOf = (id) => id.slice(id.lastIndexOf("-") + 1);
1863
+ function redirectsOfTables(db) {
1864
+ const rows = db.query(`SELECT a.alias AS old_id, a.school_id AS new_id, a.kind AS kind,
1865
+ n.minted_reslug_from AS reslug_from, n.minted_reslug_pass AS reslug_pass
1866
+ FROM school_aliases a LEFT JOIN school_nodes n ON n.node_id = a.node_id
1867
+ WHERE a.kind IN ('fold', 'reslug') AND a.school_id IS NOT NULL
1868
+ UNION ALL
1869
+ SELECT f.node_id, f.closed_into, NULL,
1870
+ n.minted_reslug_from, n.minted_reslug_pass
1871
+ FROM school_nodes f LEFT JOIN school_nodes n ON n.node_id = f.closed_into
1872
+ WHERE f.kind = 'school' AND f.closed_into IS NOT NULL`).all();
1873
+ const absorber = new Map;
1874
+ for (const r of rows)
1875
+ if (r.kind === null)
1876
+ absorber.set(r.old_id, r.new_id);
1877
+ const live = (id) => {
1878
+ const seen = new Set;
1879
+ let at = id;
1880
+ for (let next = absorber.get(at);next !== undefined && !seen.has(at); next = absorber.get(at)) {
1881
+ seen.add(at);
1882
+ at = next;
1883
+ }
1884
+ return at;
1885
+ };
1886
+ return rows.map((r) => {
1887
+ const named = r.reslug_from === r.old_id;
1888
+ return {
1889
+ old_id: r.old_id,
1890
+ new_id: live(r.new_id),
1891
+ kind: r.kind ?? (named || suffixOf(r.old_id) === suffixOf(r.new_id) ? "reslug" : "fold"),
1892
+ since: num(named ? r.reslug_pass : null)
1893
+ };
1894
+ }).sort((a, b) => cmp(a.old_id, b.old_id) || cmp(a.new_id, b.new_id));
1895
+ }
1896
+ function lineageOfTables(db) {
1897
+ const rows = db.query(`SELECT from_id, to_id, kind, valid_from, provisional, confidence, decision_rows
1898
+ FROM school_edges
1899
+ WHERE kind IN (${LINEAGE_KINDS.map(() => "?").join(", ")}) AND lag_months IS NULL`).all(...LINEAGE_KINDS);
1900
+ const out = [];
1901
+ for (const r of rows) {
1902
+ const rowsBehind = r.decision_rows === null ? [] : JSON.parse(r.decision_rows).map(String);
1903
+ const decision = rowsBehind[0] ?? null;
1904
+ const end = (id, direction, other) => ({
1905
+ id,
1906
+ direction,
1907
+ other,
1908
+ shape: r.kind,
1909
+ year: num(r.valid_from),
1910
+ provisional: r.provisional === 1,
1911
+ decision,
1912
+ confidence: decision === null ? null : num(r.confidence)
1913
+ });
1914
+ out.push(end(r.from_id, "precedes", r.to_id), end(r.to_id, "succeeds", r.from_id));
1915
+ }
1916
+ return out.sort((a, b) => cmp(a.id, b.id) || cmp(a.year ?? -1, b.year ?? -1) || cmp(a.direction, b.direction) || cmp(a.other, b.other) || cmp(a.shape, b.shape));
1917
+ }
1918
+
1826
1919
  var LINEAGE_FILE2 = "school-lineage.jsonl";
1827
1920
  var REDIRECTS_FILE = "school-redirects.jsonl";
1828
1921
  function linksOfLineage2(lines) {
@@ -1861,6 +1954,14 @@ function backingOf(r) {
1861
1954
  };
1862
1955
  }
1863
1956
  async function releaseSchoolGraph2(rel) {
1957
+ const tables = await schoolTables(rel);
1958
+ if (tables !== null) {
1959
+ const to = new Map(redirectsOfTables(tables).map((r) => [r.old_id, r.new_id]));
1960
+ return schoolGraph({
1961
+ links: linksOfLineage2(lineageOfTables(tables)),
1962
+ redirect: (id) => to.get(id) ?? null
1963
+ });
1964
+ }
1864
1965
  await rel.require("schools.lineage");
1865
1966
  await rel.fetch(LINEAGE_FILE2);
1866
1967
  const links = linksOfLineage2(readJsonl(rel.path(LINEAGE_FILE2)));
@@ -1880,7 +1981,7 @@ import {
1880
1981
  } from "@finbheara/domain/school";
1881
1982
 
1882
1983
  var str = (v) => typeof v === "string" && v !== "" ? v : null;
1883
- var num = (v) => typeof v === "number" ? v : null;
1984
+ var num2 = (v) => typeof v === "number" ? v : null;
1884
1985
  var uniq = (xs) => [...new Set(xs)];
1885
1986
  async function registrySchools(rel) {
1886
1987
  await rel.require("schools.registry");
@@ -1913,17 +2014,23 @@ async function schoolPrints(rel, q) {
1913
2014
  return { tag: rel.tag, asked: q, prints };
1914
2015
  }
1915
2016
  async function schoolRedirects(rel) {
2017
+ const tables = await schoolTables(rel);
2018
+ if (tables !== null)
2019
+ return { tag: rel.tag, redirects: redirectsOfTables(tables) };
1916
2020
  await rel.require("schools.redirects");
1917
2021
  await rel.fetch("school-redirects.jsonl");
1918
2022
  const redirects = readJsonl(rel.path("school-redirects.jsonl")).map((r) => ({
1919
2023
  old_id: String(r.old_id),
1920
2024
  new_id: String(r.new_id),
1921
2025
  kind: String(r.kind),
1922
- since: num(r.since)
2026
+ since: num2(r.since)
1923
2027
  }));
1924
2028
  return { tag: rel.tag, redirects };
1925
2029
  }
1926
2030
  async function schoolLineage(rel) {
2031
+ const tables = await schoolTables(rel);
2032
+ if (tables !== null)
2033
+ return { tag: rel.tag, edges: lineageOfTables(tables) };
1927
2034
  await rel.require("schools.lineage");
1928
2035
  await rel.fetch("school-lineage.jsonl");
1929
2036
  const edges = readJsonl(rel.path("school-lineage.jsonl")).map((r) => ({
@@ -1931,10 +2038,10 @@ async function schoolLineage(rel) {
1931
2038
  direction: String(r.direction),
1932
2039
  other: String(r.other),
1933
2040
  shape: String(r.shape),
1934
- year: num(r.year),
2041
+ year: num2(r.year),
1935
2042
  provisional: r.provisional === true,
1936
2043
  decision: str(r.decision),
1937
- confidence: num(r.confidence)
2044
+ confidence: num2(r.confidence)
1938
2045
  }));
1939
2046
  return { tag: rel.tag, edges };
1940
2047
  }
@@ -1948,7 +2055,7 @@ async function observedAssociations(rel, q) {
1948
2055
  continue;
1949
2056
  associations.push({
1950
2057
  at: String(r.at),
1951
- seq: num(r.seq) ?? 0,
2058
+ seq: num2(r.seq) ?? 0,
1952
2059
  date: str(r.date),
1953
2060
  person: str(r.person),
1954
2061
  person_printed: typeof r.personPrinted === "string" ? r.personPrinted : "",
@@ -2193,6 +2300,7 @@ var PACKAGE_KEY_PARTS = [
2193
2300
  `domain=${domainPkg.version}`
2194
2301
  ];
2195
2302
  var ENCODER = personEncoder({ read: (p, o) => dancerName(p, o) });
2303
+ var surnameBlockOf = (surname) => surnameBlock(dancerName(`${surname}, X`, "surname-first").surnameKey());
2196
2304
  var PERSON = { table: "person", value: "id", valueType: "INTEGER PRIMARY KEY" };
2197
2305
  var ASKED = ["surname_key", "nn4", "blk_surname"];
2198
2306
  var dancersIndex = {
@@ -2403,6 +2511,9 @@ class DancerResolver2 {
2403
2511
  }
2404
2512
  lineage() {
2405
2513
  this.lineageOf ??= (async () => {
2514
+ const tables = await schoolTables(this.rel);
2515
+ if (tables !== null)
2516
+ return schoolGraph2({ links: linksOfLineage2(lineageOfTables(tables)) });
2406
2517
  if ((await this.rel.capability("schools.lineage")).state !== "full")
2407
2518
  return null;
2408
2519
  await this.rel.fetch(LINEAGE_FILE2);
@@ -2557,7 +2668,7 @@ class DancerResolver2 {
2557
2668
  const hits = new Map;
2558
2669
  const names = createIndex2(db, ENCODER, PERSON);
2559
2670
  if (q.surname !== undefined) {
2560
- const block = surnameBlock(foldNameKey(q.surname).toUpperCase());
2671
+ const block = surnameBlockOf(q.surname);
2561
2672
  if (block !== null)
2562
2673
  for (const { value } of names.rows({ blk_surname: [block] }, ["print"]))
2563
2674
  hits.set(value, "surname");
@@ -3807,7 +3918,7 @@ async function parquetColumns(path) {
3807
3918
  }
3808
3919
 
3809
3920
  var str2 = (v) => typeof v === "string" && v !== "" ? v : null;
3810
- var num2 = (v) => typeof v === "number" ? v : null;
3921
+ var num3 = (v) => typeof v === "number" ? v : null;
3811
3922
  var strs = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
3812
3923
  var scope = (id) => id === null ? null : id >= FEIS_LOCAL_ID_FLOOR2 ? "per-release" : "stable";
3813
3924
  var TEAM_TABLES = [
@@ -3864,7 +3975,7 @@ var teamsIndex = {
3864
3975
  for (const r of t.event_years) {
3865
3976
  const k = str2(r.event_year);
3866
3977
  const event = str2(r.event);
3867
- const year = num2(r.year);
3978
+ const year = num3(r.year);
3868
3979
  if (k === null || event === null || year === null)
3869
3980
  continue;
3870
3981
  ey.set(k, { event, year });
@@ -3873,19 +3984,19 @@ var teamsIndex = {
3873
3984
  const putR = out.prepare("INSERT OR IGNORE INTO result VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
3874
3985
  let ord = 0;
3875
3986
  for (const r of t.team_results)
3876
- putR.run(str2(r.address), str2(r.slug), str2(r.event), num2(r.year), str2(r.card), str2(r.comp_no), str2(r.title), str2(r.category), num2(r.hands), str2(r.letter), str2(r.label), str2(r.name_printed), str2(r.school_printed), str2(r.school_loc), str2(r.school_id), num2(r.place), str2(r.place_printed), num2(r.tie), num2(r.competitors), JSON.stringify(strs(r.atts)), str2(r.age), str2(r.gender), JSON.stringify(strs(r.printed_status)), num2(r.competitors_printed), num2(r.recalled_only), ord++);
3987
+ putR.run(str2(r.address), str2(r.slug), str2(r.event), num3(r.year), str2(r.card), str2(r.comp_no), str2(r.title), str2(r.category), num3(r.hands), str2(r.letter), str2(r.label), str2(r.name_printed), str2(r.school_printed), str2(r.school_loc), str2(r.school_id), num3(r.place), str2(r.place_printed), num3(r.tie), num3(r.competitors), JSON.stringify(strs(r.atts)), str2(r.age), str2(r.gender), JSON.stringify(strs(r.printed_status)), num3(r.competitors_printed), num3(r.recalled_only), ord++);
3877
3988
  const putT = out.prepare("INSERT OR IGNORE INTO roster_team VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
3878
3989
  for (const r of t.roster_teams) {
3879
3990
  const e = ey.get(str2(r.event_year) ?? "");
3880
- putT.run(str2(r.team), str2(r.kind), e?.event ?? null, num2(r.year) ?? e?.year ?? null, str2(r.comp_no), str2(r.title), str2(r.team_index), num2(r.seq), str2(r.school_id), str2(r.school_print_materialized), str2(r.dance), str2(r.school_print_as_of), ord++);
3991
+ putT.run(str2(r.team), str2(r.kind), e?.event ?? null, num3(r.year) ?? e?.year ?? null, str2(r.comp_no), str2(r.title), str2(r.team_index), num3(r.seq), str2(r.school_id), str2(r.school_print_materialized), str2(r.dance), str2(r.school_print_as_of), ord++);
3881
3992
  }
3882
3993
  const putM = out.prepare("INSERT INTO roster_member VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
3883
3994
  for (const r of t.roster_members)
3884
- putM.run(str2(r.team), num2(r.seq), typeof r.name_printed === "string" ? r.name_printed : "", str2(r.name), num2(r.yob), num2(r.dancer_id), str2(r.gender), ord++);
3995
+ putM.run(str2(r.team), num3(r.seq), typeof r.name_printed === "string" ? r.name_printed : "", str2(r.name), num3(r.yob), num3(r.dancer_id), str2(r.gender), ord++);
3885
3996
  const putJ = out.prepare("INSERT INTO result_roster VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
3886
3997
  for (const r of t.team_result_rosters) {
3887
3998
  const e = ey.get(str2(r.event_year) ?? "");
3888
- putJ.run(str2(r.team), e?.event ?? null, e?.year ?? null, str2(r.comp_no), str2(r.school_id), str2(r.result_address), str2(r.join_kind), num2(r.via_split) === 1 ? 1 : 0, num2(r.roster_teams), num2(r.result_teams), str2(r.roster_index), str2(r.result_letter), ord++);
3999
+ putJ.run(str2(r.team), e?.event ?? null, e?.year ?? null, str2(r.comp_no), str2(r.school_id), str2(r.result_address), str2(r.join_kind), num3(r.via_split) === 1 ? 1 : 0, num3(r.roster_teams), num3(r.result_teams), str2(r.roster_index), str2(r.result_letter), ord++);
3889
4000
  }
3890
4001
  for (const s of TEAMS_INDEXES)
3891
4002
  out.run(s);
@@ -3906,10 +4017,10 @@ var eventsIndex = {
3906
4017
  const put = out.prepare("INSERT OR IGNORE INTO event_year VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
3907
4018
  for (const r of rows) {
3908
4019
  const event = str2(r.event);
3909
- const year = num2(r.year);
4020
+ const year = num3(r.year);
3910
4021
  if (event === null || year === null)
3911
4022
  continue;
3912
- put.run(event, year, str2(r.date_lo), str2(r.date_hi), str2(r.resolution), str2(r.source), JSON.stringify(strs(r.date_printed)), str2(r.place), JSON.stringify(strs(r.place_printed)), str2(r.published), num2(r.listed));
4023
+ put.run(event, year, str2(r.date_lo), str2(r.date_hi), str2(r.resolution), str2(r.source), JSON.stringify(strs(r.date_printed)), str2(r.place), JSON.stringify(strs(r.place_printed)), str2(r.published), num3(r.listed));
3913
4024
  }
3914
4025
  out.run("CREATE INDEX event_year_event ON event_year(event COLLATE NOCASE)");
3915
4026
  }
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  staleWarning2,
24
24
  progressMode2,
25
25
  progressRenderer2
26
- } from "./chunks/index-6np7hsst.js";
26
+ } from "./chunks/index-aj1n1q7j.js";
27
27
  import"./chunks/index-hghdy980.js";
28
28
 
29
29
  var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live] [--progress tty|plain|none]";
package/dist/index.js CHANGED
@@ -85,7 +85,7 @@ import {
85
85
  PROGRESS_MODES2,
86
86
  progressMode2,
87
87
  progressRenderer2
88
- } from "./chunks/index-6np7hsst.js";
88
+ } from "./chunks/index-aj1n1q7j.js";
89
89
  import {
90
90
  cacheRoot2,
91
91
  repoOf2
@@ -182,6 +182,7 @@ export interface DancerRecord {
182
182
  schools: DancerSchool[];
183
183
  }
184
184
  export declare const PACKAGE_KEY_PARTS: readonly string[];
185
+ export declare const surnameBlockOf: (surname: string) => string | null;
185
186
  export declare const dancersIndex: IndexBuilder;
186
187
  export declare function yearOf(asOf: string | undefined): number | null;
187
188
  export interface DancerBulkRecord {
@@ -0,0 +1,8 @@
1
+ import type { Database } from "bun:sqlite";
2
+ import type { Release } from "./release.js";
3
+ import type { LineageEdge, SchoolRedirect } from "./school-bulk.js";
4
+ export declare const SCHOOL_GRAPH_FEATURE = "school-graph";
5
+ export declare const LINEAGE_KINDS: readonly string[];
6
+ export declare function schoolTables(rel: Release): Promise<Database | null>;
7
+ export declare function redirectsOfTables(db: Database): SchoolRedirect[];
8
+ export declare function lineageOfTables(db: Database): LineageEdge[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finbheara/archive-client",
3
- "version": "0.53.0",
3
+ "version": "0.53.1",
4
4
  "description": "Open a versioned release of an Irish dance results archive: download, verify, decompress and cache it by tag, keep the cache, and resolve feises and schools against it",
5
5
  "keywords": ["irish-dance", "results", "release", "cache", "sqlite"],
6
6
  "license": "MIT",
@@ -44,8 +44,8 @@
44
44
  "prepublishOnly": "bun scripts/build.ts && bun ../../tools/checks/archive-client-tarball.ts"
45
45
  },
46
46
  "dependencies": {
47
- "@finbheara/domain": "0.59.0",
48
- "@finbheara/names": "0.30.0",
47
+ "@finbheara/domain": "0.60.1",
48
+ "@finbheara/names": "0.31.0",
49
49
  "hyparquet": "1.31.2"
50
50
  },
51
51
  "devDependencies": {