@finbheara/archive-client 0.33.0 → 0.34.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
@@ -100,6 +100,7 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
100
100
  | `upcoming.feises` | `upcoming.feises`, and the `next` of `feises.series` (null with the reason without it) | 285 |
101
101
  | `upcoming.fields`, `upcoming.entrants` | `upcoming.fields`, `upcoming.entrants` (285 and 290 carry the tables empty) | 291 |
102
102
  | `upcoming.fields.instance` | the `feis_instance_id` `upcoming.fields` carries; absent, never refused, without it | 320 |
103
+ | `calendar` | `calendar.get`, `calendar.list` | 320 |
103
104
  | `tabs`, `panels` | `tabs.query`, `tabs.stream`; `panels.query` | 184 |
104
105
  | `feis-panels` | `feisPanels.query` | 260 |
105
106
  | `staff.adjudicators` | `staff.adjudicators` | 230 |
@@ -752,6 +753,33 @@ the corpus `entrants/` part: its rows are schools' counts (`level_counts`), with
752
753
  host with a registrant list publishes no such field. An unknown field or version answers no rows and says
753
754
  why. On a release without the tables each call refuses by name.
754
755
 
756
+ ## The feis calendar
757
+
758
+ ```ts
759
+ const g = await rel.calendar.get("plf.2026"); // an instance, an event-year (`<event><year>`), a retired
760
+ // id, a capture (`fweb:PLF26`) or an occurrence id
761
+ g.via; // "instance" | "formerly" | "feis_id" | "occurrence_id" | null
762
+ g.entries; // [{ feis_instance_id, feis_brand_id, tier, name_printed, date_lo, date_hi, date_source,
763
+ // occurrence_ids, feis_ids, stages: { announced, syllabus, entrants, run, results },
764
+ // terminal, carried, formerly }]
765
+ const l = await rel.calendar.list({ stage: "entrants", state: "observed", from: "2026-11-01" });
766
+ // brand, tier, from, to, stage, state, terminal ("none": still ahead)
767
+ ```
768
+
769
+ ONE ROW PER FEIS INSTANCE, on the id its results carry: a feis-series instance (`<brand>.<year>`),
770
+ announced, held or both, or a rated majors event-year. Each stage (`announced`, `syllabus`,
771
+ `entrants`, `run`, `results`) is `{ state, date, cite }`: `observed` (a capture showed it, `date`
772
+ the day it was first observed, null where no capture dates it, `cite` the capture), `pending` (the
773
+ release holds captures of that kind for the instance's platform, so a later one may show it) or
774
+ `not-captured` (it holds none). A day first observed never moves later from one release to the
775
+ next: a stage an earlier release observed keeps its day, named in `carried` (`["row"]` for a row
776
+ the cut no longer names, kept whole), and a retired id is listed in `formerly`. `terminal` is
777
+ `results`, `withdrawn` (every field withdrawn), `passed-no-results` (its first day is before the
778
+ cut's day), or null for a feis still ahead. Stage dates follow capture timing, not the feis's own
779
+ order: only results after the run is a belief. `get` tries the instance id, then `formerly`, then
780
+ a capture, then an occurrence id, and says which met (`via`). On a release without the table each
781
+ call refuses by name.
782
+
755
783
  ## Teachers and adjudicators
756
784
 
757
785
  ```ts
@@ -927,6 +955,9 @@ is passed to the dancer resolver as asked (`rel.dancers`, above).
927
955
  idq upcoming [--release <spec>] [--state <s,...>] [--feis <id>] [--from <date>] [--to <date>]
928
956
  idq upcoming --entrants <field_id> [--version <capture id>]
929
957
  idq upcoming --feises [--state upcoming|no-results] [--brand <series>] [--from <date>] [--to <date>]
958
+ idq calendar [--release <spec>] <instance|feis id|occurrence id>
959
+ idq calendar [--brand <series>] [--tier <t>] [--from <date>] [--to <date>] [--stage <s>] [--state <s>]
960
+ [--terminal results|withdrawn|passed-no-results|none]
930
961
  idq teacher [--release <spec>] <name|TD number>
931
962
  idq adjudicator [--release <spec>] <name|TD number>
932
963
  idq comp [--release <spec>] <feis> <code> [--year y] [--title t]
@@ -688,6 +688,40 @@ var FEATURES2 = [
688
688
  since: 320,
689
689
  calls: "upcoming.fields' `feis_instance_id` (absent, never null, without it)"
690
690
  },
691
+ {
692
+ feature: "calendar",
693
+ needs: [
694
+ "feis_instance_id",
695
+ "feis_brand_id",
696
+ "tier",
697
+ "name_printed",
698
+ "date_lo",
699
+ "date_hi",
700
+ "date_source",
701
+ "occurrence_ids",
702
+ "feis_ids",
703
+ "announced_state",
704
+ "announced_date",
705
+ "announced_cite",
706
+ "syllabus_state",
707
+ "syllabus_date",
708
+ "syllabus_cite",
709
+ "entrants_state",
710
+ "entrants_date",
711
+ "entrants_cite",
712
+ "run_state",
713
+ "run_date",
714
+ "run_cite",
715
+ "results_state",
716
+ "results_date",
717
+ "results_cite",
718
+ "terminal",
719
+ "carried",
720
+ "formerly"
721
+ ].map((c) => `results:feis_calendar.${c}`),
722
+ since: 320,
723
+ calls: "calendar.get, calendar.list"
724
+ },
691
725
  {
692
726
  feature: "upcoming.entrants",
693
727
  needs: [
@@ -3825,6 +3859,118 @@ import {
3825
3859
  } from "fs";
3826
3860
  import { join as join3 } from "path";
3827
3861
 
3862
+ var CALENDAR_STAGES2 = [
3863
+ "announced",
3864
+ "syllabus",
3865
+ "entrants",
3866
+ "run",
3867
+ "results"
3868
+ ];
3869
+ var CALENDAR_STAGE_STATES2 = [
3870
+ "observed",
3871
+ "pending",
3872
+ "not-captured"
3873
+ ];
3874
+ var CALENDAR_TERMINALS2 = [
3875
+ "results",
3876
+ "withdrawn",
3877
+ "passed-no-results"
3878
+ ];
3879
+ var json = (s, empty) => typeof s === "string" && s !== "" ? JSON.parse(s) : empty;
3880
+ function entryOf2(r) {
3881
+ const stages = Object.fromEntries(CALENDAR_STAGES2.map((s) => [
3882
+ s,
3883
+ {
3884
+ state: r[`${s}_state`],
3885
+ date: r[`${s}_date`] ?? null,
3886
+ cite: r[`${s}_cite`] ?? null
3887
+ }
3888
+ ]));
3889
+ return {
3890
+ feis_instance_id: r.feis_instance_id,
3891
+ feis_brand_id: r.feis_brand_id ?? null,
3892
+ tier: r.tier,
3893
+ name_printed: r.name_printed ?? null,
3894
+ date_lo: r.date_lo ?? null,
3895
+ date_hi: r.date_hi ?? null,
3896
+ date_source: r.date_source ?? null,
3897
+ occurrence_ids: json(r.occurrence_ids, []),
3898
+ feis_ids: json(r.feis_ids, []),
3899
+ stages,
3900
+ terminal: r.terminal ?? null,
3901
+ carried: json(r.carried, []),
3902
+ formerly: json(r.formerly, [])
3903
+ };
3904
+ }
3905
+ var holds = (col) => `EXISTS (SELECT 1 FROM json_each(${col}) WHERE value = ?)`;
3906
+
3907
+ class CalendarFinder2 {
3908
+ rel;
3909
+ constructor(rel) {
3910
+ this.rel = rel;
3911
+ }
3912
+ async db() {
3913
+ await this.rel.fetch("results");
3914
+ await this.rel.require("calendar");
3915
+ return this.rel.db("results");
3916
+ }
3917
+ async get(id) {
3918
+ const db = await this.db();
3919
+ const ways = [
3920
+ ["instance", "feis_instance_id = ?"],
3921
+ ["formerly", holds("formerly")],
3922
+ ["feis_id", holds("feis_ids")],
3923
+ ["occurrence_id", holds("occurrence_ids")]
3924
+ ];
3925
+ for (const [via, where] of ways) {
3926
+ const rows = db.query(`SELECT * FROM feis_calendar WHERE ${where} ORDER BY feis_instance_id`).all(id);
3927
+ if (rows.length > 0)
3928
+ return { tag: this.rel.tag, asked: id, via, entries: rows.map(entryOf2) };
3929
+ }
3930
+ return {
3931
+ tag: this.rel.tag,
3932
+ asked: id,
3933
+ via: null,
3934
+ entries: [],
3935
+ why: `the calendar names no instance, capture or occurrence "${id}"`
3936
+ };
3937
+ }
3938
+ async list(q = {}) {
3939
+ if (q.stage !== undefined && !CALENDAR_STAGES2.includes(q.stage))
3940
+ throw new Error(`calendar.list: no stage "${q.stage}" (the stages are ${CALENDAR_STAGES2.join(", ")})`);
3941
+ if (q.state !== undefined && !CALENDAR_STAGE_STATES2.includes(q.state))
3942
+ throw new Error(`calendar.list: no state "${q.state}" (the states are ${CALENDAR_STAGE_STATES2.join(", ")})`);
3943
+ if (q.terminal !== undefined && q.terminal !== "none" && !CALENDAR_TERMINALS2.includes(q.terminal))
3944
+ throw new Error(`calendar.list: no terminal "${q.terminal}" (the terminals are ${CALENDAR_TERMINALS2.join(", ")}, none)`);
3945
+ const db = await this.db();
3946
+ const where = [];
3947
+ const args = [];
3948
+ const add = (sql, ...v) => {
3949
+ where.push(sql);
3950
+ args.push(...v);
3951
+ };
3952
+ if (q.brand !== undefined)
3953
+ add("feis_brand_id = ?", q.brand);
3954
+ if (q.tier !== undefined)
3955
+ add("tier = ?", q.tier);
3956
+ if (q.from !== undefined)
3957
+ add("date_lo >= ?", q.from);
3958
+ if (q.to !== undefined)
3959
+ add("date_lo <= ?", q.to);
3960
+ if (q.stage !== undefined)
3961
+ add(`${q.stage}_state = ?`, q.state ?? "observed");
3962
+ else if (q.state !== undefined)
3963
+ add(`(${CALENDAR_STAGES2.map((s) => `${s}_state = ?`).join(" OR ")})`, ...CALENDAR_STAGES2.map(() => q.state));
3964
+ if (q.terminal === "none")
3965
+ add("terminal IS NULL");
3966
+ else if (q.terminal !== undefined)
3967
+ add("terminal = ?", q.terminal);
3968
+ const sql = `SELECT * FROM feis_calendar${where.length > 0 ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY date_lo IS NULL, date_lo, feis_instance_id`;
3969
+ const rows = db.query(sql).all(...args);
3970
+ return { tag: this.rel.tag, entries: rows.map(entryOf2) };
3971
+ }
3972
+ }
3973
+
3828
3974
  import { Age as Age3 } from "@finbheara/domain/age";
3829
3975
  import { compTitle as compTitle3 } from "@finbheara/domain/title";
3830
3976
  function youngest2(answers) {
@@ -4125,7 +4271,7 @@ var FIELD_STATES2 = [
4125
4271
  "withdrawn"
4126
4272
  ];
4127
4273
  var DEPARTURE_REASONS2 = FIELD_STATES2.filter((s) => s !== "pending");
4128
- var json = (s, empty) => typeof s === "string" && s !== "" ? JSON.parse(s) : empty;
4274
+ var json2 = (s, empty) => typeof s === "string" && s !== "" ? JSON.parse(s) : empty;
4129
4275
  function fieldOf(r) {
4130
4276
  const countOnly = r.count_only === 1;
4131
4277
  return {
@@ -4154,19 +4300,19 @@ function fieldOf(r) {
4154
4300
  why: r.comp_why ?? null
4155
4301
  },
4156
4302
  state: r.state,
4157
- flags: json(r.flags, []),
4158
- results_competitions: json(r.results_competitions, []),
4159
- results_feis_ids: json(r.results_feis_ids, []),
4160
- held_out: json(r.held_out, []),
4303
+ flags: json2(r.flags, []),
4304
+ results_competitions: json2(r.results_competitions, []),
4305
+ results_feis_ids: json2(r.results_feis_ids, []),
4306
+ held_out: json2(r.held_out, []),
4161
4307
  merged_into: r.merged_into ?? null,
4162
4308
  version: r.version,
4163
- versions: json(r.versions, []),
4309
+ versions: json2(r.versions, []),
4164
4310
  captured_date: r.captured_date,
4165
4311
  sha256: r.sha256,
4166
- limits: json(r.limits, []),
4312
+ limits: json2(r.limits, []),
4167
4313
  entrants: r.entrants,
4168
4314
  stated_rows: r.stated_rows ?? null,
4169
- printed_total: json(r.printed_total, null)
4315
+ printed_total: json2(r.printed_total, null)
4170
4316
  };
4171
4317
  }
4172
4318
  function entrantOf(r) {
@@ -4183,30 +4329,30 @@ function entrantOf(r) {
4183
4329
  school_printed: r.school_printed ?? null,
4184
4330
  school_id: r.school_id ?? null,
4185
4331
  school_rung: r.school_rung,
4186
- school_candidates: json(r.school_candidates, []),
4187
- competitions: json(r.competitions, []),
4188
- field_ids: json(r.field_ids, []),
4189
- level_counts: json(r.level_counts, null),
4332
+ school_candidates: json2(r.school_candidates, []),
4333
+ competitions: json2(r.competitions, []),
4334
+ field_ids: json2(r.field_ids, []),
4335
+ level_counts: json2(r.level_counts, null),
4190
4336
  yob: r.yob ?? null,
4191
- asked: json(r.asked, null),
4337
+ asked: json2(r.asked, null),
4192
4338
  arm: r.arm ?? null,
4193
- candidates: json(r.candidates, []),
4194
- flags: json(r.flags, [])
4339
+ candidates: json2(r.candidates, []),
4340
+ flags: json2(r.flags, [])
4195
4341
  };
4196
4342
  }
4197
4343
  function feisOf(r) {
4198
4344
  return {
4199
4345
  occurrence_id: r.occurrence_id,
4200
- occurrence_ids: json(r.occurrence_ids, []),
4346
+ occurrence_ids: json2(r.occurrence_ids, []),
4201
4347
  name_printed: r.name_printed,
4202
4348
  date_lo: r.date_lo,
4203
4349
  date_hi: r.date_hi ?? null,
4204
4350
  year: r.year,
4205
- hosts: json(r.hosts, []),
4351
+ hosts: json2(r.hosts, []),
4206
4352
  feis_brand_id: r.feis_brand_id ?? null,
4207
4353
  feis_instance_id: r.feis_instance_id ?? null,
4208
4354
  series_basis: r.series_basis,
4209
- brand_candidates: json(r.brand_candidates, []),
4355
+ brand_candidates: json2(r.brand_candidates, []),
4210
4356
  captured_id: r.captured_id,
4211
4357
  state: r.results_state
4212
4358
  };
@@ -4396,6 +4542,7 @@ class Release2 {
4396
4542
  teams;
4397
4543
  events;
4398
4544
  upcoming;
4545
+ calendar;
4399
4546
  tabs;
4400
4547
  panels;
4401
4548
  feisPanels;
@@ -4422,6 +4569,7 @@ class Release2 {
4422
4569
  this.teams = new TeamFinder2(this);
4423
4570
  this.events = new EventFinder2(this);
4424
4571
  this.upcoming = new UpcomingFinder2(this);
4572
+ this.calendar = new CalendarFinder2(this);
4425
4573
  this.tabs = new TabFinder2(this);
4426
4574
  this.panels = new PanelFinder2(this);
4427
4575
  this.feisPanels = new FeisPanelFinder2(this);
@@ -5145,4 +5293,4 @@ function staleWarning2(answered, latest, floor, tags = [], command = "idq") {
5145
5293
  return `answered from ${answered}. ${floorTag ?? `cut ${floor.cut}`} is required${why}: run \`${command} use ${floor.cut}\` to get it`;
5146
5294
  }
5147
5295
 
5148
- export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, TabFinder2, PanelFinder2, FeisPanelFinder2, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, rosterOf2, NO_CALENDAR2, NO_UPCOMING2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, FIELD_STATES2, DEPARTURE_REASONS2, UpcomingFinder2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
5296
+ export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, TabFinder2, PanelFinder2, FeisPanelFinder2, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, rosterOf2, NO_CALENDAR2, NO_UPCOMING2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, CALENDAR_STAGES2, CALENDAR_STAGE_STATES2, CALENDAR_TERMINALS2, CalendarFinder2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, FIELD_STATES2, DEPARTURE_REASONS2, UpcomingFinder2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
package/dist/cli.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  latestCheck2,
22
22
  within,
23
23
  staleWarning2
24
- } from "./chunks/index-g8ab43kz.js";
24
+ } from "./chunks/index-cwhyrcyx.js";
25
25
  import"./chunks/index-hghdy980.js";
26
26
 
27
27
  var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live]";
@@ -392,6 +392,21 @@ var VERBS = [
392
392
  " held-out competitions)"
393
393
  ]
394
394
  },
395
+ {
396
+ verb: "calendar",
397
+ value: ["--release", "--brand", "--tier", "--from", "--to", "--stage", "--state", "--terminal"],
398
+ bool: [],
399
+ usage: [
400
+ " calendar [--release <spec>] <instance|feis id|occurrence id>",
401
+ " one feis instance's stages: announced, syllabus, entrants,",
402
+ " run and results, each observed, pending or not-captured,",
403
+ " the day first observed and the capture that observed it",
404
+ " calendar [--brand <series>] [--tier T1..T4] [--from <date>] [--to <date>]",
405
+ " [--stage announced|syllabus|entrants|run|results] [--state observed|pending|not-captured]",
406
+ " [--terminal results|withdrawn|passed-no-results|none]",
407
+ " the instances a query names, by first day"
408
+ ]
409
+ },
395
410
  {
396
411
  verb: "teacher",
397
412
  value: ["--release"],
@@ -799,6 +814,7 @@ var ANSWERING = new Set([
799
814
  "teams",
800
815
  "events",
801
816
  "upcoming",
817
+ "calendar",
802
818
  "teacher",
803
819
  "adjudicator",
804
820
  "comp",
@@ -1533,6 +1549,42 @@ async function main(argv, io = {}) {
1533
1549
  rel.close();
1534
1550
  }
1535
1551
  }
1552
+ case "calendar": {
1553
+ const rel = await open(spec, { ...opts, assets: [] });
1554
+ try {
1555
+ const line = (e) => ` ${e.date_lo ?? "?"} ${e.feis_instance_id} ${e.tier} ${["announced", "syllabus", "entrants", "run", "results"].map((s) => `${s}:${e.stages[s].state === "observed" ? e.stages[s].date ?? "seen" : e.stages[s].state}`).join(" ")} [${e.terminal ?? "ahead"}]${e.name_printed !== null ? ` "${e.name_printed}"` : ""}`;
1556
+ if (rest.length > 0) {
1557
+ const a = await rel.calendar.get(rest.join(" "));
1558
+ out(a, () => {
1559
+ for (const e of a.entries) {
1560
+ say(line(e));
1561
+ for (const s of ["announced", "syllabus", "entrants", "run", "results"])
1562
+ say(` ${s} ${e.stages[s].state} ${e.stages[s].date ?? "-"} ${e.stages[s].cite ?? "-"}${e.carried.includes(s) ? " (carried)" : ""}`);
1563
+ }
1564
+ say(`${a.entries.length} instance(s) for "${a.asked}"${a.via !== null ? ` by ${a.via}` : ""}${a.why !== undefined ? ` (${a.why})` : ""} in ${a.tag}`);
1565
+ });
1566
+ return a.entries.length === 0 ? 1 : 0;
1567
+ }
1568
+ const v = (f) => p.flags.get(f);
1569
+ const a = await rel.calendar.list({
1570
+ ...v("--brand") !== undefined ? { brand: v("--brand") } : {},
1571
+ ...v("--tier") !== undefined ? { tier: v("--tier") } : {},
1572
+ ...v("--from") !== undefined ? { from: v("--from") } : {},
1573
+ ...v("--to") !== undefined ? { to: v("--to") } : {},
1574
+ ...v("--stage") !== undefined ? { stage: v("--stage") } : {},
1575
+ ...v("--state") !== undefined ? { state: v("--state") } : {},
1576
+ ...v("--terminal") !== undefined ? { terminal: v("--terminal") } : {}
1577
+ });
1578
+ out(a, () => {
1579
+ for (const e of a.entries)
1580
+ say(line(e));
1581
+ say(`${a.entries.length} instance(s) in ${a.tag}`);
1582
+ });
1583
+ return a.entries.length === 0 ? 1 : 0;
1584
+ } finally {
1585
+ rel.close();
1586
+ }
1587
+ }
1536
1588
  case "teacher":
1537
1589
  case "adjudicator": {
1538
1590
  if (rest.length === 0) {
package/dist/index.js CHANGED
@@ -44,6 +44,10 @@ import {
44
44
  ensureIndex2,
45
45
  listIndexes2,
46
46
  readPin2,
47
+ CALENDAR_STAGES2,
48
+ CALENDAR_STAGE_STATES2,
49
+ CALENDAR_TERMINALS2,
50
+ CalendarFinder2,
47
51
  youngest2,
48
52
  dancerResolverOf2,
49
53
  RegistrationResolver2,
@@ -76,7 +80,7 @@ import {
76
80
  readLatestCheck2,
77
81
  latestCheck2,
78
82
  staleWarning2
79
- } from "./chunks/index-g8ab43kz.js";
83
+ } from "./chunks/index-cwhyrcyx.js";
80
84
  import {
81
85
  cacheRoot2,
82
86
  repoOf2
@@ -93,6 +97,10 @@ import {
93
97
  export {
94
98
  ADVANCEMENT_DANCES2 as ADVANCEMENT_DANCES,
95
99
  ARCHIVE_TAG2 as ARCHIVE_TAG,
100
+ CALENDAR_STAGES2 as CALENDAR_STAGES,
101
+ CALENDAR_STAGE_STATES2 as CALENDAR_STAGE_STATES,
102
+ CALENDAR_TERMINALS2 as CALENDAR_TERMINALS,
103
+ CalendarFinder2 as CalendarFinder,
96
104
  CompResolver2 as CompResolver,
97
105
  DATABASES2 as DATABASES,
98
106
  DEFAULT_KEEP2 as DEFAULT_KEEP,
@@ -0,0 +1,54 @@
1
+ import type { Release } from "./release.js";
2
+ export type CalendarStage = "announced" | "syllabus" | "entrants" | "run" | "results";
3
+ export declare const CALENDAR_STAGES: readonly CalendarStage[];
4
+ export type CalendarStageState = "observed" | "pending" | "not-captured";
5
+ export declare const CALENDAR_STAGE_STATES: readonly CalendarStageState[];
6
+ export type CalendarTerminal = "results" | "withdrawn" | "passed-no-results";
7
+ export declare const CALENDAR_TERMINALS: readonly CalendarTerminal[];
8
+ export interface CalendarStageValue {
9
+ state: CalendarStageState;
10
+ date: string | null;
11
+ cite: string | null;
12
+ }
13
+ export interface CalendarEntry {
14
+ feis_instance_id: string;
15
+ feis_brand_id: string | null;
16
+ tier: string;
17
+ name_printed: string | null;
18
+ date_lo: string | null;
19
+ date_hi: string | null;
20
+ date_source: "run" | "announced" | null;
21
+ occurrence_ids: string[];
22
+ feis_ids: string[];
23
+ stages: Record<CalendarStage, CalendarStageValue>;
24
+ terminal: CalendarTerminal | null;
25
+ carried: string[];
26
+ formerly: string[];
27
+ }
28
+ export interface CalendarQuery {
29
+ brand?: string;
30
+ tier?: string;
31
+ from?: string;
32
+ to?: string;
33
+ stage?: CalendarStage;
34
+ state?: CalendarStageState;
35
+ terminal?: CalendarTerminal | "none";
36
+ }
37
+ export interface CalendarAnswer {
38
+ tag: string;
39
+ entries: CalendarEntry[];
40
+ }
41
+ export interface CalendarGetAnswer {
42
+ tag: string;
43
+ asked: string;
44
+ via: "instance" | "formerly" | "feis_id" | "occurrence_id" | null;
45
+ entries: CalendarEntry[];
46
+ why?: string;
47
+ }
48
+ export declare class CalendarFinder {
49
+ private readonly rel;
50
+ constructor(rel: Release);
51
+ private db;
52
+ get(id: string): Promise<CalendarGetAnswer>;
53
+ list(q?: CalendarQuery): Promise<CalendarAnswer>;
54
+ }
@@ -26,4 +26,5 @@ export { type EntryRow, type StreamCompetition, type StreamQuery, type StreamRow
26
26
  export { type FeisPanelSeat, FeisPanelFinder, PanelFinder, type PanelSeat, type RegisterRow, type TabAnswer, TabFinder, type TabQuery, type TabRow, type TabStreamQuery, } from "./tabs.js";
27
27
  export { EventFinder, type EventYear, type EventYearQuery, type ResultRoster, type RosterMember, type RosterTeam, TeamFinder, type TeamResult, } from "./teams.js";
28
28
  export { type EntrantCandidate, FIELD_STATES, type FieldComp, DEPARTURE_REASONS, type DepartureReason, type FieldState, type HeldOut, type UpcomingDeparture, type UpcomingDepartureAnswer, type UpcomingDepartureQuery, type UpcomingEntrant, type UpcomingEntrantAnswer, type UpcomingEntrantQuery, type UpcomingFeis, type UpcomingFeisAnswer, type UpcomingFeisQuery, type UpcomingFeisState, type UpcomingField, type UpcomingFieldAnswer, type UpcomingFieldQuery, UpcomingFinder, type UpcomingHost, } from "./upcoming.js";
29
+ export { CALENDAR_STAGES, CALENDAR_STAGE_STATES, CALENDAR_TERMINALS, type CalendarAnswer, type CalendarEntry, CalendarFinder, type CalendarGetAnswer, type CalendarQuery, type CalendarStage, type CalendarStageState, type CalendarStageValue, type CalendarTerminal, } from "./calendar.js";
29
30
  export { ARCHIVE_TAG, type ArchiveTag, type ReleaseSpec, compareTagsNewestFirst, cutOf, parseArchiveTag, parseReleaseSpec, pickTag, renderArchiveTag, } from "./tag.js";
@@ -1,5 +1,6 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import { type AssetPlan, type LandedFile, type Receipt, type ReleaseManifest } from "./assets.js";
3
+ import { CalendarFinder } from "./calendar.js";
3
4
  import { CompResolver } from "./comps.js";
4
5
  import { type ClientOptions } from "./config.js";
5
6
  import { DancerResolver } from "./dancers.js";
@@ -47,6 +48,7 @@ export declare class Release {
47
48
  readonly teams: TeamFinder;
48
49
  readonly events: EventFinder;
49
50
  readonly upcoming: UpcomingFinder;
51
+ readonly calendar: CalendarFinder;
50
52
  readonly tabs: TabFinder;
51
53
  readonly panels: PanelFinder;
52
54
  readonly feisPanels: FeisPanelFinder;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finbheara/archive-client",
3
- "version": "0.33.0",
3
+ "version": "0.34.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",