@heroiclands/package-build 22.4.4 → 22.4.6
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 +24 -0
- package/CONTENT.md +30 -1
- package/README.md +9 -0
- package/bin/content-build.mjs +163 -0
- package/bin/package-build.mjs +18 -4
- package/content-config.mjs +7 -0
- package/docs/api.md +88 -0
- package/docs/commands.md +222 -2
- package/docs/configuration.md +19 -1
- package/docs/content-format.md +105 -6
- package/docs/diagnostics.md +1 -0
- package/docs/project-setup.md +7 -6
- package/engine/frontmatter-lint.mjs +11 -1
- package/engine/index.mjs +18 -0
- package/engine/map-build.mjs +270 -0
- package/engine/map-dot.mjs +745 -0
- package/engine/map-graphviz.mjs +138 -0
- package/engine/map-layout.mjs +894 -0
- package/engine/map-places.mjs +561 -0
- package/engine/metadata-index.mjs +7 -0
- package/engine/note-vocabulary.mjs +28 -0
- package/engine/place-relations.mjs +637 -0
- package/engine/site-config.mjs +1 -1
- package/engine/site-root.mjs +147 -6
- package/package.json +3 -2
- package/types/engine/index.d.mts +6 -0
- package/types/engine/map-build.d.mts +84 -0
- package/types/engine/map-dot.d.mts +143 -0
- package/types/engine/map-graphviz.d.mts +61 -0
- package/types/engine/map-layout.d.mts +427 -0
- package/types/engine/map-places.d.mts +259 -0
- package/types/engine/note-vocabulary.d.mts +12 -0
- package/types/engine/place-relations.d.mts +95 -0
- package/types/engine/site-config.d.mts +1 -1
- package/types/engine/site-root.d.mts +59 -7
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The angle of a bearing in degrees, counter-clockwise from east, so north
|
|
3
|
+
* is up and east is right on a page whose `y` grows upward — GraphViz's
|
|
4
|
+
* coordinate system for a pinned position.
|
|
5
|
+
*
|
|
6
|
+
* @param {unknown} bearing - A bearing.
|
|
7
|
+
* @returns {number|undefined} `N` is 90, `E` 0, `S` -90, `W` 180; `undefined`
|
|
8
|
+
* for a value that is not a bearing.
|
|
9
|
+
*/
|
|
10
|
+
export function bearingAngle(bearing: unknown): number | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* The unit vector of a bearing.
|
|
13
|
+
*
|
|
14
|
+
* @param {unknown} bearing - A bearing.
|
|
15
|
+
* @returns {{x: number, y: number}|undefined} The vector, or `undefined` for a
|
|
16
|
+
* value that is not a bearing.
|
|
17
|
+
*/
|
|
18
|
+
export function bearingVector(bearing: unknown): {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
} | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* How many steps around the compass separate two bearings, the shorter way:
|
|
24
|
+
* 0 for the same bearing, 1 for adjacent ones, 4 for opposites.
|
|
25
|
+
*
|
|
26
|
+
* @param {unknown} a - A bearing.
|
|
27
|
+
* @param {unknown} b - A bearing.
|
|
28
|
+
* @returns {number|undefined} The steps, or `undefined` when either is not a
|
|
29
|
+
* bearing.
|
|
30
|
+
*/
|
|
31
|
+
export function bearingSteps(a: unknown, b: unknown): number | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The radius of the rim — where a place beyond the horizon, or one whose
|
|
34
|
+
* days nobody stated, is named. One log step beyond the horizon, so the rim
|
|
35
|
+
* reads as the next ring rather than a margin.
|
|
36
|
+
*
|
|
37
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
38
|
+
* by default.
|
|
39
|
+
* @returns {number} Points.
|
|
40
|
+
*/
|
|
41
|
+
export function rimRadius(horizon?: number): number;
|
|
42
|
+
/**
|
|
43
|
+
* The radius of the ring a days value sits on.
|
|
44
|
+
*
|
|
45
|
+
* Logarithmic in days, so equal ratios of days are equal steps of radius: a
|
|
46
|
+
* day to two days is the same step as five to ten, whatever the horizon. Any
|
|
47
|
+
* value beyond the horizon, and no value at all, is the rim.
|
|
48
|
+
*
|
|
49
|
+
* @param {number|undefined} days - A days value, on the scale or not.
|
|
50
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
51
|
+
* by default.
|
|
52
|
+
* @returns {number} Points.
|
|
53
|
+
*/
|
|
54
|
+
export function ringRadius(days: number | undefined, horizon?: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* The rings, inside out — one per marker up to the horizon.
|
|
57
|
+
*
|
|
58
|
+
* @param {number} [horizon] - The horizon in days; the map from a place's
|
|
59
|
+
* by default.
|
|
60
|
+
* @returns {Array<{days: number, radius: number}>} Each marker and its radius.
|
|
61
|
+
*/
|
|
62
|
+
export function rings(horizon?: number): Array<{
|
|
63
|
+
days: number;
|
|
64
|
+
radius: number;
|
|
65
|
+
}>;
|
|
66
|
+
/**
|
|
67
|
+
* The smallest marker of the scale that covers a total of days, or `undefined`
|
|
68
|
+
* beyond the scale's end or for no total at all.
|
|
69
|
+
*
|
|
70
|
+
* A two-hop journey adds two markers, and the sum is rarely a marker itself;
|
|
71
|
+
* the ring it belongs on is the first one no shorter than it — "about this,
|
|
72
|
+
* under normal conditions", rounded the pessimistic way.
|
|
73
|
+
*
|
|
74
|
+
* @param {number|undefined} total - Days, on the scale or not.
|
|
75
|
+
* @returns {number|undefined} The marker.
|
|
76
|
+
*/
|
|
77
|
+
export function daysMarker(total: number | undefined): number | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* The length a route's edge asks of `neato` in the whole route graph, in
|
|
80
|
+
* inches — the same log scale as the rings, so the god's-eye view and the
|
|
81
|
+
* itinerary agree about what a day and a month look like.
|
|
82
|
+
*
|
|
83
|
+
* @param {number|undefined} days - The route's days, or none for a border.
|
|
84
|
+
* @returns {number} Inches.
|
|
85
|
+
*/
|
|
86
|
+
export function edgeLength(days: number | undefined): number;
|
|
87
|
+
/**
|
|
88
|
+
* A chain of hops composed into one bearing and one total, or nothing where
|
|
89
|
+
* a hop turns back.
|
|
90
|
+
*
|
|
91
|
+
* The composed direction is that of the hops added as vectors weighted by
|
|
92
|
+
* their days, and the total is their sum. Each hop after the first is
|
|
93
|
+
* checked against the running direction of the chain before it — not
|
|
94
|
+
* against the previous hop — and composes only where it lies within one
|
|
95
|
+
* octant of that direction, so a path may bend a little at every hop and
|
|
96
|
+
* drift past an octant of where it began, but a hop that turns back ends
|
|
97
|
+
* the chain: a place east and then north of here is not in any one
|
|
98
|
+
* direction, and the drawing omits it rather than guess. A hop with no days
|
|
99
|
+
* — a border — makes the total unknown, because a frontier states no
|
|
100
|
+
* distance, and then every hop weighs the same, because nothing says which
|
|
101
|
+
* is the longer.
|
|
102
|
+
*
|
|
103
|
+
* @param {Hop[]} hops - The hops, from the centre outward.
|
|
104
|
+
* @returns {{angle: number, days: number|undefined}|undefined} The composed
|
|
105
|
+
* bearing in degrees and the total days, or `undefined` where a hop turns
|
|
106
|
+
* back, a bearing is not one, or there are no hops.
|
|
107
|
+
*/
|
|
108
|
+
export function composeChain(hops: Hop[]): {
|
|
109
|
+
angle: number;
|
|
110
|
+
days: number | undefined;
|
|
111
|
+
} | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* Two hops composed into one bearing and one total, or nothing where they
|
|
114
|
+
* disagree.
|
|
115
|
+
*
|
|
116
|
+
* Two hops agree when their bearings are the same or adjacent — the
|
|
117
|
+
* two-hop case of {@link composeChain}: the second hop is checked against
|
|
118
|
+
* the first, which is the whole running direction at that point.
|
|
119
|
+
*
|
|
120
|
+
* @param {Hop} first - The hop from the centre.
|
|
121
|
+
* @param {Hop} second - The hop onward.
|
|
122
|
+
* @returns {{angle: number, days: number|undefined}|undefined} The composed
|
|
123
|
+
* bearing in degrees and the total days, or `undefined` where the hops
|
|
124
|
+
* disagree or either bearing is not one.
|
|
125
|
+
*/
|
|
126
|
+
export function composeHops(first: Hop, second: Hop): {
|
|
127
|
+
angle: number;
|
|
128
|
+
days: number | undefined;
|
|
129
|
+
} | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Every relation touching one place, read from both ends.
|
|
132
|
+
*
|
|
133
|
+
* A border or a route is one fact stated from each end, and a note that
|
|
134
|
+
* states one side of it does not make the fact untrue — so the map reads what
|
|
135
|
+
* the place states *and* what every other place states about it, inverting
|
|
136
|
+
* the bearing on the way back. The place's own statement wins where both
|
|
137
|
+
* exist, and a target no place declares is returned separately so the caller
|
|
138
|
+
* can name it. The lint is where a missing reciprocal is reported; here it is
|
|
139
|
+
* simply drawn.
|
|
140
|
+
*
|
|
141
|
+
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
142
|
+
* @param {string} shortcode - The place asked about.
|
|
143
|
+
* @returns {{relations: Relation[], unresolved: Array<{from: string, to: string}>}}
|
|
144
|
+
* The relations, own statements first, and the targets that resolved to
|
|
145
|
+
* nothing.
|
|
146
|
+
*/
|
|
147
|
+
export function relationsOf(places: Map<string, MapPlace>, shortcode: string): {
|
|
148
|
+
relations: Relation[];
|
|
149
|
+
unresolved: Array<{
|
|
150
|
+
from: string;
|
|
151
|
+
to: string;
|
|
152
|
+
}>;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Lay out the map from a place: two hops, a horizon of 90 days, and a rim
|
|
156
|
+
* naming what lies beyond it.
|
|
157
|
+
*
|
|
158
|
+
* The centre at the origin. Every neighbour it states, or that states it, at
|
|
159
|
+
* the angle of its bearing and on the ring of its days — the innermost ring
|
|
160
|
+
* for a border with no route, the shortest route where several modes reach
|
|
161
|
+
* one neighbour. Beyond each neighbour, every place a second hop reaches, at
|
|
162
|
+
* the composed bearing where the two hops agree and on the ring of their
|
|
163
|
+
* total; on the rim, marked unknown, where either hop states no days; omitted
|
|
164
|
+
* where the hops disagree. A place reachable by several second hops takes
|
|
165
|
+
* the one with known days, then the shortest. Nodes sharing a ring and a
|
|
166
|
+
* bearing are fanned apart.
|
|
167
|
+
*
|
|
168
|
+
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
169
|
+
* @param {string} centre - The place the map is from.
|
|
170
|
+
* @returns {FromLayout} The layout, in points.
|
|
171
|
+
* @throws {Error} When `centre` is not a place.
|
|
172
|
+
*/
|
|
173
|
+
export function layoutFrom(places: Map<string, MapPlace>, centre: string): FromLayout;
|
|
174
|
+
/**
|
|
175
|
+
* Lay out the chart from a place: the map from it at a larger horizon.
|
|
176
|
+
*
|
|
177
|
+
* The neighbours as on the map from a place. Beyond them the hops chain on,
|
|
178
|
+
* each checked against the running direction of the chain so far and
|
|
179
|
+
* composing only within one octant of it, so a path bends but never turns
|
|
180
|
+
* back; a place is drawn at the composed bearing on the ring of the summed
|
|
181
|
+
* days, and where several chains reach it, by the one with the fewest. A
|
|
182
|
+
* border beyond the first hop makes the total unknown and sends the place to
|
|
183
|
+
* the rim, and nothing is drawn beyond it. A place whose total exceeds the
|
|
184
|
+
* horizon is left out — the chart is already the larger view — so the rim
|
|
185
|
+
* holds the unknown alone.
|
|
186
|
+
*
|
|
187
|
+
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
188
|
+
* @param {string} centre - The place the chart is from.
|
|
189
|
+
* @param {object} [opts]
|
|
190
|
+
* @param {number} [opts.horizon] - The horizon in days, a marker of the
|
|
191
|
+
* scale; {@link CHART_HORIZON_DAYS} by default.
|
|
192
|
+
* @returns {FromLayout} The layout, in points.
|
|
193
|
+
* @throws {Error} When `centre` is not a place, or `horizon` is not a marker
|
|
194
|
+
* of the scale.
|
|
195
|
+
*/
|
|
196
|
+
export function layoutChart(places: Map<string, MapPlace>, centre: string, { horizon }?: {
|
|
197
|
+
horizon?: number | undefined;
|
|
198
|
+
}): FromLayout;
|
|
199
|
+
/**
|
|
200
|
+
* One edge of the whole route graph.
|
|
201
|
+
*
|
|
202
|
+
* @typedef {object} TravelEdge
|
|
203
|
+
* @property {string} from
|
|
204
|
+
* @property {string} to
|
|
205
|
+
* @property {"border"|"route"} kind
|
|
206
|
+
* @property {string} bearing - Where `to` lies from `from`.
|
|
207
|
+
* @property {number} [days]
|
|
208
|
+
* @property {string} [mode]
|
|
209
|
+
* @property {number} len - The length asked of `neato`, in inches.
|
|
210
|
+
*/
|
|
211
|
+
/**
|
|
212
|
+
* The whole route graph: one edge per pair of places, however many ends and
|
|
213
|
+
* modes state it, with a length from its days.
|
|
214
|
+
*
|
|
215
|
+
* A pair reached by several modes takes the shortest; a pair that both
|
|
216
|
+
* borders and travels takes the route, since the days are what the length
|
|
217
|
+
* is from. The end that states the relation is `from`, so a one-sided entry
|
|
218
|
+
* is drawn from the note that carries it.
|
|
219
|
+
*
|
|
220
|
+
* @param {Map<string, MapPlace>} places - Every place, by shortcode.
|
|
221
|
+
* @returns {{edges: TravelEdge[], unresolved: Array<{from: string, to: string}>}}
|
|
222
|
+
* The edges, in a stable order.
|
|
223
|
+
*/
|
|
224
|
+
export function travelGraph(places: Map<string, MapPlace>): {
|
|
225
|
+
edges: TravelEdge[];
|
|
226
|
+
unresolved: Array<{
|
|
227
|
+
from: string;
|
|
228
|
+
to: string;
|
|
229
|
+
}>;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* The horizon of the map from a place, in days. A place farther than this
|
|
233
|
+
* is a name at the rim rather than a node on a ring.
|
|
234
|
+
*
|
|
235
|
+
* @type {number}
|
|
236
|
+
*/
|
|
237
|
+
export const HORIZON_DAYS: number;
|
|
238
|
+
/**
|
|
239
|
+
* The days markers that are rings — every marker of the scale up to the
|
|
240
|
+
* horizon.
|
|
241
|
+
*
|
|
242
|
+
* @type {readonly number[]}
|
|
243
|
+
*/
|
|
244
|
+
export const RING_DAYS: readonly number[];
|
|
245
|
+
/**
|
|
246
|
+
* The horizon of the chart from a place when none is asked for, in days: the
|
|
247
|
+
* end of the scale, so the whole of what the notes state fits on the page.
|
|
248
|
+
*
|
|
249
|
+
* @type {number}
|
|
250
|
+
*/
|
|
251
|
+
export const CHART_HORIZON_DAYS: number;
|
|
252
|
+
/**
|
|
253
|
+
* A place as the map reads it. The shape {@link module :engine/map-places}
|
|
254
|
+
* builds from the content index; only the relation fields matter here.
|
|
255
|
+
*/
|
|
256
|
+
export type MapPlace = {
|
|
257
|
+
shortcode: string;
|
|
258
|
+
name: string;
|
|
259
|
+
subType?: string | undefined;
|
|
260
|
+
parents: string[];
|
|
261
|
+
borders: Array<{
|
|
262
|
+
to: string;
|
|
263
|
+
bearing: string;
|
|
264
|
+
}>;
|
|
265
|
+
routes: Array<{
|
|
266
|
+
to: string;
|
|
267
|
+
bearing: string;
|
|
268
|
+
mode?: string;
|
|
269
|
+
days?: number;
|
|
270
|
+
}>;
|
|
271
|
+
url?: string | undefined;
|
|
272
|
+
address?: string | undefined;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* A relation between two places, read from whichever end states it.
|
|
276
|
+
*/
|
|
277
|
+
export type Relation = {
|
|
278
|
+
from: string;
|
|
279
|
+
to: string;
|
|
280
|
+
/**
|
|
281
|
+
* - Where `to` lies from `from`.
|
|
282
|
+
*/
|
|
283
|
+
bearing: string;
|
|
284
|
+
kind: "border" | "route";
|
|
285
|
+
days?: number | undefined;
|
|
286
|
+
mode?: string | undefined;
|
|
287
|
+
/**
|
|
288
|
+
* - Whether `from` states it, as opposed to `to`.
|
|
289
|
+
*/
|
|
290
|
+
stated: boolean;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* The layout of the map from a place or of the chart from one.
|
|
294
|
+
*/
|
|
295
|
+
export type FromLayout = {
|
|
296
|
+
centre: string;
|
|
297
|
+
nodes: FromNode[];
|
|
298
|
+
edges: FromEdge[];
|
|
299
|
+
rings: Array<{
|
|
300
|
+
days: number;
|
|
301
|
+
radius: number;
|
|
302
|
+
}>;
|
|
303
|
+
/**
|
|
304
|
+
* - The rim's radius, in points.
|
|
305
|
+
*/
|
|
306
|
+
rim: number;
|
|
307
|
+
/**
|
|
308
|
+
* - The horizon, in days.
|
|
309
|
+
*/
|
|
310
|
+
horizon: number;
|
|
311
|
+
/**
|
|
312
|
+
* - Whether a place past the horizon is named at
|
|
313
|
+
* the rim; false, it is omitted and the rim holds only the unknown.
|
|
314
|
+
*/
|
|
315
|
+
beyond: boolean;
|
|
316
|
+
unresolved: Array<{
|
|
317
|
+
from: string;
|
|
318
|
+
to: string;
|
|
319
|
+
}>;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* One edge of the whole route graph.
|
|
323
|
+
*/
|
|
324
|
+
export type TravelEdge = {
|
|
325
|
+
from: string;
|
|
326
|
+
to: string;
|
|
327
|
+
kind: "border" | "route";
|
|
328
|
+
/**
|
|
329
|
+
* - Where `to` lies from `from`.
|
|
330
|
+
*/
|
|
331
|
+
bearing: string;
|
|
332
|
+
days?: number | undefined;
|
|
333
|
+
mode?: string | undefined;
|
|
334
|
+
/**
|
|
335
|
+
* - The length asked of `neato`, in inches.
|
|
336
|
+
*/
|
|
337
|
+
len: number;
|
|
338
|
+
};
|
|
339
|
+
/**
|
|
340
|
+
* One hop of a journey: a bearing and, for a route, its days.
|
|
341
|
+
*/
|
|
342
|
+
export type Hop = {
|
|
343
|
+
/**
|
|
344
|
+
* - Where the far end lies from the near end.
|
|
345
|
+
*/
|
|
346
|
+
bearing: string;
|
|
347
|
+
/**
|
|
348
|
+
* - The route's marker; absent for a border.
|
|
349
|
+
*/
|
|
350
|
+
days?: number | undefined;
|
|
351
|
+
};
|
|
352
|
+
/**
|
|
353
|
+
* One place on the map from a place.
|
|
354
|
+
*/
|
|
355
|
+
export type FromNode = {
|
|
356
|
+
shortcode: string;
|
|
357
|
+
/**
|
|
358
|
+
* - 0 for the centre, 1 for a neighbour, 2 and up
|
|
359
|
+
* beyond — the map from a place stops at 2, the chart goes on.
|
|
360
|
+
*/
|
|
361
|
+
hop: number;
|
|
362
|
+
/**
|
|
363
|
+
* - Points, east positive.
|
|
364
|
+
*/
|
|
365
|
+
x: number;
|
|
366
|
+
/**
|
|
367
|
+
* - Points, north positive.
|
|
368
|
+
*/
|
|
369
|
+
y: number;
|
|
370
|
+
/**
|
|
371
|
+
* - Degrees, counter-clockwise from east.
|
|
372
|
+
*/
|
|
373
|
+
angle: number;
|
|
374
|
+
/**
|
|
375
|
+
* - Points from the centre.
|
|
376
|
+
*/
|
|
377
|
+
radius: number;
|
|
378
|
+
/**
|
|
379
|
+
* - The days the ring was chosen by, or none.
|
|
380
|
+
*/
|
|
381
|
+
days?: number | undefined;
|
|
382
|
+
/**
|
|
383
|
+
* - Reached by a border alone.
|
|
384
|
+
*/
|
|
385
|
+
border: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* - On the rim because nobody stated its days.
|
|
388
|
+
*/
|
|
389
|
+
unknown: boolean;
|
|
390
|
+
/**
|
|
391
|
+
* - The place a hop beyond the neighbours is reached
|
|
392
|
+
* through.
|
|
393
|
+
*/
|
|
394
|
+
via?: string | undefined;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* One edge on the map from a place.
|
|
398
|
+
*/
|
|
399
|
+
export type FromEdge = {
|
|
400
|
+
from: string;
|
|
401
|
+
to: string;
|
|
402
|
+
/**
|
|
403
|
+
* - A route where any route reaches `to`.
|
|
404
|
+
*/
|
|
405
|
+
kind: "border" | "route";
|
|
406
|
+
bearing: string;
|
|
407
|
+
/**
|
|
408
|
+
* - The shortest route's.
|
|
409
|
+
*/
|
|
410
|
+
days?: number | undefined;
|
|
411
|
+
/**
|
|
412
|
+
* - The shortest route's.
|
|
413
|
+
*/
|
|
414
|
+
mode?: string | undefined;
|
|
415
|
+
/**
|
|
416
|
+
* - Every
|
|
417
|
+
* route that reaches `to`, for the label.
|
|
418
|
+
*/
|
|
419
|
+
routes: Array<{
|
|
420
|
+
mode: string;
|
|
421
|
+
days: number | undefined;
|
|
422
|
+
}>;
|
|
423
|
+
/**
|
|
424
|
+
* - 1 from the centre, 2 and up onward.
|
|
425
|
+
*/
|
|
426
|
+
hop: number;
|
|
427
|
+
};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read this package's places and polities out of its index records.
|
|
3
|
+
*
|
|
4
|
+
* @param {Array<Record<string, any>>} records - Index records, as
|
|
5
|
+
* {@link module:engine/content-index.indexRecordsFor} returns them.
|
|
6
|
+
* @param {object} opts
|
|
7
|
+
* @param {string} opts.contentBase - The content root the records were read from.
|
|
8
|
+
* @param {string} [opts.base] - The site base the package's pages are served
|
|
9
|
+
* under, ending in a slash. Absent, no place carries a URL.
|
|
10
|
+
* @returns {MapWorld} The world, with no dependency's places.
|
|
11
|
+
*/
|
|
12
|
+
export function placesFromRecords(records: Array<Record<string, any>>, { contentBase, base }: {
|
|
13
|
+
contentBase: string;
|
|
14
|
+
base?: string | undefined;
|
|
15
|
+
}): MapWorld;
|
|
16
|
+
/**
|
|
17
|
+
* Load the world a map is drawn from: this package's index, and the indexes
|
|
18
|
+
* of every dependency it declares.
|
|
19
|
+
*
|
|
20
|
+
* @param {object} opts
|
|
21
|
+
* @param {object} opts.config - The resolved configuration.
|
|
22
|
+
* @param {string} [opts.contentBase] - The content root, defaulting to the
|
|
23
|
+
* configured one.
|
|
24
|
+
* @param {string} [opts.base] - The site base this package's pages are served
|
|
25
|
+
* under. Absent, no local place carries a URL; a dependency's places carry
|
|
26
|
+
* the URL their index resolved to regardless.
|
|
27
|
+
* @param {object[]} [opts.problems] - Collects the notes the index cannot
|
|
28
|
+
* record, as diagnostics, instead of throwing on the first.
|
|
29
|
+
* @returns {MapWorld} The world.
|
|
30
|
+
*/
|
|
31
|
+
export function loadMapWorld({ config, contentBase, base, problems }: {
|
|
32
|
+
config: object;
|
|
33
|
+
contentBase?: string | undefined;
|
|
34
|
+
base?: string | undefined;
|
|
35
|
+
problems?: object[] | undefined;
|
|
36
|
+
}): MapWorld;
|
|
37
|
+
/**
|
|
38
|
+
* Analyse the containment tree.
|
|
39
|
+
*
|
|
40
|
+
* @param {Map<string, MapPlace>} places - Every place.
|
|
41
|
+
* @param {MapPolity[]} [polities] - Every polity.
|
|
42
|
+
* @returns {Containment} The analysis.
|
|
43
|
+
*/
|
|
44
|
+
export function analyzeContainment(places: Map<string, MapPlace>, polities?: MapPolity[]): Containment;
|
|
45
|
+
/**
|
|
46
|
+
* Every place beneath one, by following `parents` downward — the place
|
|
47
|
+
* itself included.
|
|
48
|
+
*
|
|
49
|
+
* @param {Containment} analysis - The analysis, for its children map.
|
|
50
|
+
* @param {string} root - The place at the top.
|
|
51
|
+
* @returns {Set<string>} The subtree.
|
|
52
|
+
*/
|
|
53
|
+
export function subtreeOf(analysis: Containment, root: string): Set<string>;
|
|
54
|
+
/**
|
|
55
|
+
* The anomalies as findings, in the toolchain's form.
|
|
56
|
+
*
|
|
57
|
+
* A finding about a `parents` entry is located at that entry in the note; a
|
|
58
|
+
* finding about the note as a whole at its `data` block, or the file alone;
|
|
59
|
+
* a finding about a fetched place at the cached index that supplied it. A
|
|
60
|
+
* place with no parent, a parent no place declares, and a cycle are errors —
|
|
61
|
+
* the tree cannot reach the place, or cannot be a tree. Two parents, a region
|
|
62
|
+
* with no `packFolder` and a polity beside no region are legal and worth a
|
|
63
|
+
* look, so they are warnings.
|
|
64
|
+
*
|
|
65
|
+
* @param {Containment} analysis - The analysis.
|
|
66
|
+
* @param {Map<string, MapPlace>} places - Every place.
|
|
67
|
+
* @param {object} opts
|
|
68
|
+
* @param {string} opts.contentBase - The content root the local notes sit under.
|
|
69
|
+
* @param {object} [opts.config] - The configuration, for naming a cached index.
|
|
70
|
+
* @returns {Array<{file: string, line?: number, column?: number,
|
|
71
|
+
* severity: "error"|"warning", message: string}>} The findings.
|
|
72
|
+
*/
|
|
73
|
+
export function containmentFindings(analysis: Containment, places: Map<string, MapPlace>, { contentBase, config }: {
|
|
74
|
+
contentBase: string;
|
|
75
|
+
config?: object | undefined;
|
|
76
|
+
}): Array<{
|
|
77
|
+
file: string;
|
|
78
|
+
line?: number;
|
|
79
|
+
column?: number;
|
|
80
|
+
severity: "error" | "warning";
|
|
81
|
+
message: string;
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* A place as the map reads it, from either source.
|
|
85
|
+
*/
|
|
86
|
+
export type MapPlace = {
|
|
87
|
+
/**
|
|
88
|
+
* - Lower case.
|
|
89
|
+
*/
|
|
90
|
+
shortcode: string;
|
|
91
|
+
/**
|
|
92
|
+
* - `name.full`, or the shortcode where a note has none.
|
|
93
|
+
*/
|
|
94
|
+
name: string;
|
|
95
|
+
/**
|
|
96
|
+
* - `place`.
|
|
97
|
+
*/
|
|
98
|
+
type: string;
|
|
99
|
+
subType?: string | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* - Shortcodes, lower case, empty where none.
|
|
102
|
+
*/
|
|
103
|
+
parents: string[];
|
|
104
|
+
borders: Array<{
|
|
105
|
+
to: string;
|
|
106
|
+
bearing: string;
|
|
107
|
+
}>;
|
|
108
|
+
routes: Array<{
|
|
109
|
+
to: string;
|
|
110
|
+
bearing: string;
|
|
111
|
+
mode?: string;
|
|
112
|
+
days?: number;
|
|
113
|
+
}>;
|
|
114
|
+
/**
|
|
115
|
+
* - The canonical address.
|
|
116
|
+
*/
|
|
117
|
+
address?: string | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* - The page, where a site base is known.
|
|
120
|
+
*/
|
|
121
|
+
url?: string | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* - The note's path below the content root; local only.
|
|
124
|
+
*/
|
|
125
|
+
file?: string | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* - The note's directory below the content root; local only.
|
|
128
|
+
*/
|
|
129
|
+
folder?: string | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* - The package that publishes it.
|
|
132
|
+
*/
|
|
133
|
+
package: string;
|
|
134
|
+
/**
|
|
135
|
+
* - Whether it is this package's own.
|
|
136
|
+
*/
|
|
137
|
+
local: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* - Whether the note declares
|
|
140
|
+
* `packFolder`; unknown for a fetched entry.
|
|
141
|
+
*/
|
|
142
|
+
hasPackFolder: boolean | undefined;
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* A polity — an `affiliation` note of `subType: polity` — drawn beside the
|
|
146
|
+
* region notes that share its directory.
|
|
147
|
+
*/
|
|
148
|
+
export type MapPolity = {
|
|
149
|
+
shortcode: string;
|
|
150
|
+
name: string;
|
|
151
|
+
address?: string | undefined;
|
|
152
|
+
url?: string | undefined;
|
|
153
|
+
file: string;
|
|
154
|
+
folder: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The world a map is drawn from: every place, every polity, and where the
|
|
158
|
+
* notes are for locating a finding.
|
|
159
|
+
*/
|
|
160
|
+
export type MapWorld = {
|
|
161
|
+
/**
|
|
162
|
+
* - By shortcode, lower case.
|
|
163
|
+
*/
|
|
164
|
+
places: Map<string, MapPlace>;
|
|
165
|
+
/**
|
|
166
|
+
* - In path order.
|
|
167
|
+
*/
|
|
168
|
+
polities: MapPolity[];
|
|
169
|
+
/**
|
|
170
|
+
* - The content root the local notes sit under.
|
|
171
|
+
*/
|
|
172
|
+
contentBase: string;
|
|
173
|
+
/**
|
|
174
|
+
* - The resolved configuration, where one was used.
|
|
175
|
+
*/
|
|
176
|
+
config?: object | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* - Dependency
|
|
179
|
+
* indexes that could not be read.
|
|
180
|
+
*/
|
|
181
|
+
stale: Array<{
|
|
182
|
+
package: string;
|
|
183
|
+
reason: string;
|
|
184
|
+
}>;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* What `parents` says about the world's shape.
|
|
188
|
+
*/
|
|
189
|
+
export type Containment = {
|
|
190
|
+
/**
|
|
191
|
+
* - The one `subType: world` place.
|
|
192
|
+
*/
|
|
193
|
+
world: string | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* - Regions parented directly on the world,
|
|
196
|
+
* in name order.
|
|
197
|
+
*/
|
|
198
|
+
continents: string[];
|
|
199
|
+
/**
|
|
200
|
+
* - Each place's continent, for
|
|
201
|
+
* the places that reach one by walking `parents` upward.
|
|
202
|
+
*/
|
|
203
|
+
continentOf: Map<string, string>;
|
|
204
|
+
/**
|
|
205
|
+
* - Each place's children.
|
|
206
|
+
*/
|
|
207
|
+
children: Map<string, string[]>;
|
|
208
|
+
/**
|
|
209
|
+
* - Each cycle as a chain that returns to its
|
|
210
|
+
* first place.
|
|
211
|
+
*/
|
|
212
|
+
cycles: string[][];
|
|
213
|
+
/**
|
|
214
|
+
* - Every place on any cycle.
|
|
215
|
+
*/
|
|
216
|
+
cycleNodes: Set<string>;
|
|
217
|
+
/**
|
|
218
|
+
* - The local region places
|
|
219
|
+
* in each directory, for placing polities.
|
|
220
|
+
*/
|
|
221
|
+
regionsByFolder: Map<string, string[]>;
|
|
222
|
+
/**
|
|
223
|
+
* - The polities analysed.
|
|
224
|
+
*/
|
|
225
|
+
polities: MapPolity[];
|
|
226
|
+
anomalies: Anomalies;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* Everything the containment tree can get wrong.
|
|
230
|
+
*/
|
|
231
|
+
export type Anomalies = {
|
|
232
|
+
/**
|
|
233
|
+
* - Places with no parent, the world excluded.
|
|
234
|
+
*/
|
|
235
|
+
noParent: string[];
|
|
236
|
+
/**
|
|
237
|
+
* -
|
|
238
|
+
* `parents` entries no place declares.
|
|
239
|
+
*/
|
|
240
|
+
unresolved: Array<{
|
|
241
|
+
place: string;
|
|
242
|
+
parent: string;
|
|
243
|
+
index: number;
|
|
244
|
+
}>;
|
|
245
|
+
cycles: string[][];
|
|
246
|
+
/**
|
|
247
|
+
* - Places with more than one parent.
|
|
248
|
+
*/
|
|
249
|
+
multiParent: string[];
|
|
250
|
+
/**
|
|
251
|
+
* - Polity shortcodes whose directory
|
|
252
|
+
* holds no region note.
|
|
253
|
+
*/
|
|
254
|
+
polityNoRegion: string[];
|
|
255
|
+
/**
|
|
256
|
+
* - Local regions with no `packFolder`.
|
|
257
|
+
*/
|
|
258
|
+
regionNoPackFolder: string[];
|
|
259
|
+
};
|
|
@@ -305,6 +305,18 @@ export type DataFieldSpec = {
|
|
|
305
305
|
* is a finding of its own: it addresses a hierarchy nothing will ever read.
|
|
306
306
|
*/
|
|
307
307
|
keys?: "pack" | undefined;
|
|
308
|
+
/**
|
|
309
|
+
* - A
|
|
310
|
+
* check of the value beyond its shape, run by the frontmatter lint with the
|
|
311
|
+
* link index once the container has been checked. The lint stays
|
|
312
|
+
* vocabulary-agnostic this way: the rule lives beside the field that needs
|
|
313
|
+
* it, and the linter calls whatever it is handed. A place's `borders` and
|
|
314
|
+
* `routes` carry one, because what they state is checked against the note
|
|
315
|
+
* at the other end.
|
|
316
|
+
*/
|
|
317
|
+
check?: ((note: object, opts: {
|
|
318
|
+
index?: object;
|
|
319
|
+
}) => object[]) | undefined;
|
|
308
320
|
/**
|
|
309
321
|
* - One line, for the author-facing reference.
|
|
310
322
|
*/
|