@finbheara/archive-client 0.10.0 → 0.12.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 CHANGED
@@ -281,7 +281,13 @@ words):
281
281
  followed through the redirects, a print read by `rel.schools`), and none of them is the asked
282
282
  school or a school its line had joined by that year (lineage edges dated in or before the asked
283
283
  year). A dancer with no school row, or a print no school reads, is unknown and never refuted. A
284
- dancer that ever danced for the asked school's line is never refuted by the school.
284
+ dancer that ever danced for the asked school's line is never refuted by the school. For an
285
+ adult-category question (the asked band is the adult band, read by `@finbheara/domain`:
286
+ `Adult`, `Advanced Adult`, `Adult Beginner`, `Open Adult`, `Adult Masters`), a row the
287
+ candidate danced under 18 (at every birth year of its window, in the row's latest year)
288
+ refutes nothing where the candidate is 18 or over in the asked year, however long ago the row
289
+ is: many adult dancers danced as children at another school. An and-over band (`O18`,
290
+ `18 & Over`, `18+`), `Senior`, a year of birth and a youth question are unchanged.
285
291
  - `age`: the birth window misses the asked band even with one band's dance-up (`DANCE_UP_YEARS`
286
292
  of `@finbheara/domain/age`: a dancer may enter the band one year older than the dancer's own). A
287
293
  candidate the age set aside that the dance-up holds stays open (`r.initials.heldByDanceUp`).
@@ -71,7 +71,11 @@ import { Age, DANCE_UP_YEARS, birthYearsMeet } from "@finbheara/domain/age";
71
71
  import { createIndex, indexSchema, personEncoder } from "@finbheara/domain/noun-index";
72
72
  import domainPkg from "@finbheara/domain/package.json";
73
73
  import { dancerName } from "@finbheara/domain/person";
74
- import { populationIn, populationRelation } from "@finbheara/domain/title";
74
+ import {
75
+ compTitle,
76
+ populationIn,
77
+ populationRelation
78
+ } from "@finbheara/domain/title";
75
79
  import {
76
80
  foldNameKey,
77
81
  surnameBlock
@@ -1055,8 +1059,11 @@ class DancerResolver2 {
1055
1059
  const held = [];
1056
1060
  const refuted = [];
1057
1061
  const bySchool = new Set;
1062
+ const adultBy = adultBornBy(year);
1063
+ const adultAsked = adultBy !== null && adultCategory(q.age, age?.age ?? null);
1058
1064
  const schoolFact = async (c) => {
1059
- const fact = await this.schoolRefutes(schoolsOf(db, c.dancer_id), line, year, q.school);
1065
+ const returning = adultAsked && c.birth.hi !== null && c.birth.hi <= adultBy ? c.birth.lo : null;
1066
+ const fact = await this.schoolRefutes(schoolsOf(db, c.dancer_id), line, year, q.school, returning);
1060
1067
  if (fact === null)
1061
1068
  return false;
1062
1069
  refuted.push({ dancer_id: c.dancer_id, why: "school", fact });
@@ -1195,20 +1202,30 @@ class DancerResolver2 {
1195
1202
  }
1196
1203
  return joined ? "lineage" : earlier ? "moved" : "none";
1197
1204
  }
1198
- async schoolRefutes(schools, line, year, asked) {
1205
+ async schoolRefutes(schools, line, year, asked, returning = null) {
1199
1206
  const rows = schools.filter((s) => s.year_lo === null || s.year_lo <= year);
1200
1207
  if (rows.length === 0)
1201
1208
  return null;
1202
1209
  const seen = new Set;
1210
+ const kept = [];
1211
+ let youth = 0;
1203
1212
  for (const s of rows) {
1204
1213
  const own = await this.schoolIdsOf(s);
1205
1214
  if (own.length === 0 || own.some((id) => line.has(id)))
1206
1215
  return null;
1216
+ if (returning !== null && youthRow(s, returning)) {
1217
+ youth++;
1218
+ continue;
1219
+ }
1220
+ kept.push(s);
1207
1221
  for (const id of own)
1208
1222
  seen.add(id);
1209
1223
  }
1210
- const last = latestSchool(rows, year);
1211
- return `every school row to ${year} reads ${[...seen].sort().join(", ")} (the latest ${last?.school_id ?? last?.print} in ${last?.year_hi}), none of them ${asked ?? "the asked school"} or a school its line joined by ${year}`;
1224
+ if (kept.length === 0)
1225
+ return null;
1226
+ const last = latestSchool(kept, year);
1227
+ const set = youth > 0 ? ` (${youth} youth row(s) set aside for an adult-category question)` : "";
1228
+ return `every school row to ${year} reads ${[...seen].sort().join(", ")} (the latest ${last?.school_id ?? last?.print} in ${last?.year_hi}), none of them ${asked ?? "the asked school"} or a school its line joined by ${year}${set}`;
1212
1229
  }
1213
1230
  async schoolIdsOf(s) {
1214
1231
  const key = s.school_id ?? s.print;
@@ -1247,6 +1264,24 @@ class DancerResolver2 {
1247
1264
  return done(Age.from(c.age, { year: c.year }));
1248
1265
  }
1249
1266
  }
1267
+ function adultBornBy(year) {
1268
+ const a = Age.from("adult", { year });
1269
+ return a.isAge() ? a.birthYears().to : null;
1270
+ }
1271
+ function adultCategory(asked, read) {
1272
+ if (read?.isAge() && read.isAdult())
1273
+ return true;
1274
+ if (asked === undefined || !("band" in asked))
1275
+ return false;
1276
+ const t = compTitle(asked.band).age;
1277
+ return t?.isAge() === true && t.isAdult();
1278
+ }
1279
+ function youthRow(s, bornLo) {
1280
+ if (bornLo === null || s.year_hi === null)
1281
+ return false;
1282
+ const by = adultBornBy(s.year_hi);
1283
+ return by !== null && bornLo > by;
1284
+ }
1250
1285
  function birthOf(d) {
1251
1286
  return {
1252
1287
  lo: d.birth_lo,
@@ -1352,7 +1387,7 @@ function contradictionFact(x, age, slack) {
1352
1387
  import { Age as Age2 } from "@finbheara/domain/age";
1353
1388
  import {
1354
1389
  codePopulation,
1355
- compTitle,
1390
+ compTitle as compTitle2,
1356
1391
  matchTitle,
1357
1392
  populationIn as populationIn2,
1358
1393
  secondIn,
@@ -1421,7 +1456,7 @@ function compOf(r, codes = []) {
1421
1456
  const stated = r.gender_source === "level" ? "" : populationIn2(r.gender ?? "");
1422
1457
  const pop = stated || populationIn2(r.title ?? "") || (r.platform === "ifeis" && codes.length > 0 ? codePopulation(r.code, codes) : "") || populationIn2(r.gender ?? "");
1423
1458
  const second = [r.title, r.level_printed, r.dance_printed].some((t) => t != null && secondIn(t));
1424
- const round = r.round ?? (r.title === null ? null : compTitle(r.title).round?.toString() ?? null);
1459
+ const round = r.round ?? (r.title === null ? null : compTitle2(r.title).round?.toString() ?? null);
1425
1460
  return {
1426
1461
  competition: r.competition,
1427
1462
  feis_id: r.feis_id,
@@ -1682,7 +1717,7 @@ class CompResolver2 {
1682
1717
  if (q.title === undefined || q.title.trim() === "")
1683
1718
  return answer("unique", "prior-year", hits, { from, check: "unchecked" });
1684
1719
  const m = matchTitle(q.title, [entryOf(hit)]);
1685
- const r = titleRelation(m.title, compTitle(hit.title ?? "", {}));
1720
+ const r = titleRelation(m.title, compTitle2(hit.title ?? "", {}));
1686
1721
  const check = {
1687
1722
  title: q.title,
1688
1723
  agrees: m.isSingular(),
@@ -2464,7 +2499,7 @@ import {
2464
2499
  import { join as join3 } from "path";
2465
2500
 
2466
2501
  import { Age as Age3 } from "@finbheara/domain/age";
2467
- import { compTitle as compTitle2 } from "@finbheara/domain/title";
2502
+ import { compTitle as compTitle3 } from "@finbheara/domain/title";
2468
2503
  function youngest2(answers) {
2469
2504
  const key = (a) => {
2470
2505
  const iv = Age3.from(a.age, { year: null }).interval();
@@ -2544,7 +2579,7 @@ class RegistrationResolver2 {
2544
2579
  const printed = first !== undefined ? [] : comps.flatMap((c, i) => {
2545
2580
  const code = row.codes[i];
2546
2581
  const t = row.titles?.[code];
2547
- const a = t === undefined ? null : compTitle2(t).age;
2582
+ const a = t === undefined ? null : compTitle3(t).age;
2548
2583
  return a?.isAge() === true && a.kind !== "yob" ? [{ age: a.ag1, year: c.feis.year, code }] : [];
2549
2584
  });
2550
2585
  const byTitle = youngest2(printed);
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  nameOrderOf,
5
5
  openRelease2,
6
6
  releases2
7
- } from "./chunks/index-hs72zekf.js";
7
+ } from "./chunks/index-xtv455ft.js";
8
8
  import"./chunks/index-hne1wadw.js";
9
9
  import"./chunks/index-hghdy980.js";
10
10
 
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ import {
46
46
  openCached2,
47
47
  ReleaseManager2,
48
48
  releases2
49
- } from "./chunks/index-hs72zekf.js";
49
+ } from "./chunks/index-xtv455ft.js";
50
50
  import {
51
51
  cacheRoot2,
52
52
  repoOf2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finbheara/archive-client",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
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",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@finbheara/domain": "0.50.0",
48
- "@finbheara/names": "0.24.0",
48
+ "@finbheara/names": "0.25.0",
49
49
  "hyparquet": "1.31.2"
50
50
  },
51
51
  "devDependencies": {