@finbheara/archive-client 0.40.0 → 0.43.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
@@ -94,6 +94,8 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
94
94
  | `dancers.records.names` | the `names_printed` a record of `dancers.records` carries; absent, never refused, without it | 215 |
95
95
  | `dancers.years` | `dancers.years` | 245 |
96
96
  | `results.stream.competitors_printed`, `majors.stream.competitors_printed` | the `competitors_printed` a streamed row carries (the competed count the page printed); absent, never refused, without it | 345 |
97
+ | `results.attach_basis`, `majors.attach_basis` | the `attach_basis` a row of `results.query`, `majors.results`, `results.stream` and `results.entries` carries (how its `dancer_id` was answered, or why not); absent, never refused, without it | 345 |
98
+ | `dancers.records.birth_consistency`, `dancers.years.birth_consistency` | the `birth_consistency` (0-100, floored: the percent of the dancer's, or the dancer-year's, readable rows that fit the birth window) and its denominator `birth_consistency_rows` a record of `dancers.records` and a dancer-year of `dancers.years` carry; absent, never refused, without it | 345 |
97
99
  | `dancers.years.printed` | the `printed_regions` a dancer-year of `dancers.years` carries (every region the year printed, where `region` picks one); absent, never refused, without it | 341 |
98
100
  | `majors.tabs` | `majors.tabulated` | 215 |
99
101
  | `teams` | `teams.results`, `teams.rosters`, `teams.resultRosters` | 260 |
@@ -146,6 +148,48 @@ A file already in place with no receipt (laid out by hand) is adopted where the
146
148
  vouches for it, and fetched again where it does not. A published release never changes, so a
147
149
  verified file is never fetched twice.
148
150
 
151
+ EACH DOWNLOAD WRITES A TEMP FILE OF ITS OWN beside its destination,
152
+ `<root>/<tag>/.<file>.<pid>-<hex>.part`, and renames it into place only once both its hashes
153
+ checked. A failure or a cancel leaves only what was there before, and two processes fetching one
154
+ release into one cache each land a whole, verified file (the last rename wins, the same bytes). A
155
+ temp file whose process is no longer running (a killed fetch's, or an index's
156
+ `<name>.sqlite.building.<pid>`) is removed by the next fetch or build in its directory.
157
+
158
+ ## Downloads: concurrent, streamed, reported
159
+
160
+ `rel.fetch(...assets)` (and so `openRelease`, `fetch`, `index`, `use` and `update`) downloads up
161
+ to `concurrency` files at once (the option; default `DEFAULT_CONCURRENCY`, 4), and each one is
162
+ hashed, decompressed and hashed again WHILE its bytes arrive, as a container pull downloads and
163
+ extracts at once: a file is verified when its last byte lands. `use` (and `index`) builds each
164
+ index as soon as its own inputs have landed, while the rest still download. The first file that
165
+ fails cancels the others, waits for them to stop, and fails the call with its own error, naming
166
+ the file; `use` then moves no pin. `rel.fetching(assets)` answers at once with each asset's own
167
+ promise (`each(asset)`), the whole (`all`) and `cancel()`.
168
+
169
+ A `Remote` streams where it has `bytes(repo, tag, name, signal)` (`gh release download -O -`, or
170
+ the HTTPS body); one without it is read through `download`, to a temp file, then decompressed.
171
+
172
+ The `progress` option is told every file's and every index's state and bytes
173
+ (`ProgressEvent`: `downloading`, `unpacking`, `verifying`, `indexing`, then `done`, `failed` or
174
+ `cancelled`), and `progressRenderer(mode, { line })` prints them in one of three modes:
175
+
176
+ - `tty`: one line per file and per index, redrawn in place: name, bytes of the total, unpacked
177
+ bytes, rate and state
178
+ - `plain`: one `start` line when a file (or an index) starts and one `done` (or `failed`,
179
+ `cancelled`) line when it ends, with its size and time; no control character, nothing else
180
+ - `none`: nothing
181
+
182
+ The command line picks `tty` where stderr is a terminal and `plain` where it is not (redirected, a
183
+ CI log, an agent's capture). `--progress tty|plain|none`, or `IDQ_PROGRESS`, forces a mode. A
184
+ cache already current fetches nothing and prints nothing:
185
+
186
+ start <tag> results.sqlite.zst (179.0 MB)
187
+ start <tag> school-registry.jsonl (272.5 kB)
188
+ done <tag> school-registry.jsonl 272.5 kB in 0.9 s
189
+ done <tag> results.sqlite.zst 179.0 MB -> 1.42 GB in 9.8 s
190
+ start <tag> index schools
191
+ done <tag> index schools in 12.3 s
192
+
149
193
  ## The release manager
150
194
 
151
195
  ```ts
@@ -604,6 +648,8 @@ A release without them streams every row with the six fields ABSENT, never null.
604
648
 
605
649
  `competitors_printed` (feature `results.stream.competitors_printed`, `majors.stream.competitors_printed` for scope `majors`) is the competed count the page itself printed, null where it printed none. `competitors` stays the best value. A release without it streams the field ABSENT.
606
650
 
651
+ `attach_basis` (feature `results.attach_basis`, `majors.attach_basis` for scope `majors` and `rel.majors.results`) says how a row's `dancer_id` was answered, or why it was not, in one integer: `attach_basis & 63` is the feis attach's outcome for the row's address (`0` on a majors row, `1` a platform row it carded no card for, else attached how or the gate that refused it), `attach_basis & ~63` the bits of where the id came from (none where `dancer_id` is null). `unpackAttachBasis(n)` decodes it, `{ outcome: "birth-window", via: ["feis-local"] }`, off the register `ATTACH_OUTCOMES` and `ATTACH_VIA` the package exports, and the release's `DATA-DICTIONARY.md` says what each value means. `rel.results.query` and `rel.majors.results` rows carry it too. A release without it returns the field ABSENT.
652
+
607
653
  THE COMPETITION'S KEY is `competition` (`<event-year>.<comp>` at a major, `<platform>:<host>.<comp>`
608
654
  at a feis), which holds across releases. Inside one release `(file, competition_line)` is exact: a
609
655
  competition captured twice (two files of one platform) carries one `competition` in both and two
@@ -623,10 +669,14 @@ the place the address's recall row carries.
623
669
  ```ts
624
670
  await rel.dancers.records(); // every dancer: display, appearances, birth_lo, birth_hi,
625
671
  // birth_source, birth_conflict, genders, scope,
626
- // names_printed (dancers.records.names)
672
+ // names_printed (dancers.records.names),
673
+ // birth_consistency, birth_consistency_rows
674
+ // (dancers.records.birth_consistency)
627
675
  await rel.dancers.records({ ids: [1001] });
628
676
  await rel.dancers.years({ ids: [1001], year: 2025 }); // region, region_source, nationals, geohash
629
- // printed_regions (dancers.years.printed)
677
+ // printed_regions (dancers.years.printed),
678
+ // birth_consistency, birth_consistency_rows
679
+ // (dancers.years.birth_consistency)
630
680
  await rel.feises.dates(); // every feis id with its first and last day
631
681
  await rel.majors.tabulated({ min_true_round: 3 }); // the majors addresses marked to round 3 or later
632
682
  ```
@@ -965,6 +1015,9 @@ is passed to the dancer resolver as asked (`rel.dancers`, above).
965
1015
 
966
1016
  ## The command line
967
1017
 
1018
+ Every verb takes `--cache <dir>`, `--repo <owner/name>`, `--json`, `--live` and
1019
+ `--progress tty|plain|none` (above).
1020
+
968
1021
  idq config repo <owner/name>
969
1022
  idq config keep <N>
970
1023
  idq list [--remote]