@mailwoman/geographic-model 10.0.0 → 10.2.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 +32 -32
- package/data/geographic-model.json +5 -5
- package/data/model/concepts.json +5 -5
- package/lib/artifact.ts +37 -65
- package/lib/compile.ts +55 -70
- package/lib/index.ts +22 -35
- package/lib/load.ts +60 -72
- package/lib/lookup.ts +12 -28
- package/lib/packaged.ts +50 -0
- package/lib/schema.ts +104 -97
- package/lib/validate.ts +32 -56
- package/lib/validation/issues.ts +32 -36
- package/lib/validation/references.ts +24 -27
- package/out/artifact.d.ts +28 -45
- package/out/artifact.d.ts.map +1 -1
- package/out/artifact.js +25 -52
- package/out/artifact.js.map +1 -1
- package/out/compile.d.ts +27 -41
- package/out/compile.d.ts.map +1 -1
- package/out/compile.js +42 -64
- package/out/compile.js.map +1 -1
- package/out/index.d.ts +22 -35
- package/out/index.d.ts.map +1 -1
- package/out/index.js +22 -35
- package/out/index.js.map +1 -1
- package/out/load.d.ts +30 -39
- package/out/load.d.ts.map +1 -1
- package/out/load.js +42 -56
- package/out/load.js.map +1 -1
- package/out/lookup.d.ts +12 -28
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +4 -16
- package/out/lookup.js.map +1 -1
- package/out/packaged.d.ts +24 -0
- package/out/packaged.d.ts.map +1 -0
- package/out/packaged.js +42 -0
- package/out/packaged.js.map +1 -0
- package/out/schema.d.ts +104 -97
- package/out/schema.d.ts.map +1 -1
- package/out/schema.js +37 -52
- package/out/schema.js.map +1 -1
- package/out/tools/build-artifact.d.ts +27 -0
- package/out/tools/build-artifact.d.ts.map +1 -0
- package/out/tools/build-artifact.js +44 -0
- package/out/tools/build-artifact.js.map +1 -0
- package/out/validate.d.ts +29 -50
- package/out/validate.d.ts.map +1 -1
- package/out/validate.js +12 -35
- package/out/validate.js.map +1 -1
- package/out/validation/issues.d.ts +17 -20
- package/out/validation/issues.d.ts.map +1 -1
- package/out/validation/issues.js +25 -29
- package/out/validation/issues.js.map +1 -1
- package/out/validation/references.d.ts.map +1 -1
- package/out/validation/references.js +20 -23
- package/out/validation/references.js.map +1 -1
- package/package.json +35 -76
- package/tools/build-artifact.ts +56 -0
- package/out/scripts/build-artifact.d.ts +0 -51
- package/out/scripts/build-artifact.d.ts.map +0 -1
- package/out/scripts/build-artifact.js +0 -85
- package/out/scripts/build-artifact.js.map +0 -1
package/out/load.d.ts
CHANGED
|
@@ -3,36 +3,26 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Loads a directory of JSON files into one {@link GeographicModelDocument}.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* directory does carry is one manifest — `model.json`, holding the document's `version` — because a
|
|
11
|
-
* version assembled from whichever fragment happened to declare one is a version nobody chose.
|
|
8
|
+
* File layout does not assign meaning to a file. Any file may hold any subset of the tables.
|
|
9
|
+
* Only `model.json` may declare the document's `version`.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
11
|
+
* The loader sorts files by path before reading them, so directory enumeration order never affects
|
|
12
|
+
* the output. It records the source file of every record and maps each validation issue back to that
|
|
13
|
+
* file. A duplicate-identifier issue also reports the file that used the identifier first.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* NAMES and their contents. `readdir` order, and therefore the filesystem, is out of the answer.
|
|
18
|
-
* 2. **Every issue names the file it came from.** The document validator addresses a record by its
|
|
19
|
-
* position in the merged table (`$.concepts[7].kind`), which is the one thing an author cannot
|
|
20
|
-
* see; the loader keeps a per-record origin and re-addresses each issue to its source file. A
|
|
21
|
-
* duplicate identifier names both files — the one that claimed it and the one that claimed it
|
|
22
|
-
* first — because "already used" is unactionable without the other half.
|
|
23
|
-
*
|
|
24
|
-
* Validation itself is delegated whole to `./validate.ts`. What the loader checks on its own is only
|
|
25
|
-
* what the validator cannot see: whether a file parses, whether it is an object, and whether the
|
|
26
|
-
* keys it uses are tables.
|
|
15
|
+
* `./validate.ts` performs document validation. The loader checks only that each file parses, holds
|
|
16
|
+
* an object and uses known table keys.
|
|
27
17
|
*/
|
|
28
18
|
import type { GeographicModelDocument } from "#schema";
|
|
29
19
|
/**
|
|
30
|
-
* The manifest every model directory
|
|
20
|
+
* The manifest file that every model directory contains.
|
|
21
|
+
* It holds only the document's `version`.
|
|
31
22
|
*/
|
|
32
23
|
export declare const MODEL_MANIFEST_FILENAME = "model.json";
|
|
33
24
|
/**
|
|
34
|
-
*
|
|
35
|
-
* file that is not JSON at all.
|
|
25
|
+
* Load issue codes: every validation code plus `MalformedJSON`.
|
|
36
26
|
*/
|
|
37
27
|
export declare const LoadIssueCode: {
|
|
38
28
|
readonly MissingField: "missing_field";
|
|
@@ -60,63 +50,64 @@ export declare const LoadIssueCode: {
|
|
|
60
50
|
readonly TransitiveKindsDisjoint: "transitive_kinds_disjoint";
|
|
61
51
|
readonly MalformedCountry: "malformed_country";
|
|
62
52
|
/**
|
|
63
|
-
* A source file
|
|
64
|
-
* never text.
|
|
53
|
+
* A source file is not valid JSON.
|
|
65
54
|
*/
|
|
66
55
|
readonly MalformedJSON: "malformed_json";
|
|
67
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* A {@link LoadIssueCode} value.
|
|
59
|
+
*/
|
|
68
60
|
export type LoadIssueCode = (typeof LoadIssueCode)[keyof typeof LoadIssueCode];
|
|
69
61
|
/**
|
|
70
|
-
* One
|
|
62
|
+
* One load issue, attributed to its source file.
|
|
71
63
|
*/
|
|
72
64
|
export interface SourcedIssue {
|
|
73
65
|
/**
|
|
74
|
-
* The source file
|
|
66
|
+
* The source file path relative to the model directory, with `/` separators on every platform.
|
|
75
67
|
*/
|
|
76
68
|
file: string;
|
|
77
69
|
/**
|
|
78
|
-
* The JSONPath-style
|
|
79
|
-
* validator saw.
|
|
70
|
+
* The JSONPath-style location in the merged document.
|
|
80
71
|
*/
|
|
81
72
|
path: string;
|
|
82
73
|
code: LoadIssueCode;
|
|
83
74
|
message: string;
|
|
84
75
|
/**
|
|
85
|
-
* For a duplicate identifier
|
|
76
|
+
* For a duplicate identifier, the file that used the identifier first.
|
|
86
77
|
*/
|
|
87
|
-
otherFile
|
|
78
|
+
otherFile: string | null;
|
|
88
79
|
}
|
|
89
80
|
/**
|
|
90
|
-
*
|
|
81
|
+
* A source file's path relative to the model directory, plus its text.
|
|
91
82
|
*/
|
|
92
83
|
export interface GeographicModelSourceFile {
|
|
93
84
|
path: string;
|
|
94
85
|
text: string;
|
|
95
86
|
}
|
|
96
87
|
/**
|
|
97
|
-
*
|
|
88
|
+
* Formats each issue as one `file:path: message [code]` line, in input order.
|
|
98
89
|
*/
|
|
99
90
|
export declare function formatSourcedIssues(issues: readonly SourcedIssue[]): string;
|
|
100
91
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
92
|
+
* The error thrown when a model directory does not load.
|
|
93
|
+
* Its message lists every issue.
|
|
103
94
|
*/
|
|
104
95
|
export declare class GeographicModelLoadError extends Error {
|
|
105
96
|
readonly issues: readonly SourcedIssue[];
|
|
106
97
|
constructor(issues: readonly SourcedIssue[]);
|
|
107
98
|
}
|
|
108
99
|
/**
|
|
109
|
-
*
|
|
100
|
+
* Merges source files into one document and validates it.
|
|
101
|
+
*
|
|
102
|
+
* The function sorts files by path first, so the input order never affects the result.
|
|
110
103
|
*
|
|
111
|
-
*
|
|
112
|
-
* order. Throws {@link GeographicModelLoadError} with every issue, each addressed to its source file; returns nothing
|
|
113
|
-
* partial.
|
|
104
|
+
* @throws {GeographicModelLoadError} With every issue, each attributed to its source file.
|
|
114
105
|
*/
|
|
115
106
|
export declare function mergeGeographicModelFiles(files: readonly GeographicModelSourceFile[]): GeographicModelDocument;
|
|
116
107
|
/**
|
|
117
|
-
*
|
|
108
|
+
* Reads every `*.json` file under `root`, merges the files and validates the merged document.
|
|
118
109
|
*
|
|
119
|
-
*
|
|
110
|
+
* @throws {GeographicModelLoadError} With every issue, each attributed to its source file.
|
|
120
111
|
*/
|
|
121
112
|
export declare function loadGeographicModelDirectory(root: string): Promise<GeographicModelDocument>;
|
|
122
113
|
//# sourceMappingURL=load.d.ts.map
|
package/out/load.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../lib/load.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../lib/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAUtD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,eAAe,CAAA;AAiBnD;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;IAEzB;;OAEG;4BACY,gBAAgB;CACtB,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,CAAA;AAE9E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,aAAa,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAQ3E;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IAExC,YAAY,MAAM,EAAE,SAAS,YAAY,EAAE,EAK1C;CACD;AAwKD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,yBAAyB,EAAE,GAAG,uBAAuB,CA8C9G;AAiCD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CASjG"}
|
package/out/load.js
CHANGED
|
@@ -3,27 +3,17 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Loads a directory of JSON files into one {@link GeographicModelDocument}.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* directory does carry is one manifest — `model.json`, holding the document's `version` — because a
|
|
11
|
-
* version assembled from whichever fragment happened to declare one is a version nobody chose.
|
|
8
|
+
* File layout does not assign meaning to a file. Any file may hold any subset of the tables.
|
|
9
|
+
* Only `model.json` may declare the document's `version`.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
11
|
+
* The loader sorts files by path before reading them, so directory enumeration order never affects
|
|
12
|
+
* the output. It records the source file of every record and maps each validation issue back to that
|
|
13
|
+
* file. A duplicate-identifier issue also reports the file that used the identifier first.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* NAMES and their contents. `readdir` order, and therefore the filesystem, is out of the answer.
|
|
18
|
-
* 2. **Every issue names the file it came from.** The document validator addresses a record by its
|
|
19
|
-
* position in the merged table (`$.concepts[7].kind`), which is the one thing an author cannot
|
|
20
|
-
* see; the loader keeps a per-record origin and re-addresses each issue to its source file. A
|
|
21
|
-
* duplicate identifier names both files — the one that claimed it and the one that claimed it
|
|
22
|
-
* first — because "already used" is unactionable without the other half.
|
|
23
|
-
*
|
|
24
|
-
* Validation itself is delegated whole to `./validate.ts`. What the loader checks on its own is only
|
|
25
|
-
* what the validator cannot see: whether a file parses, whether it is an object, and whether the
|
|
26
|
-
* keys it uses are tables.
|
|
15
|
+
* `./validate.ts` performs document validation. The loader checks only that each file parses, holds
|
|
16
|
+
* an object and uses known table keys.
|
|
27
17
|
*/
|
|
28
18
|
import { readLocalTextFile } from "@mailwoman/core/fs/readers";
|
|
29
19
|
import { isPlainObject } from "@mailwoman/core/objects";
|
|
@@ -33,33 +23,32 @@ import { Globerator } from "spliterator/node/fs";
|
|
|
33
23
|
import { validateGeographicModelDocument } from "#validate";
|
|
34
24
|
import { add, checkFieldNames, readArray, readString, ValidationIssueCode, } from "#validation/issues";
|
|
35
25
|
/**
|
|
36
|
-
* The manifest every model directory
|
|
26
|
+
* The manifest file that every model directory contains.
|
|
27
|
+
* It holds only the document's `version`.
|
|
37
28
|
*/
|
|
38
29
|
export const MODEL_MANIFEST_FILENAME = "model.json";
|
|
39
30
|
/**
|
|
40
|
-
* The keys a source file may use.
|
|
31
|
+
* The table keys that a non-manifest source file may use.
|
|
41
32
|
*/
|
|
42
33
|
const TABLE_FIELDS = ["relations", "concepts", "mappings", "observations", "derivedFacts"];
|
|
43
34
|
const MANIFEST_FIELDS = ["version"];
|
|
44
35
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
36
|
+
* Matches a record's path in the merged document, such as `$.concepts[7]` or `$.concepts[7].assertions[1]`.
|
|
37
|
+
* Group 3 matches only for a nested assertion.
|
|
47
38
|
*/
|
|
48
39
|
const RECORD_PATH_PATTERN = /^\$\.([A-Za-z]+)\[(\d+)\](?:\.assertions\[(\d+)\])?/u;
|
|
49
40
|
/**
|
|
50
|
-
*
|
|
51
|
-
* file that is not JSON at all.
|
|
41
|
+
* Load issue codes: every validation code plus `MalformedJSON`.
|
|
52
42
|
*/
|
|
53
43
|
export const LoadIssueCode = {
|
|
54
44
|
...ValidationIssueCode,
|
|
55
45
|
/**
|
|
56
|
-
* A source file
|
|
57
|
-
* never text.
|
|
46
|
+
* A source file is not valid JSON.
|
|
58
47
|
*/
|
|
59
48
|
MalformedJSON: "malformed_json",
|
|
60
49
|
};
|
|
61
50
|
/**
|
|
62
|
-
*
|
|
51
|
+
* Formats each issue as one `file:path: message [code]` line, in input order.
|
|
63
52
|
*/
|
|
64
53
|
export function formatSourcedIssues(issues) {
|
|
65
54
|
return issues
|
|
@@ -70,8 +59,8 @@ export function formatSourcedIssues(issues) {
|
|
|
70
59
|
.join("\n");
|
|
71
60
|
}
|
|
72
61
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
62
|
+
* The error thrown when a model directory does not load.
|
|
63
|
+
* Its message lists every issue.
|
|
75
64
|
*/
|
|
76
65
|
export class GeographicModelLoadError extends Error {
|
|
77
66
|
issues;
|
|
@@ -82,14 +71,12 @@ export class GeographicModelLoadError extends Error {
|
|
|
82
71
|
}
|
|
83
72
|
}
|
|
84
73
|
function sourced(file, issues) {
|
|
85
|
-
return issues.map((issue) => ({ file, path: issue.path, code: issue.code, message: issue.message }));
|
|
74
|
+
return issues.map((issue) => ({ file, path: issue.path, code: issue.code, message: issue.message, otherFile: null }));
|
|
86
75
|
}
|
|
87
76
|
/**
|
|
88
|
-
*
|
|
77
|
+
* Parses one source file, or records the parse failure and returns `undefined`.
|
|
89
78
|
*
|
|
90
|
-
* The
|
|
91
|
-
* boundary record keeps world semantics out of core, and a build-time loader is not the reason to reverse it. The
|
|
92
|
-
* parser's own message is also the useful half of the report here, which a wrapper returning a fallback discards.
|
|
79
|
+
* The loader calls `JSON.parse` directly because the report needs the parser's error message.
|
|
93
80
|
*/
|
|
94
81
|
function readSourceJSON(file, issues) {
|
|
95
82
|
try {
|
|
@@ -102,12 +89,13 @@ function readSourceJSON(file, issues) {
|
|
|
102
89
|
path: "$",
|
|
103
90
|
code: LoadIssueCode.MalformedJSON,
|
|
104
91
|
message: error instanceof Error ? error.message : String(error),
|
|
92
|
+
otherFile: null,
|
|
105
93
|
});
|
|
106
94
|
return undefined;
|
|
107
95
|
}
|
|
108
96
|
}
|
|
109
97
|
function claim(state, table, id, file) {
|
|
110
|
-
if (id
|
|
98
|
+
if (!id)
|
|
111
99
|
return;
|
|
112
100
|
const claims = state.firstClaims.get(table) ?? new Map();
|
|
113
101
|
state.firstClaims.set(table, claims);
|
|
@@ -117,8 +105,8 @@ function claim(state, table, id, file) {
|
|
|
117
105
|
}
|
|
118
106
|
function recordID(entry) {
|
|
119
107
|
if (!isPlainObject(entry))
|
|
120
|
-
return
|
|
121
|
-
return typeof entry.id === "string" ? entry.id :
|
|
108
|
+
return null;
|
|
109
|
+
return typeof entry.id === "string" ? entry.id : null;
|
|
122
110
|
}
|
|
123
111
|
function readManifestFile(state, file, value) {
|
|
124
112
|
const issues = [];
|
|
@@ -132,7 +120,7 @@ function readManifestFile(state, file, value) {
|
|
|
132
120
|
state.issues.push(...sourced(file.path, issues));
|
|
133
121
|
}
|
|
134
122
|
/**
|
|
135
|
-
*
|
|
123
|
+
* Appends one file's tables to the merged document and records each record's origin.
|
|
136
124
|
*/
|
|
137
125
|
function readTableFile(state, file, value) {
|
|
138
126
|
const issues = [];
|
|
@@ -141,8 +129,7 @@ function readTableFile(state, file, value) {
|
|
|
141
129
|
state.issues.push(...sourced(file.path, issues));
|
|
142
130
|
return;
|
|
143
131
|
}
|
|
144
|
-
//
|
|
145
|
-
// instead of only saying the field is unknown here.
|
|
132
|
+
// The field check allows `version` so that the specific error below can say where it belongs.
|
|
146
133
|
checkFieldNames(issues, "$", value, [...TABLE_FIELDS, ...MANIFEST_FIELDS]);
|
|
147
134
|
if ("version" in value) {
|
|
148
135
|
add(issues, "$.version", ValidationIssueCode.UnknownField, `the document's \`version\` is authored in \`${MODEL_MANIFEST_FILENAME}\`, not in a table file`);
|
|
@@ -173,33 +160,32 @@ function readTableFile(state, file, value) {
|
|
|
173
160
|
state.issues.push(...sourced(file.path, issues));
|
|
174
161
|
}
|
|
175
162
|
/**
|
|
176
|
-
*
|
|
163
|
+
* Attributes one validation issue to the file that contains the record.
|
|
177
164
|
*/
|
|
178
165
|
function attribute(state, issue) {
|
|
179
166
|
const match = RECORD_PATH_PATTERN.exec(issue.path);
|
|
180
167
|
const nested = match?.[3];
|
|
181
168
|
const key = match ? `${match[1]}[${match[2]}]${nested ? `.assertions[${nested}]` : ""}` : undefined;
|
|
182
169
|
const origin = key ? state.origins.get(key) : undefined;
|
|
183
|
-
//
|
|
184
|
-
// contributes anything outside a table.
|
|
170
|
+
// Only the manifest contributes fields outside the tables, so it owns document-level issues.
|
|
185
171
|
const file = origin?.file ?? MODEL_MANIFEST_FILENAME;
|
|
186
172
|
const claimant = issue.code === ValidationIssueCode.DuplicateID && origin?.id
|
|
187
173
|
? state.firstClaims.get(origin.table)?.get(origin.id)
|
|
188
|
-
:
|
|
174
|
+
: null;
|
|
189
175
|
return {
|
|
190
176
|
file,
|
|
191
177
|
path: issue.path,
|
|
192
178
|
code: issue.code,
|
|
193
179
|
message: issue.message,
|
|
194
|
-
|
|
180
|
+
otherFile: claimant ?? null,
|
|
195
181
|
};
|
|
196
182
|
}
|
|
197
183
|
/**
|
|
198
|
-
*
|
|
184
|
+
* Merges source files into one document and validates it.
|
|
185
|
+
*
|
|
186
|
+
* The function sorts files by path first, so the input order never affects the result.
|
|
199
187
|
*
|
|
200
|
-
*
|
|
201
|
-
* order. Throws {@link GeographicModelLoadError} with every issue, each addressed to its source file; returns nothing
|
|
202
|
-
* partial.
|
|
188
|
+
* @throws {GeographicModelLoadError} With every issue, each attributed to its source file.
|
|
203
189
|
*/
|
|
204
190
|
export function mergeGeographicModelFiles(files) {
|
|
205
191
|
const state = {
|
|
@@ -207,6 +193,7 @@ export function mergeGeographicModelFiles(files) {
|
|
|
207
193
|
tables: { relations: [], concepts: [], mappings: [], observations: [], derivedFacts: [] },
|
|
208
194
|
origins: new Map(),
|
|
209
195
|
firstClaims: new Map(),
|
|
196
|
+
version: null,
|
|
210
197
|
};
|
|
211
198
|
const ordered = files.toSorted((left, right) => compareIdentifiers(left.path, right.path));
|
|
212
199
|
const manifest = ordered.find((file) => file.path === MODEL_MANIFEST_FILENAME);
|
|
@@ -216,6 +203,7 @@ export function mergeGeographicModelFiles(files) {
|
|
|
216
203
|
path: "$",
|
|
217
204
|
code: LoadIssueCode.MissingField,
|
|
218
205
|
message: `a model directory carries \`${MODEL_MANIFEST_FILENAME}\`, holding the document's \`version\``,
|
|
206
|
+
otherFile: null,
|
|
219
207
|
});
|
|
220
208
|
}
|
|
221
209
|
for (const file of ordered) {
|
|
@@ -228,7 +216,7 @@ export function mergeGeographicModelFiles(files) {
|
|
|
228
216
|
}
|
|
229
217
|
readTableFile(state, file, value);
|
|
230
218
|
}
|
|
231
|
-
//
|
|
219
|
+
// Validation issues cannot be attributed reliably after a structural failure, so those failures stop here.
|
|
232
220
|
if (state.issues.length)
|
|
233
221
|
throw new GeographicModelLoadError(state.issues);
|
|
234
222
|
const result = validateGeographicModelDocument({ version: state.version, ...state.tables });
|
|
@@ -238,11 +226,9 @@ export function mergeGeographicModelFiles(files) {
|
|
|
238
226
|
return result.document;
|
|
239
227
|
}
|
|
240
228
|
/**
|
|
241
|
-
*
|
|
229
|
+
* Lists every `*.json` file under `root` as a relative path, sorted by code point at each level.
|
|
242
230
|
*
|
|
243
|
-
*
|
|
244
|
-
* the tree and not of the filesystem that stored it. Symbolic links are not followed: a model directory is source, and
|
|
245
|
-
* a link out of it is a record whose home nobody can state.
|
|
231
|
+
* Symbolic links are skipped because only regular files and directories match.
|
|
246
232
|
*/
|
|
247
233
|
async function listSourceFiles(root, prefix = "") {
|
|
248
234
|
const entries = await Globerator.from("*", {
|
|
@@ -264,9 +250,9 @@ async function listSourceFiles(root, prefix = "") {
|
|
|
264
250
|
return found;
|
|
265
251
|
}
|
|
266
252
|
/**
|
|
267
|
-
*
|
|
253
|
+
* Reads every `*.json` file under `root`, merges the files and validates the merged document.
|
|
268
254
|
*
|
|
269
|
-
*
|
|
255
|
+
* @throws {GeographicModelLoadError} With every issue, each attributed to its source file.
|
|
270
256
|
*/
|
|
271
257
|
export async function loadGeographicModelDirectory(root) {
|
|
272
258
|
const paths = await listSourceFiles(root);
|
package/out/load.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../lib/load.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../lib/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,kBAAkB,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAGhD,OAAO,EAAE,+BAA+B,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EACN,GAAG,EACH,eAAe,EACf,SAAS,EACT,UAAU,EAEV,mBAAmB,GACnB,MAAM,oBAAoB,CAAA;AAC3B;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAA;AAEnD;;GAEG;AACH,MAAM,YAAY,GAAG,CAAC,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,CAAU,CAAA;AAInG,MAAM,eAAe,GAAG,CAAC,SAAS,CAAU,CAAA;AAE5C;;;GAGG;AACH,MAAM,mBAAmB,GAAG,sDAAsD,CAAA;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC5B,GAAG,mBAAmB;IACtB;;OAEG;IACH,aAAa,EAAE,gBAAgB;CACtB,CAAA;AAmCV;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA+B;IAClE,OAAO,MAAM;SACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACd,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,uBAAuB,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAEhF,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,GAAG,QAAQ,KAAK,KAAK,CAAC,IAAI,GAAG,CAAA;IAClF,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACzC,MAAM,CAAyB;IAExC,YAAY,MAA+B;QAC1C,KAAK,CAAC,0CAA0C,MAAM,CAAC,MAAM,aAAa,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAExG,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACrB,CAAC;CACD;AA2BD,SAAS,OAAO,CAAC,IAAY,EAAE,MAAkC;IAChE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AACtH,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,IAA+B,EAAE,MAAsB;IAC9E,IAAI,CAAC;QACJ,2EAA2E;QAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,aAAa,CAAC,aAAa;YACjC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/D,SAAS,EAAE,IAAI;SACf,CAAC,CAAA;QAEF,OAAO,SAAS,CAAA;IACjB,CAAC;AACF,CAAC;AAED,SAAS,KAAK,CAAC,KAAiB,EAAE,KAAa,EAAE,EAAiB,EAAE,IAAY;IAC/E,IAAI,CAAC,EAAE;QAAE,OAAM;IAEf,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAA;IAExE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAEpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IACrB,CAAC;AACF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC/B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEtC,OAAO,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACtD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAiB,EAAE,IAA+B,EAAE,KAAc;IAC3F,MAAM,MAAM,GAAsB,EAAE,CAAA;IAEpC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,mBAAmB,CAAC,SAAS,EAAE,KAAK,uBAAuB,sBAAsB,CAAC,CAAA;IACpG,CAAC;SAAM,CAAC;QACP,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,eAAe,CAAC,CAAA;QAEpD,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;IAChE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;AACjD,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,KAAiB,EAAE,IAA+B,EAAE,KAAc;IACxF,MAAM,MAAM,GAAsB,EAAE,CAAA;IAEpC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,mBAAmB,CAAC,SAAS,EAAE,kDAAkD,CAAC,CAAA;QAEnG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;QAEhD,OAAM;IACP,CAAC;IAED,8FAA8F;IAC9F,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,EAAE,GAAG,eAAe,CAAC,CAAC,CAAA;IAE1E,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;QACxB,GAAG,CACF,MAAM,EACN,WAAW,EACX,mBAAmB,CAAC,YAAY,EAChC,+CAA+C,uBAAuB,yBAAyB,CAC/F,CAAA;IACF,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC;YAAE,SAAQ;QAE/B,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;YACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;YAC1B,MAAM,YAAY,GAAG,GAAG,KAAK,IAAI,KAAK,GAAG,CAAA;YAEzC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAC/B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;YAC/D,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YAElC,IAAI,KAAK,KAAK,UAAU,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;gBAAE,SAAQ;YAE/F,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;gBAChE,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;gBAEvC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,YAAY,eAAe,QAAQ,GAAG,EAAE;oBAC5D,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,YAAY;oBACnB,EAAE,EAAE,WAAW;iBACf,CAAC,CAAA;gBAEF,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;YACnD,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;AACjD,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAiB,EAAE,KAAsB;IAC3D,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAClD,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAA;IACzB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;IACnG,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAEvD,6FAA6F;IAC7F,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,uBAAuB,CAAA;IAEpD,MAAM,QAAQ,GACb,KAAK,CAAC,IAAI,KAAK,mBAAmB,CAAC,WAAW,IAAI,MAAM,EAAE,EAAE;QAC3D,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACrD,CAAC,CAAC,IAAI,CAAA;IAER,OAAO;QACN,IAAI;QACJ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,QAAQ,IAAI,IAAI;KAC3B,CAAA;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAA2C;IACpF,MAAM,KAAK,GAAe;QACzB,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;QACzF,OAAO,EAAE,IAAI,GAAG,EAAE;QAClB,WAAW,EAAE,IAAI,GAAG,EAAE;QACtB,OAAO,EAAE,IAAI;KACb,CAAA;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1F,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAA;IAE9E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;YACjB,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,aAAa,CAAC,YAAY;YAChC,OAAO,EAAE,+BAA+B,uBAAuB,wCAAwC;YACvG,SAAS,EAAE,IAAI;SACf,CAAC,CAAA;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAEhD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAQ;QAEjC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;YAEpC,SAAQ;QACT,CAAC;QAED,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAClC,CAAC;IAED,2GAA2G;IAC3G,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAEzE,MAAM,MAAM,GAAG,+BAA+B,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;IAE3F,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;IAC1F,CAAC;IAED,OAAO,MAAM,CAAC,QAAQ,CAAA;AACvB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,MAAM,GAAG,EAAE;IACvD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE;QAC1C,GAAG,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC;QAC9B,aAAa,EAAE,IAAI;QACnB,SAAS,EAAE,KAAK;KAChB,CAAC,CAAC,OAAO,EAAE,CAAA;IAEZ,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAClG,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAA;QAE5D,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAElD,SAAQ;QACT,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,IAAY;IAC9D,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,KAAK,GAAgC,EAAE,CAAA;IAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,yBAAyB,CAAC,KAAK,CAAC,CAAA;AACxC,CAAC"}
|
package/out/lookup.d.ts
CHANGED
|
@@ -3,62 +3,46 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* The shape is deliberate. `@mailwoman/geographic-model` compiles authored records into an artifact
|
|
10
|
-
* precisely so a runtime consumer never traverses anything — so the index exposes lookups
|
|
11
|
-
* (`concept`, `ancestorsOf`, `derivedFactsAbout`, `conceptsForExternalID`) and no walk, no cursor,
|
|
12
|
-
* and no query language.
|
|
13
|
-
*
|
|
14
|
-
* Two absences are distinguished everywhere, because they are different answers. A lookup for a
|
|
15
|
-
* concept the artifact does not carry returns `undefined` — the model cannot speak to it. A lookup
|
|
16
|
-
* for a concept it does carry, which nothing was derived about, returns an empty list — the model
|
|
17
|
-
* carries it and states nothing. A reader that collapsed the two would report "no ancestors" for a
|
|
18
|
-
* concept it had never heard of.
|
|
6
|
+
* Read-only lookups over a compiled artifact. Queries use prebuilt maps rather than traversing the graph.
|
|
7
|
+
* The lookup returns `undefined` for unknown concepts and an empty list for known concepts with no related facts.
|
|
19
8
|
*/
|
|
20
9
|
import type { POICategoryID } from "@mailwoman/poi-taxonomy/types";
|
|
21
10
|
import type { CompiledGeographicModel } from "#artifact";
|
|
22
11
|
import type { ConceptID, ConceptRecord, DerivedFactRecord, ExternalVocabulary, RelationID, RelationRecord } from "#schema";
|
|
23
12
|
/**
|
|
24
|
-
*
|
|
13
|
+
* Lookup methods for one compiled artifact.
|
|
25
14
|
*/
|
|
26
15
|
export interface GeographicModelIndex {
|
|
27
16
|
/**
|
|
28
|
-
*
|
|
17
|
+
* Compiled artifact used by this index.
|
|
29
18
|
*/
|
|
30
19
|
readonly model: CompiledGeographicModel;
|
|
31
20
|
/**
|
|
32
|
-
*
|
|
21
|
+
* Concept record, or `undefined` if absent.
|
|
33
22
|
*/
|
|
34
23
|
concept(id: ConceptID): ConceptRecord | undefined;
|
|
35
24
|
/**
|
|
36
|
-
*
|
|
25
|
+
* Relation definition, or `undefined` if absent.
|
|
37
26
|
*/
|
|
38
27
|
relation(id: RelationID): RelationRecord | undefined;
|
|
39
28
|
/**
|
|
40
|
-
*
|
|
41
|
-
* nothing; `undefined` for a concept the artifact does not carry.
|
|
29
|
+
* Transitive ancestors in code-point order; `undefined` if the concept is absent.
|
|
42
30
|
*/
|
|
43
31
|
ancestorsOf(id: ConceptID): readonly ConceptID[] | undefined;
|
|
44
32
|
/**
|
|
45
|
-
*
|
|
46
|
-
* `undefined` for a concept the artifact does not carry.
|
|
33
|
+
* Derived facts in artifact order; `undefined` if the concept is absent.
|
|
47
34
|
*/
|
|
48
35
|
derivedFactsAbout(id: ConceptID): readonly DerivedFactRecord[] | undefined;
|
|
49
36
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* An empty list is a true negative rather than an unread answer: the artifact carries every mapping the document
|
|
53
|
-
* authored, so nothing having declared this identifier is the whole of what there is to know about it.
|
|
37
|
+
* Concepts mapped from this external ID, in code-point order.
|
|
38
|
+
* An empty list means no mapping is recorded.
|
|
54
39
|
*/
|
|
55
40
|
conceptsForExternalID(vocabulary: ExternalVocabulary, externalID: POICategoryID): readonly ConceptID[];
|
|
56
41
|
}
|
|
57
42
|
/**
|
|
58
|
-
*
|
|
43
|
+
* Build lookup maps over a compiled artifact.
|
|
59
44
|
*
|
|
60
|
-
*
|
|
61
|
-
* are the artifact's own.
|
|
45
|
+
* Return references to the artifact's records without copying them.
|
|
62
46
|
*/
|
|
63
47
|
export declare function createGeographicModelIndex(model: CompiledGeographicModel): GeographicModelIndex;
|
|
64
48
|
//# sourceMappingURL=lookup.d.ts.map
|
package/out/lookup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../lib/lookup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../lib/lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAElE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,KAAK,EACX,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,uBAAuB,CAAA;IACvC;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CAAA;IACjD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,cAAc,GAAG,SAAS,CAAA;IACpD;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,SAAS,SAAS,EAAE,GAAG,SAAS,CAAA;IAC5D;;OAEG;IACH,iBAAiB,CAAC,EAAE,EAAE,SAAS,GAAG,SAAS,iBAAiB,EAAE,GAAG,SAAS,CAAA;IAC1E;;;OAGG;IACH,qBAAqB,CAAC,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAE,aAAa,GAAG,SAAS,SAAS,EAAE,CAAA;CACtG;AAMD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,uBAAuB,GAAG,oBAAoB,CAmD/F"}
|
package/out/lookup.js
CHANGED
|
@@ -3,29 +3,17 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* The shape is deliberate. `@mailwoman/geographic-model` compiles authored records into an artifact
|
|
10
|
-
* precisely so a runtime consumer never traverses anything — so the index exposes lookups
|
|
11
|
-
* (`concept`, `ancestorsOf`, `derivedFactsAbout`, `conceptsForExternalID`) and no walk, no cursor,
|
|
12
|
-
* and no query language.
|
|
13
|
-
*
|
|
14
|
-
* Two absences are distinguished everywhere, because they are different answers. A lookup for a
|
|
15
|
-
* concept the artifact does not carry returns `undefined` — the model cannot speak to it. A lookup
|
|
16
|
-
* for a concept it does carry, which nothing was derived about, returns an empty list — the model
|
|
17
|
-
* carries it and states nothing. A reader that collapsed the two would report "no ancestors" for a
|
|
18
|
-
* concept it had never heard of.
|
|
6
|
+
* Read-only lookups over a compiled artifact. Queries use prebuilt maps rather than traversing the graph.
|
|
7
|
+
* The lookup returns `undefined` for unknown concepts and an empty list for known concepts with no related facts.
|
|
19
8
|
*/
|
|
20
9
|
import { compareByCodePoint as compareIdentifiers } from "@mailwoman/core/strings/compare";
|
|
21
10
|
function externalKey(vocabulary, externalID) {
|
|
22
11
|
return `${vocabulary}\u0000${externalID}`;
|
|
23
12
|
}
|
|
24
13
|
/**
|
|
25
|
-
*
|
|
14
|
+
* Build lookup maps over a compiled artifact.
|
|
26
15
|
*
|
|
27
|
-
*
|
|
28
|
-
* are the artifact's own.
|
|
16
|
+
* Return references to the artifact's records without copying them.
|
|
29
17
|
*/
|
|
30
18
|
export function createGeographicModelIndex(model) {
|
|
31
19
|
const concepts = new Map(model.concepts.map((concept) => [String(concept.id), concept]));
|
package/out/lookup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../lib/lookup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../lib/lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
* @file Reads the compiled model this package ships in `data/geographic-model.json`.
|
|
6
|
+
*/
|
|
7
|
+
import { type CompiledGeographicModel } from "#artifact";
|
|
8
|
+
/**
|
|
9
|
+
* The authoring directory and the artifact it compiles to.
|
|
10
|
+
*
|
|
11
|
+
* Probes for `model/model.json`, so a genuinely missing `data/` throws naming the path.
|
|
12
|
+
*/
|
|
13
|
+
export declare function packagedModelPaths(): Promise<{
|
|
14
|
+
source: string;
|
|
15
|
+
artifact: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Read the committed artifact.
|
|
19
|
+
*
|
|
20
|
+
* The reader checks the format version.
|
|
21
|
+
* It trusts the records because the loader validated them on input.
|
|
22
|
+
*/
|
|
23
|
+
export declare function readCompiledGeographicModel(): Promise<CompiledGeographicModel>;
|
|
24
|
+
//# sourceMappingURL=packaged.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packaged.d.ts","sourceRoot":"","sources":["../lib/packaged.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EAAE,KAAK,uBAAuB,EAAgC,MAAM,WAAW,CAAA;AAEtF;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAexF;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAOpF"}
|