@finbheara/domain 0.39.0 → 0.41.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
@@ -45,7 +45,7 @@ ESM, Node ≥ 22 or Bun ≥ 1.4.2. MIT. Not affiliated with or endorsed by any d
45
45
  | `@finbheara/domain/ceili` | `ceili()`, `ceiliRelation`, `CEILI_NODES`: the céilí handbook dances |
46
46
  | `@finbheara/domain/dance` | `dance()`: a print read as a tune and a céilí dance, narrowed by its round |
47
47
  | `@finbheara/domain/age` | `Age.from`, `Age.fromYOB`, `Age.fromTitle`, `ageTitleToken`, `ageRelation`, `canOverlap`, `averageAge`, `isAveraged`, `intersectBirthYears`, `validYOB`, the age constants |
48
- | `@finbheara/domain/noun-index` | `createIndex`, `indexSchema`, `personEncoder`, and the `SqlHandle`/`NounEncoder` types: a database-backed name map (below) |
48
+ | `@finbheara/domain/noun-index` | `createIndex`, `indexSchema`, `personEncoder`, `roleEncoder`, `roleSchoolGlob`, and the `SqlHandle`/`NounEncoder` types: a database-backed name map (below) |
49
49
  | `@finbheara/domain/dance-types` | `danceTypes()`, `DANCE_TYPES`, `rhythmOfTime`, and the shared `DanceMatch`/`DanceRelation`/`SetRhythm`/`TimeSignature` types |
50
50
  | `@finbheara/domain/promotion` | `samePromotedRow`, `samePromotedSchool`, `samePromotedHeir`, `samePromotedName`, `questionMarksRead`, `foldCharSynonyms`: is a row the same row after a promotion (below) |
51
51
  | `@finbheara/domain/person` | `seatName`, `dancerName`, `teacherName`, `roleName`, `roleSentinelOf`, `rolePrintsNoName`, `dancerPrintsNoName`, the role lists and `SHARED_ROW_SENTINELS`: a person's print read in its role (below) |
@@ -512,6 +512,28 @@ schools.nouns(11).map((s) => s.sn0); // ["Ardvarna Academy", "
512
512
  schools.get(read("Ardvarna Academy of Irish Dance (Calgary, AB)"), "sn3"); // [10]
513
513
  ```
514
514
 
515
+ An adjudicator and a teacher are one type, a `RolePerson`: a name read in its role, the
516
+ person's number in the register that lists them (`null` where none does), the role, and the
517
+ ids of the schools the person is filed at. `roleEncoder` stores one as `personEncoder`'s
518
+ columns plus `id`, `role` and `schools`. Its levels are `nn0`-`nn4` and `id`, and `id` is
519
+ indexed. The name is re-read with `roleName`, so a print on a role's not-a-name list comes
520
+ back refused. `schools` is one column, and `roleSchoolGlob(school)` matches a row filed at
521
+ that school, the whole id and never a part of another:
522
+
523
+ ```ts
524
+ import { roleEncoder, roleSchoolGlob } from "@finbheara/domain/noun-index";
525
+ import { seatName, teacherName } from "@finbheara/domain/person";
526
+
527
+ const staff = createIndex(db, roleEncoder(), { table: "staff" }); // after its indexSchema
528
+ staff.add({ name: seatName("Aoife Ni Mhaolvarna"), id: "1001", role: "adjudicator", schools: ["s1", "s10"] }, 1);
529
+ staff.add({ name: teacherName("Kestrel Evbatyrov"), id: null, role: "teacher", schools: ["s10"] }, 2);
530
+
531
+ staff.find("id", "1001"); // [1]
532
+ staff.get({ name: teacherName("AOIFE NÍ MHAOLVARNA"), id: null, role: "teacher", schools: [] }, "nn3"); // [1]
533
+ staff.glob("schools", roleSchoolGlob("s10")).map((r) => r.value); // [1, 2]
534
+ staff.nouns(1)[0]?.schools; // ["s1", "s10"]
535
+ ```
536
+
515
537
  `rows({ column: keys, ... })` answers every row where any column holds one of its keys, and
516
538
  `glob(column, pattern)` a SQLite `GLOB` on one column. An encoder is a plain object: add a
517
539
  column of your own by spreading one, `{ ...enc, columns: [...enc.columns, "k"], encode: (x) =>
@@ -0,0 +1,122 @@
1
+ import {
2
+ SHARED_ROW_SENTINELS2,
3
+ sentinelIn2
4
+ } from "./place-tcgfvemw.js";
5
+
6
+ import {
7
+ NAME_REFUSED,
8
+ isNoNamePrint,
9
+ personName
10
+ } from "@finbheara/names/normalize";
11
+ var ADJUDICATOR_SENTINELS2 = [
12
+ {
13
+ print: "withdrawn adjudicator",
14
+ authority: "`Withdrawn Adjudicator`: 180 seat cells, one panel sheet's empty seat"
15
+ },
16
+ {
17
+ print: "no school judge",
18
+ authority: "`No School Judge`: an entry form's option for an adjudicator's entry"
19
+ }
20
+ ];
21
+ var DANCER_SENTINELS2 = [
22
+ {
23
+ print: "name withheld",
24
+ authority: "`Name Withheld`: 136 name cells, the entry platform printed that the name was withheld"
25
+ },
26
+ {
27
+ print: "test dancer",
28
+ authority: "`Test Dancer`: 7 name cells, an entry platform's test entry"
29
+ },
30
+ {
31
+ print: "none none",
32
+ authority: "`none none`: 4 name cells, the sentinel `none` typed into both name fields"
33
+ },
34
+ {
35
+ print: "not known",
36
+ authority: "`Not known`: 1 name cell"
37
+ },
38
+ {
39
+ print: "don t know",
40
+ authority: "`Don't Know`: 1 name cell"
41
+ }
42
+ ];
43
+ var TEACHER_SENTINELS2 = [];
44
+ var ROLE_SENTINELS2 = {
45
+ adjudicator: [...SHARED_ROW_SENTINELS2, ...ADJUDICATOR_SENTINELS2],
46
+ dancer: [...SHARED_ROW_SENTINELS2, ...DANCER_SENTINELS2],
47
+ teacher: [...SHARED_ROW_SENTINELS2, ...TEACHER_SENTINELS2]
48
+ };
49
+ var MATCHERS = {
50
+ adjudicator: sentinelIn2(ROLE_SENTINELS2.adjudicator),
51
+ dancer: sentinelIn2(ROLE_SENTINELS2.dancer),
52
+ teacher: sentinelIn2(ROLE_SENTINELS2.teacher)
53
+ };
54
+ function roleSentinelOf2(role, print) {
55
+ return MATCHERS[role](print);
56
+ }
57
+ var NO_PART = Object.freeze({ particles: [], base: "", parts: [], tradition: null });
58
+
59
+ class RoleRefusedName {
60
+ [Symbol.toStringTag] = "PersonName";
61
+ nn0;
62
+ nn1;
63
+ nn2 = NAME_REFUSED;
64
+ nn3 = NAME_REFUSED;
65
+ nn4 = NAME_REFUSED;
66
+ surname = NO_PART;
67
+ given = [];
68
+ suffixes = [];
69
+ refusal;
70
+ verdict;
71
+ role;
72
+ sentinel;
73
+ constructor(read, role, sentinel) {
74
+ this.role = role;
75
+ this.sentinel = sentinel;
76
+ this.nn0 = read.nn0;
77
+ this.nn1 = read.nn1;
78
+ this.refusal = { rule: "placeholder", printed: read.nn0, value: NAME_REFUSED };
79
+ this.verdict = { kind: "refused", refusal: this.refusal, rules: read.verdict.rules };
80
+ }
81
+ toString() {
82
+ return this.nn2;
83
+ }
84
+ get length() {
85
+ return this.nn2.length;
86
+ }
87
+ surnameKey() {
88
+ return "";
89
+ }
90
+ givenFields() {
91
+ return [];
92
+ }
93
+ givenName() {
94
+ return "";
95
+ }
96
+ isTeam() {
97
+ return false;
98
+ }
99
+ isPerson() {
100
+ return false;
101
+ }
102
+ isEmpty() {
103
+ return false;
104
+ }
105
+ printsNoName() {
106
+ return true;
107
+ }
108
+ }
109
+ function roleName2(role, print, order, factory) {
110
+ const read = factory === undefined ? personName(print, order) : factory.parse(print, order);
111
+ const sentinel = MATCHERS[role](print);
112
+ return sentinel === undefined ? read : new RoleRefusedName(read, role, sentinel);
113
+ }
114
+ function rolePrintsNoName2(role, print) {
115
+ return MATCHERS[role](print) !== undefined || isNoNamePrint(print);
116
+ }
117
+ var dancerPrintsNoName2 = (print) => rolePrintsNoName2("dancer", print);
118
+ var seatName2 = (print) => roleName2("adjudicator", print, "given-first");
119
+ var dancerName2 = (print, order, factory) => roleName2("dancer", print, order, factory);
120
+ var teacherName2 = (print, order) => roleName2("teacher", print, order);
121
+
122
+ export { ADJUDICATOR_SENTINELS2, DANCER_SENTINELS2, TEACHER_SENTINELS2, ROLE_SENTINELS2, roleSentinelOf2, roleName2, rolePrintsNoName2, dancerPrintsNoName2, seatName2, dancerName2, teacherName2 };
@@ -7422,6 +7422,7 @@ function genericKey2(folded) {
7422
7422
  var DEFAULT_PLACE_CAPACITY2 = 8192;
7423
7423
  var PLACE_CELL_SENTINELS = [...SHARED_ROW_SENTINELS2];
7424
7424
  var placeCellSentinelOf = sentinelIn2(PLACE_CELL_SENTINELS);
7425
+ var SHARED_INDEXES = new WeakMap;
7425
7426
  function createPlaceReader2(options = {}) {
7426
7427
  const nodes = options.tree ?? PLACE_NODES;
7427
7428
  const withinTable = options.within ?? PLACE_WITHIN;
@@ -7502,7 +7503,7 @@ function createPlaceReader2(options = {}) {
7502
7503
  const byRunPrint = new Map;
7503
7504
  const byGeneric = new Map;
7504
7505
  for (const n of source) {
7505
- if (generic && n.kind === "city")
7506
+ if (n.kind === "city")
7506
7507
  for (const p of [n.name, ...n.prints]) {
7507
7508
  const k = genericKey2(fold(p));
7508
7509
  if (k !== undefined)
@@ -7639,8 +7640,10 @@ function createPlaceReader2(options = {}) {
7639
7640
  };
7640
7641
  }
7641
7642
  function idx() {
7642
- if (index === undefined)
7643
- index = buildIndex(nodes);
7643
+ if (index !== undefined)
7644
+ return index;
7645
+ index = SHARED_INDEXES.get(nodes) ?? buildIndex(nodes);
7646
+ SHARED_INDEXES.set(nodes, index);
7644
7647
  return index;
7645
7648
  }
7646
7649
  function ancestorIds(n) {
package/dist/geocode.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  place2,
6
6
  placeFromId2,
7
7
  placeParts2
8
- } from "./chunks/place-k6y6fe1y.js";
8
+ } from "./chunks/place-zd6bq670.js";
9
9
 
10
10
  var PLACE_TOWNS = {
11
11
  "AUS-ACT": "Acton~~r3dp~9973368|Ainslie~~r3dp~8348552|Amaroo~~r3dp~8349331|Aranda~~r3dp~8349333|Banks~~r3dn~8348388|Barton~~r3dp~8349163|Belconnen~~r3dp~2176373|Bonner~~r3dp~9973375|Bonython~~r3dn~8349164|Braddon~~r3dp~8349165|Bruce~~r3dp~8349301|Calwell~~r3dn~8347865|Campbell~~r3dp~2172618|Canberra City~~r3dp~8347868|Casey~~r3dp~8349161~AU.07.21610|Chapman~~r39y~8349166|Charnwood~~r39z~8349169|Chifley~~r3dn~8348372|Chisholm~~r3dn~8349303|Conder~~r3dn~8349167|Cook~~r3dp~8347746~AU.04.32500|Coombs~~r39z~9973426|Crace~~r3dp~8349353|Curtin~~r3dp~8349171|Deakin~~r3dp~8349172|Dickson~~r3dp~8348400|Downer~~r3dp~8348308|Duffy~~r39y~8349425|Dunlop~~r39z~8349173|Evatt~~r3dp~8349175|Fadden~~r3dn~8348126|Farrer~~r3dn~8347869|Fisher~~r39y~8349304~CA.03.5953379|Florey~~r39z~8349174|Flynn~~r39z~8349305|Forde~~r3dp~8347874|Forrest~~r3dp~8504554|Franklin~~r3dp~8349306|Fraser~~r39z~8348647|Garran~~r3dn~9973428|Gilmore~~r3dn~8349400|Giralang~~r3dp~8348680|Gordon~~r3dn~8348660|Gowrie~~r3dn~8348892|Greenway~~r3dn~8349176|Griffith~~r3dp~8349307~AU.02.13450|Gungahlin~~r3dp~8349178|Hackett~~r3dp~8349180|Harrison~~r3dp~8349179|Hawker~~r39z~8349385|Higgins~~r39z~8349181|Holder~~r39y~8349308|Holt~~r39z~8347705|Hughes~~r3dn~8349446|Isaacs~~r3dn~8349182|Isabella Plains~~r3dn~8349183|Jacka~~r3dp~9973376|Jervis Bay Village~~r3g0~2162322|Kaleen~~r3dp~6619483|Kambah~~r39y~8348370|Kingston~~r3dp~8349299~~3489854|Latham~~r39z~8349309|Lyneham~~r3dp~8347876|Lyons~~r3dn~8349159|Macarthur~~r3dn~7302189|Macgregor~~r39z~8348907|Macquarie~~r3dp~7281844|Mawson~~r3dn~8348684|McKellar~~r3dp~8349184|Melba~~r39z~8349186|Monash~~r3dn~8349310~AU.07.24970|Narrabundah~~r3dn~8349435|Ngunnawal~~r3dp~8349187|Nicholls~~r3dp~8349185|O'Connor~~r3dp~8348190|O'Malley~~r3dn~8349436|Oxley~~r3dn~8349413|Page~~r39z~8348129|Palmerston~~r3dp~8349170~AU.03.72800|Pearce~~r3dn~8349379|Phillip~~r3dn~2153335|Red Hill~~r3dp~9973374|Reid~~r3dp~8348371|Richardson~~r3dn~8349188|Rivett~~r39y~8349189|Scullin~~r39z~8349327|Spence~~r3dp~8349313|Stirling~~r39y~8349380~AU.08.57910,CA.01.4802009,GB.SCT.W6|Symonston~~r3dn~8349190|Theodore~~r3dn~8348420~CA.11.4709028|Torrens~~r3dn~8348973|Tuggeranong~~r3dn~2145936|Turner~~r3dp~8348040|Wanniassa~~r3dn~8349191|Waramanga~~r39y~8349192|Watson~~r3dp~8348373~CA.11.4710062|Weetangera~~r39z~2144224|Weston~~r39y~8349397|Wright~~r39z~9973427|Yarralumla~~r3dp~8348374",
@@ -200,14 +200,19 @@ function townNodes() {
200
200
  }
201
201
  return out;
202
202
  }
203
+ var layerTree;
203
204
  var layer;
204
205
  var genericLayer;
206
+ function layerNodes() {
207
+ layerTree ??= [...PLACE_NODES, ...townNodes()];
208
+ return layerTree;
209
+ }
205
210
  function layerReader() {
206
- layer ??= createPlaceReader2({ tree: [...PLACE_NODES, ...townNodes()] });
211
+ layer ??= createPlaceReader2({ tree: layerNodes() });
207
212
  return layer;
208
213
  }
209
214
  function genericReader() {
210
- genericLayer ??= createPlaceReader2({ tree: [...PLACE_NODES, ...townNodes()], generic: true });
215
+ genericLayer ??= createPlaceReader2({ tree: layerNodes(), generic: true });
211
216
  return genericLayer;
212
217
  }
213
218
  function oneTown(t) {
@@ -1,3 +1,8 @@
1
+ import"./chunks/place-tcgfvemw.js";
2
+ import {
3
+ roleName2
4
+ } from "./chunks/place-4dkz48q6.js";
5
+
1
6
  import {
2
7
  NAME_COLUMNS,
3
8
  NAME_LEVEL_COLUMNS,
@@ -226,8 +231,61 @@ function personEncoder(options = {}) {
226
231
  }
227
232
  };
228
233
  }
234
+ var STAFF_ROLES = ["adjudicator", "teacher"];
235
+ function roleEncoder(options = {}) {
236
+ const read = options.read ?? ((role, p, o) => roleName2(role, p, o));
237
+ const named = (role) => personEncoder({
238
+ read: (p, o) => read(role, p, o),
239
+ print: options.print,
240
+ reading: options.reading
241
+ });
242
+ const names = {
243
+ adjudicator: named("adjudicator"),
244
+ teacher: named("teacher")
245
+ };
246
+ const roleOf = (r) => {
247
+ if (STAFF_ROLES.includes(r))
248
+ return r;
249
+ throw new Error(`roleEncoder: ${JSON.stringify(r)} is not a role`);
250
+ };
251
+ const base = names.teacher;
252
+ return {
253
+ columns: [...base.columns, "id", "role", "schools"],
254
+ levels: [...base.levels, "id"],
255
+ indexed: [...base.indexed, "id"],
256
+ encode(x) {
257
+ for (const s of x.schools)
258
+ if (typeof s !== "string" || s === "")
259
+ throw new Error(`roleEncoder: ${JSON.stringify(s)} is not a school id`);
260
+ return {
261
+ ...names[roleOf(x.role)].encode(x.name),
262
+ id: x.id,
263
+ role: x.role,
264
+ schools: x.schools.length === 0 ? null : JSON.stringify(x.schools)
265
+ };
266
+ },
267
+ key: (x, level) => level === "id" ? x.id : nameColumns(x.name)[level],
268
+ decode(row) {
269
+ const role = roleOf(row.role);
270
+ const schools = row.schools ?? null;
271
+ return {
272
+ name: names[role].decode(row),
273
+ id: row.id ?? null,
274
+ role,
275
+ schools: schools === null ? [] : JSON.parse(schools)
276
+ };
277
+ }
278
+ };
279
+ }
280
+ var globLiteral = (s) => s.replace(/[*?[]/gu, (c) => `[${c}]`);
281
+ function roleSchoolGlob(school) {
282
+ return `*[[,]${globLiteral(JSON.stringify(school))}[],]*`;
283
+ }
229
284
  export {
285
+ STAFF_ROLES,
230
286
  createIndex,
231
287
  indexSchema,
232
- personEncoder
288
+ personEncoder,
289
+ roleEncoder,
290
+ roleSchoolGlob
233
291
  };
package/dist/person.js CHANGED
@@ -1,135 +1,32 @@
1
+ import {
2
+ ADJUDICATOR_SENTINELS2,
3
+ DANCER_SENTINELS2,
4
+ TEACHER_SENTINELS2,
5
+ ROLE_SENTINELS2,
6
+ roleSentinelOf2,
7
+ roleName2,
8
+ rolePrintsNoName2,
9
+ dancerPrintsNoName2,
10
+ seatName2,
11
+ dancerName2,
12
+ teacherName2
13
+ } from "./chunks/place-4dkz48q6.js";
1
14
  import {
2
15
  SHARED_ROW_SENTINELS2,
3
16
  sentinelIn2
4
17
  } from "./chunks/place-tcgfvemw.js";
5
-
6
- import {
7
- NAME_REFUSED,
8
- isNoNamePrint,
9
- personName
10
- } from "@finbheara/names/normalize";
11
- var ADJUDICATOR_SENTINELS = [
12
- {
13
- print: "withdrawn adjudicator",
14
- authority: "`Withdrawn Adjudicator`: 180 seat cells, one panel sheet's empty seat"
15
- },
16
- {
17
- print: "no school judge",
18
- authority: "`No School Judge`: an entry form's option for an adjudicator's entry"
19
- }
20
- ];
21
- var DANCER_SENTINELS = [
22
- {
23
- print: "name withheld",
24
- authority: "`Name Withheld`: 136 name cells, the entry platform printed that the name was withheld"
25
- },
26
- {
27
- print: "test dancer",
28
- authority: "`Test Dancer`: 7 name cells, an entry platform's test entry"
29
- },
30
- {
31
- print: "none none",
32
- authority: "`none none`: 4 name cells, the sentinel `none` typed into both name fields"
33
- },
34
- {
35
- print: "not known",
36
- authority: "`Not known`: 1 name cell"
37
- },
38
- {
39
- print: "don t know",
40
- authority: "`Don't Know`: 1 name cell"
41
- }
42
- ];
43
- var TEACHER_SENTINELS = [];
44
- var ROLE_SENTINELS = {
45
- adjudicator: [...SHARED_ROW_SENTINELS2, ...ADJUDICATOR_SENTINELS],
46
- dancer: [...SHARED_ROW_SENTINELS2, ...DANCER_SENTINELS],
47
- teacher: [...SHARED_ROW_SENTINELS2, ...TEACHER_SENTINELS]
48
- };
49
- var MATCHERS = {
50
- adjudicator: sentinelIn2(ROLE_SENTINELS.adjudicator),
51
- dancer: sentinelIn2(ROLE_SENTINELS.dancer),
52
- teacher: sentinelIn2(ROLE_SENTINELS.teacher)
53
- };
54
- function roleSentinelOf(role, print) {
55
- return MATCHERS[role](print);
56
- }
57
- var NO_PART = Object.freeze({ particles: [], base: "", parts: [], tradition: null });
58
-
59
- class RoleRefusedName {
60
- [Symbol.toStringTag] = "PersonName";
61
- nn0;
62
- nn1;
63
- nn2 = NAME_REFUSED;
64
- nn3 = NAME_REFUSED;
65
- nn4 = NAME_REFUSED;
66
- surname = NO_PART;
67
- given = [];
68
- suffixes = [];
69
- refusal;
70
- verdict;
71
- role;
72
- sentinel;
73
- constructor(read, role, sentinel) {
74
- this.role = role;
75
- this.sentinel = sentinel;
76
- this.nn0 = read.nn0;
77
- this.nn1 = read.nn1;
78
- this.refusal = { rule: "placeholder", printed: read.nn0, value: NAME_REFUSED };
79
- this.verdict = { kind: "refused", refusal: this.refusal, rules: read.verdict.rules };
80
- }
81
- toString() {
82
- return this.nn2;
83
- }
84
- get length() {
85
- return this.nn2.length;
86
- }
87
- surnameKey() {
88
- return "";
89
- }
90
- givenFields() {
91
- return [];
92
- }
93
- givenName() {
94
- return "";
95
- }
96
- isTeam() {
97
- return false;
98
- }
99
- isPerson() {
100
- return false;
101
- }
102
- isEmpty() {
103
- return false;
104
- }
105
- printsNoName() {
106
- return true;
107
- }
108
- }
109
- function roleName(role, print, order, factory) {
110
- const read = factory === undefined ? personName(print, order) : factory.parse(print, order);
111
- const sentinel = MATCHERS[role](print);
112
- return sentinel === undefined ? read : new RoleRefusedName(read, role, sentinel);
113
- }
114
- function rolePrintsNoName(role, print) {
115
- return MATCHERS[role](print) !== undefined || isNoNamePrint(print);
116
- }
117
- var dancerPrintsNoName = (print) => rolePrintsNoName("dancer", print);
118
- var seatName = (print) => roleName("adjudicator", print, "given-first");
119
- var dancerName = (print, order, factory) => roleName("dancer", print, order, factory);
120
- var teacherName = (print, order) => roleName("teacher", print, order);
121
18
  export {
122
- ADJUDICATOR_SENTINELS,
123
- DANCER_SENTINELS,
124
- ROLE_SENTINELS,
19
+ ADJUDICATOR_SENTINELS2 as ADJUDICATOR_SENTINELS,
20
+ DANCER_SENTINELS2 as DANCER_SENTINELS,
21
+ ROLE_SENTINELS2 as ROLE_SENTINELS,
125
22
  SHARED_ROW_SENTINELS2 as SHARED_ROW_SENTINELS,
126
- TEACHER_SENTINELS,
127
- dancerName,
128
- dancerPrintsNoName,
129
- roleName,
130
- rolePrintsNoName,
131
- roleSentinelOf,
132
- seatName,
23
+ TEACHER_SENTINELS2 as TEACHER_SENTINELS,
24
+ dancerName2 as dancerName,
25
+ dancerPrintsNoName2 as dancerPrintsNoName,
26
+ roleName2 as roleName,
27
+ rolePrintsNoName2 as rolePrintsNoName,
28
+ roleSentinelOf2 as roleSentinelOf,
29
+ seatName2 as seatName,
133
30
  sentinelIn2 as sentinelIn,
134
- teacherName
31
+ teacherName2 as teacherName
135
32
  };
package/dist/place.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  placesRelation2,
20
20
  probablySamePlace2,
21
21
  sameReading2
22
- } from "./chunks/place-k6y6fe1y.js";
22
+ } from "./chunks/place-zd6bq670.js";
23
23
  import"./chunks/place-tcgfvemw.js";
24
24
  export {
25
25
  DEFAULT_PLACE_CAPACITY2 as DEFAULT_PLACE_CAPACITY,
package/dist/school.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  areAllPlaceTokens2,
13
13
  placeRelation2,
14
14
  sameReading2
15
- } from "./chunks/place-k6y6fe1y.js";
15
+ } from "./chunks/place-zd6bq670.js";
16
16
  import {
17
17
  validity
18
18
  } from "./chunks/place-q9kwsmzd.js";
@@ -1,4 +1,5 @@
1
1
  import { type PersonName, type ResolvedNameOrder, type TransitiveLevel } from "@finbheara/names/normalize";
2
+ import { type PersonRole } from "./person.ts";
2
3
  export type SqlValue = string | number | bigint | null;
3
4
  export interface SqlStatement {
4
5
  run(...params: SqlValue[]): unknown;
@@ -65,3 +66,20 @@ export interface PersonEncoderOptions {
65
66
  readonly reading?: string;
66
67
  }
67
68
  export declare function personEncoder(options?: PersonEncoderOptions): NounEncoder<PersonName, TransitiveLevel>;
69
+ export type StaffRole = Extract<PersonRole, "adjudicator" | "teacher">;
70
+ export declare const STAFF_ROLES: readonly StaffRole[];
71
+ export interface RolePerson {
72
+ readonly name: PersonName;
73
+ readonly id: string | null;
74
+ readonly role: StaffRole;
75
+ readonly schools: readonly string[];
76
+ }
77
+ export type RoleLevel = TransitiveLevel | "id";
78
+ export type RoleReader = (role: StaffRole, print: string, order: ResolvedNameOrder) => PersonName;
79
+ export interface RoleEncoderOptions {
80
+ readonly read?: RoleReader;
81
+ readonly print?: string;
82
+ readonly reading?: string;
83
+ }
84
+ export declare function roleEncoder(options?: RoleEncoderOptions): NounEncoder<RolePerson, RoleLevel>;
85
+ export declare function roleSchoolGlob(school: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finbheara/domain",
3
- "version": "0.39.0",
3
+ "version": "0.41.0",
4
4
  "description": "Places, CLRG regions, school names, ages, dances, competition titles and schedules, and a person's print in its role, as they are printed: read, compared and told apart",
5
5
  "keywords": [
6
6
  "places",