@heroiclands/package-build 23.7.0 → 23.7.1
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/CHANGELOG.md +13 -0
- package/docs/authoring/links-and-markup.md +215 -36
- package/docs/content-format.md +1 -1
- package/docs/reference/format-details.md +374 -211
- package/docs/reference/note-types.md +83 -27
- package/engine/content-format.yaml +3 -0
- package/engine/language-data.mjs +236 -1
- package/engine/language-rows.mjs +235 -3
- package/engine/language-terms.mjs +524 -9
- package/engine/language-words.mjs +75 -0
- package/engine/sql-tables.mjs +12 -2
- package/engine/word-rows.mjs +8 -3
- package/engine/word-terms.mjs +60 -2
- package/package.json +1 -1
- package/types/engine/language-rows.d.mts +89 -3
- package/types/engine/language-terms.d.mts +106 -4
- package/types/engine/word-rows.d.mts +2 -1
- package/types/engine/word-terms.d.mts +11 -0
package/engine/language-rows.mjs
CHANGED
|
@@ -33,6 +33,13 @@
|
|
|
33
33
|
* `elements` and `roots` — one row per entry, the list keys always lists;
|
|
34
34
|
* - `scope` — one row per value, with the `kind` of `data.scope` it is under;
|
|
35
35
|
* - `clusters` — one row per language stating `data.sounds.clusters`;
|
|
36
|
+
* - `cluster_groups` and `mutations` — one row per entry of
|
|
37
|
+
* `data.sounds.clusters.groups` and `data.sounds.mutations`;
|
|
38
|
+
* - `older` — one row per `data.older` entry;
|
|
39
|
+
* - `negation` — one row per language stating `data.negation`;
|
|
40
|
+
* - `name_shapes`, `name_edges`, `name_draws` and `held_from` — one row per
|
|
41
|
+
* entry of the lists of `data.naming`, and `near_names` one per worked
|
|
42
|
+
* near name, with the language's `min_syllables`;
|
|
36
43
|
* - `cognates` — one row per form of each set, with the set's `gloss`.
|
|
37
44
|
*
|
|
38
45
|
* @module
|
|
@@ -40,7 +47,9 @@
|
|
|
40
47
|
|
|
41
48
|
import { isLanguageRecord, noteAddressOf } from "./word-rows.mjs";
|
|
42
49
|
import {
|
|
50
|
+
ANY_NAME,
|
|
43
51
|
CALLING_CLOSING_KEYS,
|
|
52
|
+
CLUSTER_GROUP_KEYS,
|
|
44
53
|
EDGE_KEYS,
|
|
45
54
|
ELEMENT_KEYS,
|
|
46
55
|
FINAL_KEYS,
|
|
@@ -48,6 +57,8 @@ import {
|
|
|
48
57
|
JOIN_KEYS,
|
|
49
58
|
LETTER_KEYS,
|
|
50
59
|
MARK_KEYS,
|
|
60
|
+
MUTATION_KEYS,
|
|
61
|
+
OLDER_KEYS,
|
|
51
62
|
READ_PAST_KEYS,
|
|
52
63
|
REGISTER_KEYS,
|
|
53
64
|
RETIRED_KEYS,
|
|
@@ -86,6 +97,38 @@ export const LETTER_COLUMNS = Object.freeze([...IDENTITY, ...LETTER_KEYS]);
|
|
|
86
97
|
export const EDGE_COLUMNS = Object.freeze([...IDENTITY, ...EDGE_KEYS]);
|
|
87
98
|
/** Every column of the `clusters` relation, in order. */
|
|
88
99
|
export const CLUSTER_COLUMNS = Object.freeze(["language", "max"]);
|
|
100
|
+
/** Every column of the `cluster_groups` relation, in order. */
|
|
101
|
+
export const CLUSTER_GROUP_COLUMNS = Object.freeze([...IDENTITY, ...CLUSTER_GROUP_KEYS]);
|
|
102
|
+
/** Every column of the `mutations` relation, in order. */
|
|
103
|
+
export const MUTATION_COLUMNS = Object.freeze([...IDENTITY, ...MUTATION_KEYS]);
|
|
104
|
+
/** Every column of the `older` relation, in order. */
|
|
105
|
+
export const OLDER_COLUMNS = Object.freeze([...IDENTITY, ...OLDER_KEYS]);
|
|
106
|
+
/** Every column of the `name_shapes` relation, in order. */
|
|
107
|
+
export const NAME_SHAPE_COLUMNS = Object.freeze([
|
|
108
|
+
...IDENTITY,
|
|
109
|
+
"of",
|
|
110
|
+
"syllables_min",
|
|
111
|
+
"syllables_max",
|
|
112
|
+
"per_vowel_min",
|
|
113
|
+
"per_vowel_max",
|
|
114
|
+
]);
|
|
115
|
+
/** Every column of the `name_edges` relation, in order. */
|
|
116
|
+
export const NAME_EDGE_COLUMNS = Object.freeze([...IDENTITY, "edge", "sounds", "vowel", "of"]);
|
|
117
|
+
/** Every column of the `name_draws` relation, in order. */
|
|
118
|
+
export const NAME_DRAW_COLUMNS = Object.freeze([...IDENTITY, "kind", "elements"]);
|
|
119
|
+
/** Every column of the `held_from` relation, in order. */
|
|
120
|
+
export const HELD_FROM_COLUMNS = Object.freeze([
|
|
121
|
+
...IDENTITY,
|
|
122
|
+
"source",
|
|
123
|
+
"takes",
|
|
124
|
+
"clip",
|
|
125
|
+
"genitive",
|
|
126
|
+
"elements",
|
|
127
|
+
]);
|
|
128
|
+
/** Every column of the `near_names` relation, in order. */
|
|
129
|
+
export const NEAR_NAME_COLUMNS = Object.freeze([...IDENTITY, "near", "given", "min_syllables"]);
|
|
130
|
+
/** Every column of the `negation` relation, in order: one row per language. */
|
|
131
|
+
export const NEGATION_COLUMNS = Object.freeze(["language", "particle", "mutation"]);
|
|
89
132
|
/** Every column of the `stress` relation, in order. */
|
|
90
133
|
export const STRESS_COLUMNS = Object.freeze(["language", "stress"]);
|
|
91
134
|
/** Every column of the `finals` relation, in order. */
|
|
@@ -106,6 +149,7 @@ export const SYLLABLE_COLUMNS = Object.freeze([
|
|
|
106
149
|
"harmony_front",
|
|
107
150
|
"harmony_neutral",
|
|
108
151
|
"harmony_neutralAs",
|
|
152
|
+
"harmony_partners",
|
|
109
153
|
]);
|
|
110
154
|
/** Every column of the `joining` relation, in order. */
|
|
111
155
|
export const JOINING_COLUMNS = Object.freeze([...IDENTITY, ...JOINING_KEYS]);
|
|
@@ -132,6 +176,7 @@ export const SOUND_CHANGE_COLUMNS = Object.freeze([
|
|
|
132
176
|
"name",
|
|
133
177
|
"from_language",
|
|
134
178
|
"to_language",
|
|
179
|
+
"takes",
|
|
135
180
|
"step_position",
|
|
136
181
|
...SOUND_CHANGE_STEP_KEYS,
|
|
137
182
|
]);
|
|
@@ -174,6 +219,21 @@ export const LANGUAGE_COLUMN_TYPES = Object.freeze({
|
|
|
174
219
|
letters: { position: "BIGINT", letters: LIST, tongue: LIST },
|
|
175
220
|
edges: { position: "BIGINT", sounds: LIST },
|
|
176
221
|
clusters: { max: "BIGINT" },
|
|
222
|
+
cluster_groups: { position: "BIGINT", clusters: LIST },
|
|
223
|
+
mutations: { position: "BIGINT" },
|
|
224
|
+
older: { position: "BIGINT" },
|
|
225
|
+
negation: {},
|
|
226
|
+
name_shapes: {
|
|
227
|
+
position: "BIGINT",
|
|
228
|
+
syllables_min: "BIGINT",
|
|
229
|
+
syllables_max: "BIGINT",
|
|
230
|
+
per_vowel_min: "DOUBLE",
|
|
231
|
+
per_vowel_max: "DOUBLE",
|
|
232
|
+
},
|
|
233
|
+
name_edges: { position: "BIGINT", sounds: LIST, vowel: "BOOLEAN" },
|
|
234
|
+
name_draws: { position: "BIGINT", elements: LIST },
|
|
235
|
+
held_from: { position: "BIGINT", genitive: LIST, elements: LIST },
|
|
236
|
+
near_names: { position: "BIGINT", min_syllables: "BIGINT" },
|
|
177
237
|
stress: {},
|
|
178
238
|
finals: { position: "BIGINT" },
|
|
179
239
|
syllables: {
|
|
@@ -188,6 +248,7 @@ export const LANGUAGE_COLUMN_TYPES = Object.freeze({
|
|
|
188
248
|
harmony_back: LIST,
|
|
189
249
|
harmony_front: LIST,
|
|
190
250
|
harmony_neutral: LIST,
|
|
251
|
+
harmony_partners: "STRUCT(vowel VARCHAR, partner VARCHAR)[]",
|
|
191
252
|
},
|
|
192
253
|
joining: { position: "BIGINT", first: LIST, second: LIST },
|
|
193
254
|
joins: { position: "BIGINT", letters: LIST },
|
|
@@ -470,6 +531,159 @@ export function clusterRows(records) {
|
|
|
470
531
|
return rows;
|
|
471
532
|
}
|
|
472
533
|
|
|
534
|
+
/**
|
|
535
|
+
* The `cluster_groups` rows: one per `data.sounds.clusters.groups` entry,
|
|
536
|
+
* `clusters` a list.
|
|
537
|
+
*
|
|
538
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
539
|
+
* @returns {object[]}
|
|
540
|
+
*/
|
|
541
|
+
export function clusterGroupRows(records) {
|
|
542
|
+
return listRows(records, (data) => soundsOf(data).clusters?.groups, CLUSTER_GROUP_KEYS, {
|
|
543
|
+
lists: ["clusters"],
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* The `mutations` rows: one per `data.sounds.mutations` entry.
|
|
549
|
+
*
|
|
550
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
551
|
+
* @returns {object[]}
|
|
552
|
+
*/
|
|
553
|
+
export function mutationRows(records) {
|
|
554
|
+
return listRows(records, (data) => soundsOf(data).mutations, MUTATION_KEYS);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* The `older` rows: one per `data.older` entry.
|
|
559
|
+
*
|
|
560
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
561
|
+
* @returns {object[]}
|
|
562
|
+
*/
|
|
563
|
+
export function olderRows(records) {
|
|
564
|
+
return listRows(records, (data) => data.older, OLDER_KEYS);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* The `negation` rows: one per language stating `data.negation`.
|
|
569
|
+
*
|
|
570
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
571
|
+
* @returns {object[]}
|
|
572
|
+
*/
|
|
573
|
+
export function negationRows(records) {
|
|
574
|
+
const rows = [];
|
|
575
|
+
for (const [language, record] of languagesOf(records)) {
|
|
576
|
+
const negation = record.data?.negation;
|
|
577
|
+
if (isMap(negation))
|
|
578
|
+
rows.push({
|
|
579
|
+
language,
|
|
580
|
+
particle: negation.particle ?? null,
|
|
581
|
+
mutation: negation.mutation ?? null,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
return rows;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/** A language's `data.naming`, or an empty map. */
|
|
588
|
+
const namingOf = (data) => (isMap(data.naming) ? data.naming : {});
|
|
589
|
+
|
|
590
|
+
/** A range's bound, or `null`. */
|
|
591
|
+
const bound = (range, key) => (isMap(range) && typeof range[key] === "number" ? range[key] : null);
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* The `name_shapes` rows: one per `data.naming.shapes` entry, each range as
|
|
595
|
+
* its two bounds.
|
|
596
|
+
*
|
|
597
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
598
|
+
* @returns {object[]}
|
|
599
|
+
*/
|
|
600
|
+
export function nameShapeRows(records) {
|
|
601
|
+
const rows = [];
|
|
602
|
+
for (const [language, record] of languagesOf(records)) {
|
|
603
|
+
const shapes = namingOf(isMap(record.data) ? record.data : {}).shapes;
|
|
604
|
+
if (!Array.isArray(shapes)) continue;
|
|
605
|
+
shapes.forEach((shape, position) => {
|
|
606
|
+
if (!isMap(shape)) return;
|
|
607
|
+
rows.push({
|
|
608
|
+
language,
|
|
609
|
+
position,
|
|
610
|
+
of: shape.of ?? null,
|
|
611
|
+
syllables_min: bound(shape.syllables, "min"),
|
|
612
|
+
syllables_max: bound(shape.syllables, "max"),
|
|
613
|
+
per_vowel_min: bound(shape.perVowel, "min"),
|
|
614
|
+
per_vowel_max: bound(shape.perVowel, "max"),
|
|
615
|
+
});
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
return rows;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* The `name_edges` rows: one per `data.naming.edges` entry, `sounds` a list,
|
|
623
|
+
* `vowel` `false` and `of` `name` where unstated.
|
|
624
|
+
*
|
|
625
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
626
|
+
* @returns {object[]}
|
|
627
|
+
*/
|
|
628
|
+
export function nameEdgeRows(records) {
|
|
629
|
+
return listRows(records, (data) => namingOf(data).edges, ["edge", "sounds", "vowel", "of"], {
|
|
630
|
+
lists: ["sounds"],
|
|
631
|
+
}).map((row) => ({ ...row, vowel: row.vowel === true, of: row.of ?? ANY_NAME }));
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* The `name_draws` rows: one per `data.naming.draws` entry.
|
|
636
|
+
*
|
|
637
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
638
|
+
* @returns {object[]}
|
|
639
|
+
*/
|
|
640
|
+
export function nameDrawRows(records) {
|
|
641
|
+
return listRows(records, (data) => namingOf(data).draws, ["kind", "elements"], {
|
|
642
|
+
lists: ["elements"],
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* The `held_from` rows: one per `data.naming.heldFrom` entry.
|
|
648
|
+
*
|
|
649
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
650
|
+
* @returns {object[]}
|
|
651
|
+
*/
|
|
652
|
+
export function heldFromRows(records) {
|
|
653
|
+
return listRows(
|
|
654
|
+
records,
|
|
655
|
+
(data) => namingOf(data).heldFrom,
|
|
656
|
+
["source", "takes", "clip", "genitive", "elements"],
|
|
657
|
+
{ lists: ["genitive", "elements"] },
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* The `near_names` rows: one per worked example of `data.naming.nearName`,
|
|
663
|
+
* each with the language's `min_syllables`.
|
|
664
|
+
*
|
|
665
|
+
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
666
|
+
* @returns {object[]}
|
|
667
|
+
*/
|
|
668
|
+
export function nearNameRows(records) {
|
|
669
|
+
const rows = [];
|
|
670
|
+
for (const [language, record] of languagesOf(records)) {
|
|
671
|
+
const near = namingOf(isMap(record.data) ? record.data : {}).nearName;
|
|
672
|
+
if (!isMap(near) || !Array.isArray(near.examples)) continue;
|
|
673
|
+
near.examples.forEach((example, position) => {
|
|
674
|
+
if (!isMap(example)) return;
|
|
675
|
+
rows.push({
|
|
676
|
+
language,
|
|
677
|
+
position,
|
|
678
|
+
near: example.near ?? null,
|
|
679
|
+
given: example.given ?? null,
|
|
680
|
+
min_syllables: near.minSyllables ?? null,
|
|
681
|
+
});
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
return rows;
|
|
685
|
+
}
|
|
686
|
+
|
|
473
687
|
/**
|
|
474
688
|
* The `read_past` rows: one per `data.sounds.readPast` entry.
|
|
475
689
|
*
|
|
@@ -482,8 +696,8 @@ export function readPastRows(records) {
|
|
|
482
696
|
|
|
483
697
|
/**
|
|
484
698
|
* The `sound_changes` rows: one per step of each `data.soundChanges` set, with
|
|
485
|
-
* the set's `position`, `name`, `from_language` and `
|
|
486
|
-
* step's `step_position` within it.
|
|
699
|
+
* the set's `position`, `name`, `from_language`, `to_language` and `takes`,
|
|
700
|
+
* and the step's `step_position` within it.
|
|
487
701
|
*
|
|
488
702
|
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
489
703
|
* @returns {object[]}
|
|
@@ -503,6 +717,7 @@ export function soundChangeRows(records) {
|
|
|
503
717
|
name: set.name ?? null,
|
|
504
718
|
from_language: set.from ?? null,
|
|
505
719
|
to_language: set.to ?? null,
|
|
720
|
+
takes: set.takes ?? null,
|
|
506
721
|
step_position: stepPosition,
|
|
507
722
|
};
|
|
508
723
|
for (const key of SOUND_CHANGE_STEP_KEYS) row[key] = step[key] ?? null;
|
|
@@ -592,7 +807,8 @@ export function finalRows(records) {
|
|
|
592
807
|
/**
|
|
593
808
|
* The `syllables` rows: one per language stating `data.sounds.syllables`, a
|
|
594
809
|
* list rule always a list (`any` a list of one), the harmony's sets each a
|
|
595
|
-
* column of its own
|
|
810
|
+
* column of its own, its partners a list of `{ vowel, partner }` in the order
|
|
811
|
+
* stated.
|
|
596
812
|
*
|
|
597
813
|
* @param {Iterable<Record<string, any>>} records - Index records.
|
|
598
814
|
* @returns {object[]}
|
|
@@ -618,6 +834,13 @@ export function syllableRows(records) {
|
|
|
618
834
|
harmony_front: asList(harmony.front),
|
|
619
835
|
harmony_neutral: asList(harmony.neutral),
|
|
620
836
|
harmony_neutralAs: harmony.neutralAs ?? null,
|
|
837
|
+
harmony_partners:
|
|
838
|
+
isMap(harmony.partners) && Object.keys(harmony.partners).length ?
|
|
839
|
+
Object.entries(harmony.partners).map(([vowel, partner]) => ({
|
|
840
|
+
vowel,
|
|
841
|
+
partner: partner == null ? null : String(partner),
|
|
842
|
+
}))
|
|
843
|
+
: null,
|
|
621
844
|
});
|
|
622
845
|
}
|
|
623
846
|
return rows;
|
|
@@ -744,6 +967,8 @@ export const LANGUAGE_RELATIONS = Object.freeze([
|
|
|
744
967
|
["letters", letterRows, LETTER_COLUMNS],
|
|
745
968
|
["edges", edgeRows, EDGE_COLUMNS],
|
|
746
969
|
["clusters", clusterRows, CLUSTER_COLUMNS],
|
|
970
|
+
["cluster_groups", clusterGroupRows, CLUSTER_GROUP_COLUMNS],
|
|
971
|
+
["mutations", mutationRows, MUTATION_COLUMNS],
|
|
747
972
|
["stress", stressRows, STRESS_COLUMNS],
|
|
748
973
|
["finals", finalRows, FINAL_COLUMNS],
|
|
749
974
|
["syllables", syllableRows, SYLLABLE_COLUMNS],
|
|
@@ -758,4 +983,11 @@ export const LANGUAGE_RELATIONS = Object.freeze([
|
|
|
758
983
|
["roots", rootRows, ROOT_COLUMNS],
|
|
759
984
|
["cognates", cognateRows, COGNATE_COLUMNS],
|
|
760
985
|
["calling_names", callingNameRows, CALLING_NAME_COLUMNS],
|
|
986
|
+
["older", olderRows, OLDER_COLUMNS],
|
|
987
|
+
["negation", negationRows, NEGATION_COLUMNS],
|
|
988
|
+
["name_shapes", nameShapeRows, NAME_SHAPE_COLUMNS],
|
|
989
|
+
["name_edges", nameEdgeRows, NAME_EDGE_COLUMNS],
|
|
990
|
+
["name_draws", nameDrawRows, NAME_DRAW_COLUMNS],
|
|
991
|
+
["held_from", heldFromRows, HELD_FROM_COLUMNS],
|
|
992
|
+
["near_names", nearNameRows, NEAR_NAME_COLUMNS],
|
|
761
993
|
]);
|