@finbheara/archive-client 0.40.0 → 0.42.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/dist/cli.js CHANGED
@@ -20,13 +20,15 @@ import {
20
20
  LATEST_CHECK_BUDGET_MS2,
21
21
  latestCheck2,
22
22
  within,
23
- staleWarning2
24
- } from "./chunks/index-bs939h4v.js";
23
+ staleWarning2,
24
+ progressMode2,
25
+ progressRenderer2
26
+ } from "./chunks/index-0xdcttqf.js";
25
27
  import"./chunks/index-hghdy980.js";
26
28
 
27
- var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live]";
29
+ var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live] [--progress tty|plain|none]";
28
30
  var GLOBAL_FLAGS = {
29
- value: ["--cache", "--repo"],
31
+ value: ["--cache", "--repo", "--progress"],
30
32
  bool: ["--json", "--live"]
31
33
  };
32
34
  var VERBS = [
@@ -510,6 +512,12 @@ var VERBS = [
510
512
  }
511
513
  ];
512
514
  var USAGE_FOOTER = [
515
+ " A download or an index build reports on stderr: on a terminal one line per file, redrawn in",
516
+ " place (bytes of the total, rate, downloading, unpacking, verifying, indexing, done); redirected,",
517
+ " one start line and one done (or failed) line per file, with its size and time. --progress",
518
+ " tty|plain|none (or IDQ_PROGRESS) forces a mode. Up to 4 files download at once, each",
519
+ " decompressed and hashed while it arrives; the first failure cancels the rest, and fails the call.",
520
+ "",
513
521
  " A query on the default spec prints one warning line on stderr when its release is older than",
514
522
  " the newest published one (the remote asked at most once per hour, <cache>/LATEST.json); the",
515
523
  " answer and the exit code are unchanged, and an offline check says nothing.",
@@ -897,8 +905,10 @@ async function main(argv, io = {}) {
897
905
  const say = io.say ?? ((s) => console.log(s));
898
906
  const log = io.log ?? ((s) => console.error(s));
899
907
  let p;
908
+ let progress;
900
909
  try {
901
910
  p = parseArgs(argv);
911
+ progress = progressRenderer2(progressMode2(p.flags.get("--progress"), io.env ?? process.env, io.isTTY ?? process.stderr.isTTY === true), { line: log, ...io.write !== undefined ? { write: io.write } : {} });
902
912
  } catch (e) {
903
913
  log(e.message);
904
914
  return 2;
@@ -909,6 +919,7 @@ async function main(argv, io = {}) {
909
919
  const opts = {
910
920
  ...io.opts,
911
921
  log,
922
+ progress: io.opts?.progress ?? progress.sink,
912
923
  ...p.flags.has("--cache") ? { cache: p.flags.get("--cache") } : {},
913
924
  ...p.flags.has("--repo") ? { repo: p.flags.get("--repo") } : {}
914
925
  };
@@ -1777,9 +1788,11 @@ async function main(argv, io = {}) {
1777
1788
  return verb === undefined || verb === "help" ? 0 : 2;
1778
1789
  }
1779
1790
  } catch (e) {
1791
+ progress.close();
1780
1792
  log(`idq ${verb}: ${e.message}`);
1781
1793
  return 1;
1782
1794
  } finally {
1795
+ progress.close();
1783
1796
  const b = answered.build;
1784
1797
  if (b !== null)
1785
1798
  log(`answered from ${b.build.label} (unpublished, ${b.build.dir}). Pass --release <tag> for a published one, or --live for the pin.`);
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  planAsset2,
5
5
  sha256File2,
6
6
  unzstdTo2,
7
+ streamTo2,
7
8
  NAME_LEVELS2,
8
9
  nameLevel2,
9
10
  TabFinder2,
@@ -59,6 +60,7 @@ import {
59
60
  DEPARTURE_REASONS2,
60
61
  UpcomingFinder2,
61
62
  resolveTag2,
63
+ DEFAULT_CONCURRENCY2,
62
64
  Release2,
63
65
  openRelease2,
64
66
  openCached2,
@@ -79,8 +81,11 @@ import {
79
81
  latestCheckPath2,
80
82
  readLatestCheck2,
81
83
  latestCheck2,
82
- staleWarning2
83
- } from "./chunks/index-bs939h4v.js";
84
+ staleWarning2,
85
+ PROGRESS_MODES2,
86
+ progressMode2,
87
+ progressRenderer2
88
+ } from "./chunks/index-0xdcttqf.js";
84
89
  import {
85
90
  cacheRoot2,
86
91
  repoOf2
@@ -94,15 +99,86 @@ import {
94
99
  parseReleaseSpec2,
95
100
  pickTag2
96
101
  } from "./chunks/index-hghdy980.js";
102
+ var ATTACH_OUTCOMES = [
103
+ "majors",
104
+ "no-card",
105
+ "attached",
106
+ "unrefuted",
107
+ "decision",
108
+ "account",
109
+ "unique-name",
110
+ "band-unique",
111
+ "pre-majors",
112
+ "transfer",
113
+ "address-conflict",
114
+ "no-name",
115
+ "no-year",
116
+ "no-namesake",
117
+ "school-unresolved",
118
+ "school-disagrees",
119
+ "school-years",
120
+ "sex-split",
121
+ "birth-window",
122
+ "under-cap",
123
+ "too-young",
124
+ "young-school",
125
+ "level-age",
126
+ "ambiguous",
127
+ "vetoed",
128
+ "feis-birth",
129
+ "co-attendance",
130
+ "card-split",
131
+ "same-spans-identities",
132
+ "same-contradicted",
133
+ "co-appearance",
134
+ "under-18-return",
135
+ "distinct-split"
136
+ ];
137
+ var OUTCOME_UNREAD = 63;
138
+ var OUTCOME_MASK = 63;
139
+ var ATTACH_VIA = {
140
+ assignment: 1 << 6,
141
+ ledger: 1 << 7,
142
+ "local-attach": 1 << 8,
143
+ "local-fold": 1 << 9,
144
+ "feis-attach": 1 << 10,
145
+ kinship: 1 << 11,
146
+ "initial-only": 1 << 12,
147
+ "name-school-fold": 1 << 13,
148
+ "feis-local": 1 << 14,
149
+ ruling: 1 << 15
150
+ };
151
+ var CODE = new Map(ATTACH_OUTCOMES.map((n, i) => [n, i]));
152
+ function outcomeCode(name) {
153
+ const c = CODE.get(name);
154
+ if (c === undefined)
155
+ throw new Error(`attach basis: no code for the outcome ${name}`);
156
+ return c;
157
+ }
158
+ function packAttachBasis(outcome, via) {
159
+ let n = outcome;
160
+ for (const v of via)
161
+ n |= ATTACH_VIA[v];
162
+ return n;
163
+ }
164
+ function unpackAttachBasis(n) {
165
+ const code = n & OUTCOME_MASK;
166
+ const outcome = code === OUTCOME_UNREAD ? "unread" : ATTACH_OUTCOMES[code] ?? null;
167
+ const via = Object.keys(ATTACH_VIA).filter((k) => (n & ATTACH_VIA[k]) !== 0);
168
+ return { outcome, via };
169
+ }
97
170
  export {
98
171
  ADVANCEMENT_DANCES2 as ADVANCEMENT_DANCES,
99
172
  ARCHIVE_TAG2 as ARCHIVE_TAG,
173
+ ATTACH_OUTCOMES,
174
+ ATTACH_VIA,
100
175
  CALENDAR_STAGES2 as CALENDAR_STAGES,
101
176
  CALENDAR_STAGE_STATES2 as CALENDAR_STAGE_STATES,
102
177
  CALENDAR_TERMINALS2 as CALENDAR_TERMINALS,
103
178
  CalendarFinder2 as CalendarFinder,
104
179
  CompResolver2 as CompResolver,
105
180
  DATABASES2 as DATABASES,
181
+ DEFAULT_CONCURRENCY2 as DEFAULT_CONCURRENCY,
106
182
  DEFAULT_KEEP2 as DEFAULT_KEEP,
107
183
  DEPARTURE_REASONS2 as DEPARTURE_REASONS,
108
184
  DancerResolver2 as DancerResolver,
@@ -120,6 +196,9 @@ export {
120
196
  NAME_LEVELS2 as NAME_LEVELS,
121
197
  NO_CALENDAR2 as NO_CALENDAR,
122
198
  NO_UPCOMING2 as NO_UPCOMING,
199
+ OUTCOME_MASK,
200
+ OUTCOME_UNREAD,
201
+ PROGRESS_MODES2 as PROGRESS_MODES,
123
202
  PanelFinder2 as PanelFinder,
124
203
  RegistrationResolver2 as RegistrationResolver,
125
204
  Release2 as Release,
@@ -161,11 +240,15 @@ export {
161
240
  openBuild2 as openBuild,
162
241
  openCached2 as openCached,
163
242
  openRelease2 as openRelease,
243
+ outcomeCode,
244
+ packAttachBasis,
164
245
  parseArchiveTag2 as parseArchiveTag,
165
246
  parseReleaseSpec2 as parseReleaseSpec,
166
247
  pickBuild2 as pickBuild,
167
248
  pickTag2 as pickTag,
168
249
  planAsset2 as planAsset,
250
+ progressMode2 as progressMode,
251
+ progressRenderer2 as progressRenderer,
169
252
  readLatestCheck2 as readLatestCheck,
170
253
  readPin2 as readPin,
171
254
  readPopulation2 as readPopulation,
@@ -180,8 +263,10 @@ export {
180
263
  setRemote2 as setRemote,
181
264
  sha256File2 as sha256File,
182
265
  staleWarning2 as staleWarning,
266
+ streamTo2 as streamTo,
183
267
  sweepBuilds2 as sweepBuilds,
184
268
  syllabusSourceOf2 as syllabusSourceOf,
269
+ unpackAttachBasis,
185
270
  unzstdTo2 as unzstdTo,
186
271
  youngest2 as youngest
187
272
  };
@@ -0,0 +1,23 @@
1
+ export declare const ATTACH_OUTCOMES: readonly ["majors", "no-card", "attached", "unrefuted", "decision", "account", "unique-name", "band-unique", "pre-majors", "transfer", "address-conflict", "no-name", "no-year", "no-namesake", "school-unresolved", "school-disagrees", "school-years", "sex-split", "birth-window", "under-cap", "too-young", "young-school", "level-age", "ambiguous", "vetoed", "feis-birth", "co-attendance", "card-split", "same-spans-identities", "same-contradicted", "co-appearance", "under-18-return", "distinct-split"];
2
+ export declare const OUTCOME_UNREAD = 63;
3
+ export declare const OUTCOME_MASK = 63;
4
+ export type AttachOutcomeName = (typeof ATTACH_OUTCOMES)[number] | "unread";
5
+ export declare const ATTACH_VIA: {
6
+ readonly assignment: number;
7
+ readonly ledger: number;
8
+ readonly "local-attach": number;
9
+ readonly "local-fold": number;
10
+ readonly "feis-attach": number;
11
+ readonly kinship: number;
12
+ readonly "initial-only": number;
13
+ readonly "name-school-fold": number;
14
+ readonly "feis-local": number;
15
+ readonly ruling: number;
16
+ };
17
+ export type AttachVia = keyof typeof ATTACH_VIA;
18
+ export declare function outcomeCode(name: string): number;
19
+ export declare function packAttachBasis(outcome: number, via: readonly AttachVia[]): number;
20
+ export declare function unpackAttachBasis(n: number): {
21
+ outcome: AttachOutcomeName | null;
22
+ via: AttachVia[];
23
+ };
@@ -1,3 +1,15 @@
1
1
  export declare function sha256File(path: string): Promise<string>;
2
2
  export declare function unzstdTo(src: string, dest: string): Promise<string>;
3
3
  export declare function sha256OfDigest(digest: string | null | undefined): string | null;
4
+ export interface Streamed {
5
+ rawSha256: string;
6
+ rawBytes: number;
7
+ sha256: string;
8
+ bytes: number;
9
+ }
10
+ export declare function streamTo(source: AsyncIterable<Uint8Array>, dest: string, o: {
11
+ decompress: boolean;
12
+ raw?: string;
13
+ onBytes?: (received: number, written: number) => void;
14
+ signal?: AbortSignal;
15
+ }): Promise<Streamed>;
@@ -4,7 +4,7 @@ export interface VerbSpec {
4
4
  bool: readonly string[];
5
5
  usage: readonly string[];
6
6
  }
7
- export declare const USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live]";
7
+ export declare const USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live] [--progress tty|plain|none]";
8
8
  export declare const GLOBAL_FLAGS: {
9
9
  value: readonly string[];
10
10
  bool: readonly string[];
@@ -39,4 +39,7 @@ export declare function main(argv: readonly string[], io?: {
39
39
  stdin?: () => Promise<string>;
40
40
  freshness?: FreshnessIO | false;
41
41
  local?: LocalIO | false;
42
+ env?: Readonly<Record<string, string | undefined>>;
43
+ isTTY?: boolean;
44
+ write?: (s: string) => void;
42
45
  }): Promise<number>;
@@ -1,5 +1,6 @@
1
1
  export { type AssetPlan, DATABASES, type DatabaseName, type LandedFile, type Receipt, type ReleaseManifest, planAsset, } from "./assets.js";
2
- export { sha256File, unzstdTo } from "./bytes.js";
2
+ export { ATTACH_OUTCOMES, ATTACH_VIA, type AttachOutcomeName, type AttachVia, OUTCOME_MASK, OUTCOME_UNREAD, outcomeCode, packAttachBasis, unpackAttachBasis, } from "./attach-basis.js";
3
+ export { type Streamed, sha256File, streamTo, unzstdTo } from "./bytes.js";
3
4
  export { type AgeAsked, type AgeEvidence, type DancerAnswer, type DancerBulkRecord, type DancerCandidate, type DancerQuery, type DancerRecord, DancerResolver, type DancerRegion, type DancerSchool, type DancerSearchQuery, type DancerYear, type ExcludedCandidate, FEIS_LOCAL_ID_FLOOR, type InitialsRefuted, type Narrowing, initialsOnly, type OireachtasAsked, type PopulationEvidence, type RegionEvidence, type SchoolEvidence, readPopulation, } from "./dancers.js";
4
5
  export { NAME_LEVELS, type NameLevel, nameLevel } from "./dancers-names.js";
5
6
  export { ADVANCEMENT_DANCES, type DancerGrades, type DancerLevelAnswer, type DancerLevelQuery, type LevelRange, } from "./dancer-level.js";
@@ -14,7 +15,8 @@ export { type Registered, type Sat, type StaffAnswer, StaffFinder, type StaffPer
14
15
  export { type FreshnessFloor, LATEST_CHECK_BUDGET_MS, LATEST_CHECK_MS, type LatestCheck, latestCheck, latestCheckPath, readLatestCheck, staleWarning, } from "./freshness.js";
15
16
  export { type Pin, readPin } from "./pin.js";
16
17
  export { type Remote, type RemoteAsset, fallbackRemote, ghRemote, httpsRemote, setRemote, } from "./remote.js";
17
- export { type OpenOptions, Release, openCached, openRelease, resolveTag, } from "./release.js";
18
+ export { DEFAULT_CONCURRENCY, type Fetching, type OpenOptions, Release, openCached, openRelease, resolveTag, } from "./release.js";
19
+ export { PROGRESS_MODES, type ProgressEvent, type ProgressMode, type ProgressRenderer, type ProgressSink, type ProgressState, progressMode, progressRenderer, } from "./progress.js";
18
20
  export { type MajorCompetition, type MajorEvent, MajorsFinder, type ResultAnswer, ResultFinder, type ResultQuery, type ResultRow, } from "./results.js";
19
21
  export { type DancerAnswerLike, type DancerQueryLike, type DancerResolverLike, type DancerUnavailable, type RegistrationRow, type ResolvedDancer, RegistrationResolver, type ResolvedRegistration, dancerResolverOf, youngest, } from "./registrations.js";
20
22
  export type { LineageEdge, ObservedAssociation, RegistrySchool, SchoolPrint, SchoolRedirect, } from "./school-bulk.js";
@@ -1,4 +1,5 @@
1
1
  import { Database } from "bun:sqlite";
2
+ import type { ProgressSink } from "./progress.js";
2
3
  import type { Release } from "./release.js";
3
4
  export interface IndexBuilder {
4
5
  readonly name: string;
@@ -27,6 +28,7 @@ export declare function buildIndex(rel: Release, b: IndexBuilder, o: {
27
28
  export declare function ensureIndex(rel: Release, b: IndexBuilder, o: {
28
29
  force: boolean;
29
30
  log?: (line: string) => void;
31
+ progress?: ProgressSink;
30
32
  }): Promise<string>;
31
33
  export interface IndexFile {
32
34
  name: string;
@@ -84,6 +84,7 @@ export declare class ReleaseManager {
84
84
  path: string;
85
85
  }[];
86
86
  }>;
87
+ private buildAsLanded;
87
88
  private plan;
88
89
  private planRemove;
89
90
  private apply;
@@ -0,0 +1,30 @@
1
+ export type ProgressState = "downloading" | "unpacking" | "verifying" | "indexing" | "done" | "failed" | "cancelled";
2
+ export interface ProgressEvent {
3
+ tag: string;
4
+ kind: "asset" | "index";
5
+ item: string;
6
+ state: ProgressState;
7
+ bytes: number;
8
+ total: number | null;
9
+ unpacked: number;
10
+ ms: number;
11
+ error?: string;
12
+ }
13
+ export type ProgressSink = (e: ProgressEvent) => void;
14
+ export type ProgressMode = "tty" | "plain" | "none";
15
+ export declare const PROGRESS_MODES: readonly ProgressMode[];
16
+ export declare function progressMode(flag: string | undefined, env: Readonly<Record<string, string | undefined>>, isTTY: boolean): ProgressMode;
17
+ export declare function bytesText(n: number): string;
18
+ export declare function plainLine(e: ProgressEvent, started: boolean): string | null;
19
+ export declare function ttyLine(e: ProgressEvent, width: number): string;
20
+ export interface ProgressRenderer {
21
+ readonly mode: ProgressMode;
22
+ sink: ProgressSink;
23
+ close(): void;
24
+ }
25
+ export declare function progressRenderer(mode: ProgressMode, io: {
26
+ line: (s: string) => void;
27
+ write?: (s: string) => void;
28
+ columns?: () => number;
29
+ intervalMs?: number;
30
+ }): ProgressRenderer;
@@ -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 { type Streamed } from "./bytes.js";
3
4
  import { CalendarFinder } from "./calendar.js";
4
5
  import { CompResolver } from "./comps.js";
5
6
  import { type ClientOptions } from "./config.js";
@@ -7,8 +8,9 @@ import { DancerResolver } from "./dancers.js";
7
8
  import { FeisFinder } from "./feises.js";
8
9
  import { type IndexBuilder } from "./indexes.js";
9
10
  import { StaffFinder } from "./people.js";
11
+ import type { ProgressSink } from "./progress.js";
10
12
  import { type DancerResolverLike, RegistrationResolver } from "./registrations.js";
11
- import { type Remote } from "./remote.js";
13
+ import { type Remote, type RemoteAsset } from "./remote.js";
12
14
  import { MajorsFinder, ResultFinder } from "./results.js";
13
15
  import { type Capability } from "./schema.js";
14
16
  import { type SchoolReaderChoice, SchoolResolver } from "./schools.js";
@@ -22,6 +24,8 @@ export interface OpenOptions extends ClientOptions {
22
24
  strict?: boolean;
23
25
  keepCompressed?: boolean;
24
26
  log?: (line: string) => void;
27
+ progress?: ProgressSink;
28
+ concurrency?: number;
25
29
  builders?: readonly IndexBuilder[];
26
30
  schoolReader?: SchoolReaderChoice;
27
31
  dancerResolver?: DancerResolverLike | null;
@@ -30,6 +34,13 @@ export declare function tagDir(root: string, tag: string): string;
30
34
  export declare const receiptPath: (dir: string) => string;
31
35
  export declare function readReceipt(dir: string): Receipt | null;
32
36
  export declare function resolveTag(spec: string | number | ReleaseSpec, opts?: OpenOptions): Promise<string>;
37
+ export declare const DEFAULT_CONCURRENCY = 4;
38
+ export declare function partPath(dest: string): string;
39
+ export interface Fetching {
40
+ each(asset: string): Promise<LandedFile>;
41
+ all: Promise<LandedFile[]>;
42
+ cancel(): void;
43
+ }
33
44
  export declare class Release {
34
45
  readonly tag: string;
35
46
  readonly cut: number | undefined;
@@ -54,13 +65,17 @@ export declare class Release {
54
65
  readonly feisPanels: FeisPanelFinder;
55
66
  private readonly opts;
56
67
  private readonly handles;
57
- private remoteAssets;
68
+ private listing;
58
69
  constructor(tag: string, root: string, manifest: ReleaseManifest, opts: OpenOptions);
59
70
  receipt(): Receipt;
60
71
  plan(asset: string): AssetPlan;
61
72
  has(asset: string): boolean;
62
73
  path(asset: string): string;
63
74
  fetch(...assets: string[]): Promise<LandedFile[]>;
75
+ private readonly inflight;
76
+ private slots;
77
+ private swept;
78
+ fetching(assets: readonly string[]): Fetching;
64
79
  publishes(asset: string): Promise<boolean>;
65
80
  private readonly probe;
66
81
  private readonly checked;
@@ -83,6 +98,23 @@ export declare class Release {
83
98
  close(): void;
84
99
  [Symbol.dispose](): void;
85
100
  }
101
+ export declare function verifyLanded(got: Pick<Streamed, "rawSha256" | "sha256">, pub: {
102
+ name: string;
103
+ digest: string | null;
104
+ }, plan: AssetPlan, strict: boolean): LandedFile["verified"];
105
+ export interface AssetJob {
106
+ remote: Remote;
107
+ repo: string;
108
+ tag: string;
109
+ pub: RemoteAsset;
110
+ plan: AssetPlan;
111
+ dest: string;
112
+ opts: Pick<OpenOptions, "strict" | "keepCompressed">;
113
+ log: (line: string) => void;
114
+ progress?: ProgressSink;
115
+ signal?: AbortSignal;
116
+ }
117
+ export declare function fetchAsset(j: AssetJob): Promise<LandedFile>;
86
118
  export declare function land(raw: string, pub: {
87
119
  name: string;
88
120
  digest: string | null;
@@ -8,6 +8,7 @@ export interface Remote {
8
8
  tags(repo: string): Promise<string[]>;
9
9
  assets(repo: string, tag: string): Promise<RemoteAsset[]>;
10
10
  download(repo: string, tag: string, name: string, dest: string): Promise<void>;
11
+ bytes?(repo: string, tag: string, name: string, signal?: AbortSignal): Promise<AsyncIterable<Uint8Array>>;
11
12
  }
12
13
  export declare const ghRemote: Remote;
13
14
  export declare function httpsRemote(env?: Readonly<Record<string, string | undefined>>, fetchImpl?: typeof fetch): Remote;
@@ -32,6 +32,7 @@ export interface ResultRow {
32
32
  school_id: string | null;
33
33
  yob: number | null;
34
34
  qualifier: string | null;
35
+ attach_basis?: number;
35
36
  }
36
37
  export interface ResultAnswer {
37
38
  tag: string;
@@ -40,7 +41,7 @@ export interface ResultAnswer {
40
41
  rows: ResultRow[];
41
42
  truncated: number;
42
43
  }
43
- export declare function queryResults(rel: Release, db: string, q: ResultQuery): ResultAnswer;
44
+ export declare function queryResults(rel: Release, db: string, q: ResultQuery, basis?: boolean): ResultAnswer;
44
45
  export declare class ResultFinder {
45
46
  private readonly rel;
46
47
  constructor(rel: Release);
@@ -0,0 +1,4 @@
1
+ export declare function pidAlive(pid: number): boolean;
2
+ export declare const PART_FILE: RegExp;
3
+ export declare const BUILDING_FILE: RegExp;
4
+ export declare function sweepDead(dir: string, re: RegExp): string[];
@@ -57,6 +57,7 @@ export interface StreamRow extends Partial<StreamCompetition> {
57
57
  school_id: string | null;
58
58
  dancer_id: number | null;
59
59
  dancer_scope: "per-release" | "stable" | null;
60
+ attach_basis?: number;
60
61
  yob: number | null;
61
62
  yob_printed: string | null;
62
63
  points_printed: string | null;
@@ -72,6 +73,7 @@ export declare function entryRank(section: string): number;
72
73
  export interface StreamShape {
73
74
  competition?: boolean;
74
75
  competitorsPrinted?: boolean;
76
+ attachBasis?: boolean;
75
77
  }
76
78
  export declare const scopeDb: (s: StreamScope) => "majors" | "results";
77
79
  export declare function streamSql(q: StreamQuery, shape?: StreamShape): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finbheara/archive-client",
3
- "version": "0.40.0",
3
+ "version": "0.42.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",