@finbheara/archive-client 0.3.1 → 0.5.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 +95 -6
- package/dist/chunks/{index-3va2jzse.js → index-8gna56w2.js} +609 -8
- package/dist/cli.js +200 -3
- package/dist/index.js +9 -1
- package/dist/types/cli.d.ts +3 -1
- package/dist/types/dancers.d.ts +33 -0
- package/dist/types/feises.d.ts +8 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/indexes.d.ts +7 -1
- package/dist/types/parquet.d.ts +4 -0
- package/dist/types/release.d.ts +3 -0
- package/dist/types/results.d.ts +11 -0
- package/dist/types/schema.d.ts +1 -0
- package/dist/types/stream.d.ts +71 -0
- package/dist/types/teams.d.ts +105 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Open a versioned release of an Irish dance results dataset and work with it locally: download,
|
|
4
4
|
verify, decompress and cache it by tag, keep a user-local cache of releases, and resolve feises,
|
|
5
|
-
schools, competitions, registration lists, dancers, results, majors, teachers
|
|
6
|
-
adjudicators against one. A command line, `idq`, is a thin wrapper over the same calls.
|
|
5
|
+
schools, competitions, registration lists, dancers, results, majors, teams, event dates, teachers
|
|
6
|
+
and adjudicators against one. A command line, `idq`, is a thin wrapper over the same calls.
|
|
7
7
|
|
|
8
8
|
Bun 1.4.2 or later (the databases open through `bun:sqlite`). MIT.
|
|
9
9
|
|
|
@@ -20,7 +20,7 @@ type declarations (`.d.ts`), so a TypeScript project needs Bun's types (`"types"
|
|
|
20
20
|
`bunx idq <verb>`.
|
|
21
21
|
|
|
22
22
|
The version is 0.x while the API settles: a minor bump may break, so pin a minor
|
|
23
|
-
(`"@finbheara/archive-client": "0.
|
|
23
|
+
(`"@finbheara/archive-client": "0.5.x"`).
|
|
24
24
|
|
|
25
25
|
## Configuration
|
|
26
26
|
|
|
@@ -85,6 +85,13 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
|
|
|
85
85
|
| `staff` | `staff.teacher`, `staff.adjudicator` | 260 |
|
|
86
86
|
| `majors.order` | `majors.competitions` | 260 |
|
|
87
87
|
| `feises`, `comps` | `feises.find`, `feises.series`, `comps.*`, `registrations.resolve` | 265 |
|
|
88
|
+
| `results.stream`, `majors.stream` | `results.stream`, `results.entries` | 255 |
|
|
89
|
+
| `feises.dates` | `feises.dates` | 245 |
|
|
90
|
+
| `dancers.records` | `dancers.records` | 215 |
|
|
91
|
+
| `dancers.years` | `dancers.years` | 245 |
|
|
92
|
+
| `majors.tabs` | `majors.tabulated` | 215 |
|
|
93
|
+
| `teams` | `teams.results`, `teams.rosters`, `teams.resultRosters` | 260 |
|
|
94
|
+
| `events` | `events.years` | 260 |
|
|
88
95
|
|
|
89
96
|
A spec is `pinned` (the default: the user-local pin, else the latest), `latest`, a cut number
|
|
90
97
|
(`42`, or `42.1` for a fraction) or a tag (`archive-YYYY.MM.DD-N`).
|
|
@@ -138,8 +145,9 @@ outside the cache root.
|
|
|
138
145
|
|
|
139
146
|
The release databases carry a primary key per table and nothing more, so lookups build side
|
|
140
147
|
indexes, one SQLite file per index per tag, each keyed on its builder's version and the sha256 of
|
|
141
|
-
every input it read. A file whose key is stale is rebuilt, never served.
|
|
142
|
-
caller may hand its own (`builders` option, an `IndexBuilder`
|
|
148
|
+
every input it read. A file whose key is stale is rebuilt, never served. These ship here, and a
|
|
149
|
+
caller may hand its own (`builders` option, an `IndexBuilder`, with an optional async `load` step
|
|
150
|
+
whose answer its `build` receives):
|
|
143
151
|
|
|
144
152
|
- `schools`: every published school print with the ids its rows carry, filed into a
|
|
145
153
|
`@finbheara/domain` `schoolEncoder` noun index, with the registry and the retired ids
|
|
@@ -151,6 +159,9 @@ caller may hand its own (`builders` option, an `IndexBuilder`):
|
|
|
151
159
|
- `staff` (keyed the same way): teachers and adjudicators by name (a `roleEncoder` noun index) and TD number: the
|
|
152
160
|
schools' staff lists and TD links, the adjudicator register, and the seats each sat
|
|
153
161
|
- `comps`: every competition by its feis and the feis's own code, with its series and year
|
|
162
|
+
- `teams`: the team results, the roster teams with their members, and how they join, by
|
|
163
|
+
event-year
|
|
164
|
+
- `events`: every event-year's dates and place
|
|
154
165
|
|
|
155
166
|
## Feises
|
|
156
167
|
|
|
@@ -270,6 +281,75 @@ A row carries the prints and the ids that stand for them: the address, the compe
|
|
|
270
281
|
and age, the place, the name and school as printed with the dancer and school ids. The majors are
|
|
271
282
|
read from `majors.sqlite`, fetched on first use.
|
|
272
283
|
|
|
284
|
+
## Every row, streamed
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
for await (const row of rel.results.stream({ scope: "majors" })) { ... }
|
|
288
|
+
for await (const row of rel.results.stream({
|
|
289
|
+
scope: "platform", // "majors" | "transcribed" | "platform" | "all"
|
|
290
|
+
primary: true, // only rows no other source stands in for
|
|
291
|
+
year: [2015, 2024], // a year or an inclusive range
|
|
292
|
+
feis_level: [600, 700], // also: event (one or several), tier, category, dancer_id, school_id
|
|
293
|
+
})) { ... }
|
|
294
|
+
for await (const entry of rel.results.entries({ scope: "all", event: "<event>" })) { ... }
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
A stream yields one row at a time and never holds the table in memory. A row carries its
|
|
298
|
+
competition beside its own fields: `competition`, `event`, `year`, `tier`, `comp_no`, `title`,
|
|
299
|
+
`category`, `age`, `age_printed`, `gender`, `competitors`, `feis_level`, `level_printed`,
|
|
300
|
+
`date_printed`, `source`, `round`, and at a feis its `feis_id`, `feis_date_lo` and
|
|
301
|
+
`feis_date_hi`. Its own: `address`, `section`, `card`, `place`, `place_printed`, `tie`,
|
|
302
|
+
`relative_place`, `atts`, `withdrawn`, `qualifier`, `name_printed`, `name`, `school_printed`,
|
|
303
|
+
`school_loc`, `school_id`, `dancer_id`, `dancer_scope`, `yob`, `yob_printed`, `points_printed`,
|
|
304
|
+
`platform_dancer_id`, `primary_source`. Rows come in the release's own order, a competition's
|
|
305
|
+
rows together.
|
|
306
|
+
|
|
307
|
+
The scopes: `majors` reads the majors (tiers T1 to T3), `transcribed` the transcribed rows of
|
|
308
|
+
every tier, `platform` every row a results platform published, `all` every row.
|
|
309
|
+
|
|
310
|
+
AN ENTRY is one row per address, the row the card stands for: a card printed in several sections
|
|
311
|
+
(a recall order, the final, a single round's solo placing, a qualifying heat) keeps the final's
|
|
312
|
+
row, then the sectionless page's, the recall order's, the standings', the unplaced row, a heat's
|
|
313
|
+
and last a solo round's (`entryRank`), and two rows of one rank keep the later. `recall_place` is
|
|
314
|
+
the place the address's recall row carries.
|
|
315
|
+
|
|
316
|
+
## Bulk reads
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
await rel.dancers.records(); // every dancer: display, appearances, birth_lo, birth_hi,
|
|
320
|
+
// birth_source, birth_conflict, genders, scope
|
|
321
|
+
await rel.dancers.records({ ids: [1001] });
|
|
322
|
+
await rel.dancers.years({ ids: [1001], year: 2025 }); // region, region_source, nationals, geohash
|
|
323
|
+
await rel.feises.dates(); // every feis id with its first and last day
|
|
324
|
+
await rel.majors.tabulated({ min_true_round: 3 }); // the majors addresses marked to round 3 or later
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Teams and event-years
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
const r = await rel.teams.results({ event: "<event>", year: 2024 });
|
|
331
|
+
r.results; // [{ address, competition, event, year, comp_no, title, category, hands, letter, label,
|
|
332
|
+
// school_printed, school_id, place, place_printed, tie, competitors, atts, ... }]
|
|
333
|
+
const t = await rel.teams.rosters({ event: "<event>", year: 2024 });
|
|
334
|
+
t.teams; // [{ team, kind, event, year, comp_no, title, team_index, seq, school_id, school_printed,
|
|
335
|
+
// members: [{ seq, name_printed, name, yob, dancer_id, dancer_scope }] }]
|
|
336
|
+
const j = await rel.teams.resultRosters({ event: "<event>", year: 2024 });
|
|
337
|
+
j.joins; // [{ team, result_address, join_kind, via_split, roster_index, result_letter, ... }]
|
|
338
|
+
const e = await rel.events.years({ event: "<event>" });
|
|
339
|
+
e.years; // [{ event, year, date_lo, date_hi, resolution, source, date_printed, place, place_printed }]
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
A query names an event (case-blind), a year, both, or neither (every row). Everything comes from
|
|
343
|
+
ONE release: a roster member's `dancer_id` is the same release's id as the results', so a caller
|
|
344
|
+
never joins team records of one release to dancer ids of another. A roster is a sheet of a school's
|
|
345
|
+
teams (`kind: "rosterTeam"`) or a result card's own line-up (`lineup`). `join_kind` says how a
|
|
346
|
+
roster team met the results (`exact`, `card`, `branch`) or why it did not (`no-result`,
|
|
347
|
+
`no-school`, `no-roster`, `multi-team-unjoined`), and `result_address` is null where none joined.
|
|
348
|
+
An event-year's dates are a window (`date_lo`, `date_hi`) with how fine it is (`resolution`:
|
|
349
|
+
`day`, `month`, `calendar`) and what it is read from (`source`), and `place` is a place-tree node
|
|
350
|
+
where the release knows one. A field the source left empty is null. The rows are read once per
|
|
351
|
+
release into the `teams` and `events` indexes.
|
|
352
|
+
|
|
273
353
|
## Teachers and adjudicators
|
|
274
354
|
|
|
275
355
|
```ts
|
|
@@ -394,6 +474,15 @@ and the competitions still resolve.
|
|
|
394
474
|
[--population girls|boys] [--rows]
|
|
395
475
|
idq results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <c>] [--school <s>] [--year <y>] [--limit <n>]
|
|
396
476
|
idq majors [--release <spec>] [--event <e>] [--year <y>] [--comp <c>] [--dancer <id>] [--rows]
|
|
477
|
+
idq stream [--release <spec>] --scope majors|transcribed|platform|all [--entries] [--event <e,...>]
|
|
478
|
+
[--year <y> | --year <from>..<to>] [--tier <t,...>] [--category <c,...>]
|
|
479
|
+
[--level <n,...>] [--dancer <id,...>] [--school <school_id>] [--primary]
|
|
480
|
+
idq records [--release <spec>] [--dancer <id,...>]
|
|
481
|
+
idq records --years [--release <spec>] [--dancer <id,...>] [--year <y>]
|
|
482
|
+
idq feis-dates [--release <spec>]
|
|
483
|
+
idq tabulated [--release <spec>] [--min-round <n>]
|
|
484
|
+
idq teams [--release <spec>] [--event <e>] [--year <y>] [--rosters | --joins]
|
|
485
|
+
idq events [--release <spec>] [--event <e>] [--year <y>]
|
|
397
486
|
idq teacher [--release <spec>] <name|TD number>
|
|
398
487
|
idq adjudicator [--release <spec>] <name|TD number>
|
|
399
488
|
idq comp [--release <spec>] <feis> <code> [--year y] [--title t]
|
|
@@ -403,7 +492,7 @@ and the competitions still resolve.
|
|
|
403
492
|
idq resolve dancer [<name>] [--school s] [--comp <feis>/<code> | --yob y | --band b --year y]
|
|
404
493
|
idq resolve registrations
|
|
405
494
|
|
|
406
|
-
`dancer` prints the results of the one dancer where the answer is unique (every candidate's with
|
|
495
|
+
`stream` prints one JSON line per row (or entry), as it reads them. `dancer` prints the results of the one dancer where the answer is unique (every candidate's with
|
|
407
496
|
`--rows`). `--json` prints the call's answer as it is. `--cache` and `--repo` override the defaults.
|
|
408
497
|
|
|
409
498
|
`resolve` speaks JSON lines: one answer per line out, and with no positional question the
|