@mailwoman/core 2.1.0 → 3.0.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.
Files changed (172) hide show
  1. package/out/api/APIClient.d.ts +57 -0
  2. package/out/api/APIClient.d.ts.map +1 -0
  3. package/out/api/APIClient.js +108 -0
  4. package/out/api/APIClient.js.map +1 -0
  5. package/out/api/headless.d.ts +17 -0
  6. package/out/api/headless.d.ts.map +1 -0
  7. package/out/api/headless.js +18 -0
  8. package/out/api/headless.js.map +1 -0
  9. package/out/api/index.d.ts +11 -0
  10. package/out/api/index.d.ts.map +1 -0
  11. package/out/api/index.js +11 -0
  12. package/out/api/index.js.map +1 -0
  13. package/out/api/responses.d.ts +48 -0
  14. package/out/api/responses.d.ts.map +1 -0
  15. package/out/api/responses.js +68 -0
  16. package/out/api/responses.js.map +1 -0
  17. package/out/collections.d.ts +66 -0
  18. package/out/collections.d.ts.map +1 -0
  19. package/out/collections.js +97 -0
  20. package/out/collections.js.map +1 -0
  21. package/out/db/schema.d.ts +21 -0
  22. package/out/db/schema.d.ts.map +1 -0
  23. package/out/db/schema.js +16 -0
  24. package/out/db/schema.js.map +1 -0
  25. package/out/decoder/build-tree.d.ts +14 -1
  26. package/out/decoder/build-tree.d.ts.map +1 -1
  27. package/out/decoder/build-tree.js +37 -9
  28. package/out/decoder/build-tree.js.map +1 -1
  29. package/out/decoder/proposals-to-tree.d.ts.map +1 -1
  30. package/out/decoder/proposals-to-tree.js +2 -0
  31. package/out/decoder/proposals-to-tree.js.map +1 -1
  32. package/out/decoder/serialize-xml.d.ts +22 -1
  33. package/out/decoder/serialize-xml.d.ts.map +1 -1
  34. package/out/decoder/serialize-xml.js +64 -4
  35. package/out/decoder/serialize-xml.js.map +1 -1
  36. package/out/decoder/types.d.ts +45 -0
  37. package/out/decoder/types.d.ts.map +1 -1
  38. package/out/decoder/types.js +6 -0
  39. package/out/decoder/types.js.map +1 -1
  40. package/out/errors/index.d.ts +9 -0
  41. package/out/errors/index.d.ts.map +1 -0
  42. package/out/errors/index.js +9 -0
  43. package/out/errors/index.js.map +1 -0
  44. package/out/errors/schema.d.ts +69 -0
  45. package/out/errors/schema.d.ts.map +1 -0
  46. package/out/errors/schema.js +102 -0
  47. package/out/errors/schema.js.map +1 -0
  48. package/out/identifiers.d.ts +18 -0
  49. package/out/identifiers.d.ts.map +1 -0
  50. package/out/identifiers.js +49 -0
  51. package/out/identifiers.js.map +1 -0
  52. package/out/index.d.ts +3 -0
  53. package/out/index.d.ts.map +1 -1
  54. package/out/index.js +3 -4
  55. package/out/index.js.map +1 -1
  56. package/out/kysley/adapter.d.ts +13 -0
  57. package/out/kysley/adapter.d.ts.map +1 -0
  58. package/out/kysley/adapter.js +25 -0
  59. package/out/kysley/adapter.js.map +1 -0
  60. package/out/kysley/client.d.ts +16 -0
  61. package/out/kysley/client.d.ts.map +1 -0
  62. package/out/kysley/client.js +22 -0
  63. package/out/kysley/client.js.map +1 -0
  64. package/out/kysley/dialect-config.d.ts +27 -0
  65. package/out/kysley/dialect-config.d.ts.map +1 -0
  66. package/out/kysley/dialect-config.js +7 -0
  67. package/out/kysley/dialect-config.js.map +1 -0
  68. package/out/kysley/dialect.d.ts +39 -0
  69. package/out/kysley/dialect.d.ts.map +1 -0
  70. package/out/kysley/dialect.js +49 -0
  71. package/out/kysley/dialect.js.map +1 -0
  72. package/out/kysley/driver.d.ts +22 -0
  73. package/out/kysley/driver.d.ts.map +1 -0
  74. package/out/kysley/driver.js +114 -0
  75. package/out/kysley/driver.js.map +1 -0
  76. package/out/lifecycle/ServiceSymbol.d.ts +59 -0
  77. package/out/lifecycle/ServiceSymbol.d.ts.map +1 -0
  78. package/out/lifecycle/ServiceSymbol.js +62 -0
  79. package/out/lifecycle/ServiceSymbol.js.map +1 -0
  80. package/out/lifecycle/index.d.ts +11 -0
  81. package/out/lifecycle/index.d.ts.map +1 -0
  82. package/out/lifecycle/index.js +11 -0
  83. package/out/lifecycle/index.js.map +1 -0
  84. package/out/lifecycle/lru-cache.d.ts +22 -0
  85. package/out/lifecycle/lru-cache.d.ts.map +1 -0
  86. package/out/lifecycle/lru-cache.js +31 -0
  87. package/out/lifecycle/lru-cache.js.map +1 -0
  88. package/out/lifecycle/services.d.ts +145 -0
  89. package/out/lifecycle/services.d.ts.map +1 -0
  90. package/out/lifecycle/services.js +190 -0
  91. package/out/lifecycle/services.js.map +1 -0
  92. package/out/logging/index.d.ts +7 -0
  93. package/out/logging/index.d.ts.map +1 -0
  94. package/out/logging/index.js +7 -0
  95. package/out/logging/index.js.map +1 -0
  96. package/out/logging/shared.d.ts +60 -0
  97. package/out/logging/shared.d.ts.map +1 -0
  98. package/out/logging/shared.js +100 -0
  99. package/out/logging/shared.js.map +1 -0
  100. package/out/logging/tables.d.ts +7 -0
  101. package/out/logging/tables.d.ts.map +1 -0
  102. package/out/logging/tables.js +75 -0
  103. package/out/logging/tables.js.map +1 -0
  104. package/out/objects.d.ts +96 -0
  105. package/out/objects.d.ts.map +1 -0
  106. package/out/objects.js +96 -0
  107. package/out/objects.js.map +1 -0
  108. package/out/parser/proposal-pipeline.d.ts.map +1 -1
  109. package/out/parser/proposal-pipeline.js +0 -1
  110. package/out/parser/proposal-pipeline.js.map +1 -1
  111. package/out/pipeline/index.d.ts +14 -0
  112. package/out/pipeline/index.d.ts.map +1 -0
  113. package/out/pipeline/index.js +11 -0
  114. package/out/pipeline/index.js.map +1 -0
  115. package/out/pipeline/reconcile.d.ts +135 -0
  116. package/out/pipeline/reconcile.d.ts.map +1 -0
  117. package/out/pipeline/reconcile.js +355 -0
  118. package/out/pipeline/reconcile.js.map +1 -0
  119. package/out/pipeline/runtime-pipeline.d.ts +29 -0
  120. package/out/pipeline/runtime-pipeline.d.ts.map +1 -0
  121. package/out/pipeline/runtime-pipeline.js +339 -0
  122. package/out/pipeline/runtime-pipeline.js.map +1 -0
  123. package/out/pipeline/span-logit-aggregation.d.ts +57 -0
  124. package/out/pipeline/span-logit-aggregation.d.ts.map +1 -0
  125. package/out/pipeline/span-logit-aggregation.js +105 -0
  126. package/out/pipeline/span-logit-aggregation.js.map +1 -0
  127. package/out/pipeline/types.d.ts +215 -0
  128. package/out/pipeline/types.d.ts.map +1 -0
  129. package/out/pipeline/types.js +16 -0
  130. package/out/pipeline/types.js.map +1 -0
  131. package/out/resolver/index.d.ts +9 -0
  132. package/out/resolver/index.d.ts.map +1 -0
  133. package/out/resolver/index.js +8 -0
  134. package/out/resolver/index.js.map +1 -0
  135. package/out/resolver/resolve.d.ts +21 -0
  136. package/out/resolver/resolve.d.ts.map +1 -0
  137. package/out/resolver/resolve.js +118 -0
  138. package/out/resolver/resolve.js.map +1 -0
  139. package/out/resolver/types.d.ts +118 -0
  140. package/out/resolver/types.d.ts.map +1 -0
  141. package/out/resolver/types.js +26 -0
  142. package/out/resolver/types.js.map +1 -0
  143. package/out/resources/git.d.ts +1 -1
  144. package/out/resources/index.d.ts +0 -1
  145. package/out/resources/index.d.ts.map +1 -1
  146. package/out/resources/index.js +0 -1
  147. package/out/resources/index.js.map +1 -1
  148. package/out/resources/whosonfirst/DataSourceCache.d.ts +0 -1
  149. package/out/resources/whosonfirst/DataSourceCache.d.ts.map +1 -1
  150. package/out/resources/whosonfirst/DataSourceCache.js +0 -1
  151. package/out/resources/whosonfirst/DataSourceCache.js.map +1 -1
  152. package/out/resources/whosonfirst/PlacetypeDataSource.d.ts +2 -2
  153. package/out/resources/whosonfirst/PlacetypeDataSource.d.ts.map +1 -1
  154. package/out/resources/whosonfirst/PlacetypeDataSource.js +9 -6
  155. package/out/resources/whosonfirst/PlacetypeDataSource.js.map +1 -1
  156. package/out/resources/whosonfirst/placetypes/admin.d.ts +23 -1
  157. package/out/resources/whosonfirst/placetypes/admin.d.ts.map +1 -1
  158. package/out/resources/whosonfirst/placetypes/admin.js +14 -1
  159. package/out/resources/whosonfirst/placetypes/admin.js.map +1 -1
  160. package/out/routing/index.d.ts +67 -0
  161. package/out/routing/index.d.ts.map +1 -0
  162. package/out/routing/index.js +114 -0
  163. package/out/routing/index.js.map +1 -0
  164. package/out/sets.d.ts +2 -0
  165. package/out/sets.d.ts.map +1 -0
  166. package/out/sets.js +2 -0
  167. package/out/sets.js.map +1 -0
  168. package/package.json +28 -2
  169. package/out/resources/db/index.d.ts +0 -57
  170. package/out/resources/db/index.d.ts.map +0 -1
  171. package/out/resources/db/index.js +0 -57
  172. package/out/resources/db/index.js.map +0 -1
@@ -0,0 +1,215 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Types for the runtime pipeline coordinator (`runPipeline`).
7
+ *
8
+ * Generic over its stage implementations — each stage is an injected function or class, defined
9
+ * structurally. Keeps `@mailwoman/core` free of dependencies on the concrete neural / normalize /
10
+ * query-shape / resolver packages while still composing them at runtime when callers wire them
11
+ * up.
12
+ *
13
+ * See `docs/articles/plan/reference/STAGES.md` for the full contract this implements.
14
+ */
15
+ import type { AddressTree } from "../decoder/types.js";
16
+ import type { ResolveOpts, Resolver } from "../resolver/types.js";
17
+ import type { Section } from "../types/classifier.js";
18
+ export type LocaleTag = string;
19
+ /** Optional user-location signal for Stage 6 resolver scoring. */
20
+ export type UserLocation = {
21
+ lat: number;
22
+ lon: number;
23
+ } | {
24
+ country: string;
25
+ } | {
26
+ region: string;
27
+ country: string;
28
+ };
29
+ /** Common opts threaded through every stage. */
30
+ export interface PipelineOpts {
31
+ locale?: LocaleTag;
32
+ userLocation?: UserLocation;
33
+ /** Disable fast-path shortcuts; always run the full pipeline. */
34
+ forceFullPipeline?: boolean;
35
+ /**
36
+ * Enable the joint-reconcile path (Stage 5 beam search). Opt-in until phrase-grouper proposal
37
+ * quality supports multi-word streets/localities — currently produces single-token spans.
38
+ * Requires phrase grouper + classifier with `parseWithLogits`.
39
+ */
40
+ forceJointReconcile?: boolean;
41
+ /** Hard cap on lookups the resolver may issue; passed through. */
42
+ resolveOpts?: ResolveOpts;
43
+ signal?: AbortSignal;
44
+ }
45
+ /** Minimal structural shape `NormalizedInput` must satisfy. Compatible with @mailwoman/normalize. */
46
+ export interface NormalizedInputLite {
47
+ raw: string;
48
+ normalized: string;
49
+ appliedLocale?: string;
50
+ }
51
+ /** Minimal structural shape `QueryShape` must satisfy. Compatible with @mailwoman/query-shape. */
52
+ export interface QueryShapeLite {
53
+ knownFormats: ReadonlyArray<{
54
+ format: string;
55
+ span: {
56
+ start: number;
57
+ end: number;
58
+ };
59
+ confidence: number;
60
+ }>;
61
+ segments?: ReadonlyArray<{
62
+ body: string;
63
+ index: number;
64
+ }>;
65
+ characterClass?: string;
66
+ totalLength?: number;
67
+ }
68
+ /** Detected (or asserted) locale + alternatives. */
69
+ export interface LocaleHint {
70
+ locale: LocaleTag;
71
+ confidence: number;
72
+ alternatives: ReadonlyArray<{
73
+ locale: LocaleTag;
74
+ confidence: number;
75
+ }>;
76
+ source: "caller" | "detected" | "ensemble";
77
+ }
78
+ /** Kind classifier output. */
79
+ export type QueryKind = "postcode_only" | "locality_only" | "structured_address" | "intersection" | "po_box" | "landmark" | "vague";
80
+ export interface QueryKindResult {
81
+ kind: QueryKind;
82
+ confidence: number;
83
+ alternatives: ReadonlyArray<{
84
+ kind: QueryKind;
85
+ confidence: number;
86
+ }>;
87
+ }
88
+ /**
89
+ * Stage 2.7 phrase grouper output. Coarse phrase-shape hypothesis attached to a `Section` (sub-Span
90
+ * of the tokenized input). The classifier (Stage 3) conditions on these proposals so it can answer
91
+ * the simpler "what type is this proposed span?" instead of jointly discovering boundaries and
92
+ * types. The reconciler (Stage 5) consumes them as boundary candidates for joint decoding.
93
+ *
94
+ * Taxonomy is purely structural — no place-name knowledge. A `LOCALITY_PHRASE` proposal is "this
95
+ * looks shaped like a multi-word capitalized phrase that could be a city name" — not "this IS New
96
+ * York." Typing the span is the classifier's job.
97
+ *
98
+ * See `docs/articles/concepts/the-knowledge-ladder.md` § Phrase grouper for the design rationale.
99
+ */
100
+ export type PhraseKind = "NUMERIC" | "STREET_PHRASE" | "LOCALITY_PHRASE" | "REGION_ABBREVIATION" | "POSTCODE" | "VENUE_PHRASE" | "HYPHENATED_COMPOUND";
101
+ /**
102
+ * One phrase proposal emitted by Stage 2.7. The contract:
103
+ *
104
+ * - `span`: the input slice (sub-Span of the tokenized input) the proposal applies to.
105
+ * - `kindHypothesis`: structural shape this slice looks like.
106
+ * - `confidence`: 0..1 score. Used by downstream stages to weight proposals.
107
+ *
108
+ * Per "possibilities not constraints", emit a proposal whenever a rule fires — overlapping
109
+ * proposals over the same tokens are expected (e.g. `Saint Petersburg` may surface as one
110
+ * `LOCALITY_PHRASE` AND two `LOCALITY_PHRASE`s, with confidence ordering signalling which the
111
+ * grouper prefers).
112
+ */
113
+ export interface PhraseProposal {
114
+ span: Section;
115
+ kindHypothesis: PhraseKind;
116
+ confidence: number;
117
+ }
118
+ /**
119
+ * Stage 2.7 contract. Structural — any of the rule-based grouper (`@mailwoman/phrase-grouper`), a
120
+ * learned span proposer (future), or a fake for tests satisfies this. Async so the coordinator can
121
+ * stay uniform even when implementations call into models.
122
+ */
123
+ export interface PhraseGrouper {
124
+ group(input: NormalizedInputLite, shape: QueryShapeLite, locale: LocaleHint): Promise<PhraseProposal[]>;
125
+ }
126
+ /**
127
+ * Stage 3 contract: classifier that turns a text into an `AddressTree`. Structural — any of
128
+ * `@mailwoman/neural`'s `NeuralAddressClassifier`, a rule-based classifier, or a fake for tests
129
+ * satisfies this.
130
+ */
131
+ /**
132
+ * Structural type for the FST gazetteer matcher, compatible with @mailwoman/resolver-wof-sqlite's
133
+ * FstMatcher.
134
+ */
135
+ export interface FstMatcherLike {
136
+ walk(tokens: string[]): {
137
+ stateId: number;
138
+ accepted: boolean;
139
+ depth: number;
140
+ } | null;
141
+ walkFrom(prev: {
142
+ stateId: number;
143
+ depth: number;
144
+ }, token: string): {
145
+ stateId: number;
146
+ accepted: boolean;
147
+ depth: number;
148
+ } | null;
149
+ accepting(stateId: number): Array<{
150
+ wofID: number;
151
+ placetype: string;
152
+ importance: number;
153
+ }>;
154
+ }
155
+ export interface ClassifierOpts {
156
+ queryShape?: QueryShapeLite;
157
+ fst?: FstMatcherLike;
158
+ fstBiasScale?: number;
159
+ }
160
+ export interface AddressClassifier {
161
+ parse(text: string, opts?: ClassifierOpts): Promise<AddressTree>;
162
+ }
163
+ /**
164
+ * Injectable stage implementations. All optional — when a stage is absent, the coordinator either
165
+ * skips it (resolver) or substitutes a no-op stub (normalize / queryShape / locale gate / kind
166
+ * classifier). The classifier is required for the full pipeline path; without it, the coordinator
167
+ * can only fast-path on QueryShape known-formats.
168
+ */
169
+ export interface RuntimePipelineStages {
170
+ normalize?: (raw: string, opts?: {
171
+ locale?: string;
172
+ }) => NormalizedInputLite;
173
+ computeQueryShape?: (input: NormalizedInputLite | string, opts?: {
174
+ locale?: string;
175
+ }) => QueryShapeLite;
176
+ detectLocale?: (input: NormalizedInputLite, shape: QueryShapeLite, opts?: {
177
+ hint?: LocaleTag;
178
+ }) => Promise<LocaleHint>;
179
+ classifyKind?: (input: NormalizedInputLite, shape: QueryShapeLite, locale: LocaleHint) => Promise<QueryKindResult>;
180
+ /**
181
+ * Stage 2.7 phrase grouper. Emits coherent input-unit proposals consumed by Stage 3 (as
182
+ * conditioning) and Stage 5 (as boundary candidates). Hard dep in v0.5.0; pre-v0.5.0 callers run
183
+ * with no grouper and the result `phraseProposals` field is empty.
184
+ */
185
+ groupPhrases?: (input: NormalizedInputLite, shape: QueryShapeLite, locale: LocaleHint) => Promise<PhraseProposal[]>;
186
+ classifier?: AddressClassifier;
187
+ /**
188
+ * Pre-built FST gazetteer matcher. When provided, gazetteer matches produce additive emission
189
+ * biases during classification.
190
+ */
191
+ fst?: FstMatcherLike;
192
+ resolver?: Resolver;
193
+ }
194
+ export interface PipelineTiming {
195
+ [stage: string]: number;
196
+ }
197
+ /** Result of one `runPipeline` call. */
198
+ export interface PipelineResult {
199
+ input: string;
200
+ normalized: NormalizedInputLite;
201
+ queryShape: QueryShapeLite;
202
+ locale: LocaleHint;
203
+ kind: QueryKindResult;
204
+ /**
205
+ * Stage 2.7 phrase proposals when a grouper was wired. Empty array when the coordinator ran with
206
+ * no grouper (pre-v0.5.0 callers) or when the fast-path skipped Stage 2.7. Stage 3 consumes this
207
+ * as conditioning; Stage 5 consumes it as boundary candidates.
208
+ */
209
+ phraseProposals: PhraseProposal[];
210
+ tree: AddressTree;
211
+ timing: PipelineTiming;
212
+ /** Which path the coordinator took. `"fast-path"` skipped stages 3-5. */
213
+ path: "fast-path" | "full";
214
+ }
215
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../pipeline/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Types for the runtime pipeline coordinator (`runPipeline`).
7
+ *
8
+ * Generic over its stage implementations — each stage is an injected function or class, defined
9
+ * structurally. Keeps `@mailwoman/core` free of dependencies on the concrete neural / normalize /
10
+ * query-shape / resolver packages while still composing them at runtime when callers wire them
11
+ * up.
12
+ *
13
+ * See `docs/articles/plan/reference/STAGES.md` for the full contract this implements.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../pipeline/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ export { createWofResolver } from "./resolve.js";
7
+ export { DEFAULT_PLACETYPE_MAP } from "./types.js";
8
+ export type { PlacetypeMap, ResolveOpts, ResolvedPlace, Resolver, ResolverBackend } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../resolver/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAClD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ export { createWofResolver } from "./resolve.js";
7
+ export { DEFAULT_PLACETYPE_MAP } from "./types.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../resolver/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `resolveTree` — walk an `AddressTree` top-down and decorate matched nodes with resolver- supplied
7
+ * attribution + coordinates.
8
+ *
9
+ * The walk is parent-constraint-aware: when a parent node resolves to a place id, its children's
10
+ * lookups are scoped to descendants of that parent. This dramatically narrows the search space
11
+ * for ambiguous names — `Springfield` under a resolved `Illinois` parent resolves to the IL one,
12
+ * not the MA one.
13
+ */
14
+ import { type Resolver, type ResolverBackend } from "./types.js";
15
+ /**
16
+ * Build a `Resolver` backed by a `ResolverBackend`. The backend can be any concrete impl
17
+ * structurally compatible with `PlaceLookup` — e.g. `new WofSqlitePlaceLookup({ databasePath
18
+ * }).asResolverBackend()` or a fake for tests.
19
+ */
20
+ export declare function createWofResolver(backend: ResolverBackend): Resolver;
21
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../resolver/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAKN,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,QAAQ,CAEpE"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `resolveTree` — walk an `AddressTree` top-down and decorate matched nodes with resolver- supplied
7
+ * attribution + coordinates.
8
+ *
9
+ * The walk is parent-constraint-aware: when a parent node resolves to a place id, its children's
10
+ * lookups are scoped to descendants of that parent. This dramatically narrows the search space
11
+ * for ambiguous names — `Springfield` under a resolved `Illinois` parent resolves to the IL one,
12
+ * not the MA one.
13
+ */
14
+ import { DEFAULT_PLACETYPE_MAP, } from "./types.js";
15
+ /**
16
+ * Build a `Resolver` backed by a `ResolverBackend`. The backend can be any concrete impl
17
+ * structurally compatible with `PlaceLookup` — e.g. `new WofSqlitePlaceLookup({ databasePath
18
+ * }).asResolverBackend()` or a fake for tests.
19
+ */
20
+ export function createWofResolver(backend) {
21
+ return new WofResolver(backend);
22
+ }
23
+ class WofResolver {
24
+ #backend;
25
+ constructor(backend) {
26
+ this.#backend = backend;
27
+ }
28
+ async resolveTree(tree, opts = {}) {
29
+ const state = {
30
+ lookupsRemaining: opts.maxLookups ?? 10,
31
+ // Full replacement when `placetypeMap` is supplied — callers that want to extend rather
32
+ // than replace should spread DEFAULT_PLACETYPE_MAP themselves.
33
+ placetypeMap: opts.placetypeMap ?? DEFAULT_PLACETYPE_MAP,
34
+ minWinningScore: opts.minWinningScore ?? 0,
35
+ candidatesPerLookup: opts.candidatesPerLookup ?? 5,
36
+ };
37
+ const newRoots = [];
38
+ for (const root of tree.roots) {
39
+ newRoots.push(await this.#walk(root, /* parentResolved */ null, state));
40
+ }
41
+ return { raw: tree.raw, roots: newRoots };
42
+ }
43
+ async #walk(node, parentResolved, state) {
44
+ // Always clone — never mutate input nodes.
45
+ const decorated = { ...node, children: [] };
46
+ const placetype = state.placetypeMap[node.tag];
47
+ let resolved = null;
48
+ if (placetype && state.lookupsRemaining > 0 && node.value.trim().length > 0) {
49
+ const picked = await this.#lookupAndPick(node, placetype, parentResolved, state);
50
+ if (picked) {
51
+ resolved = picked.top;
52
+ decorateNode(decorated, picked.top, picked.alternatives);
53
+ }
54
+ }
55
+ const carryParent = resolved ?? parentResolved;
56
+ for (const child of node.children) {
57
+ decorated.children.push(await this.#walk(child, carryParent, state));
58
+ }
59
+ return decorated;
60
+ }
61
+ async #lookupAndPick(node, placetype, parentResolved, state) {
62
+ state.lookupsRemaining--;
63
+ const query = {
64
+ text: node.value,
65
+ placetype,
66
+ limit: state.candidatesPerLookup,
67
+ };
68
+ // Pass the inherited parent constraint to the backend when available — both `parentId` and
69
+ // `country` are valid narrowing hints depending on what the parent resolved to.
70
+ if (parentResolved) {
71
+ if (typeof parentResolved.id === "number")
72
+ query.parentId = parentResolved.id;
73
+ if (parentResolved.country)
74
+ query.country = parentResolved.country;
75
+ }
76
+ let candidates;
77
+ try {
78
+ candidates = await this.#backend.findPlace(query);
79
+ }
80
+ catch {
81
+ // Defensive: a backend failure should not abort the whole tree walk. Leave the node with
82
+ // its classifier attribution intact.
83
+ return null;
84
+ }
85
+ if (candidates.length === 0)
86
+ return null;
87
+ const top = candidates[0];
88
+ if (top.score < state.minWinningScore)
89
+ return null;
90
+ return { top, alternatives: candidates.slice(1) };
91
+ }
92
+ }
93
+ /**
94
+ * Stamp a node with resolver-supplied attribution. Displaces any prior classifier `source` /
95
+ * `sourceId` into `metadata.classifier_source` / `metadata.classifier_source_id` so debugging tools
96
+ * can still see who made the original assertion. Surfaces the runner-up candidates on
97
+ * `alternatives` so callers can disambiguate (Springfield-class failures, [#8 in the failure
98
+ * catalogue]).
99
+ */
100
+ function decorateNode(node, resolved, alternatives) {
101
+ if (node.source !== undefined || node.sourceId !== undefined) {
102
+ const meta = { ...(node.metadata ?? {}) };
103
+ if (node.source !== undefined)
104
+ meta["classifier_source"] = node.source;
105
+ if (node.sourceId !== undefined)
106
+ meta["classifier_source_id"] = node.sourceId;
107
+ node.metadata = meta;
108
+ }
109
+ node.source = "resolver";
110
+ node.sourceId = `${resolved.placetype}:${resolved.id}`;
111
+ node.lat = resolved.lat;
112
+ node.lon = resolved.lon;
113
+ node.placeId = `wof:${resolved.id}`; // v1: only WOF resolvers; the URI scheme stays this simple
114
+ if (alternatives.length > 0) {
115
+ node.alternatives = alternatives;
116
+ }
117
+ }
118
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../resolver/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACN,qBAAqB,GAMrB,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACzD,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC;AASD,MAAM,WAAW;IACP,QAAQ,CAAiB;IAElC,YAAY,OAAwB;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAiB,EAAE,OAAoB,EAAE;QAC1D,MAAM,KAAK,GAAoB;YAC9B,gBAAgB,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;YACvC,wFAAwF;YACxF,+DAA+D;YAC/D,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,qBAAqB;YACxD,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,CAAC;YAC1C,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,IAAI,CAAC;SAClD,CAAA;QAED,MAAM,QAAQ,GAAkB,EAAE,CAAA;QAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;QACxE,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAiB,EAAE,cAAoC,EAAE,KAAsB;QAC1F,2CAA2C;QAC3C,MAAM,SAAS,GAAgB,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;QAExD,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAmB,CAAC,CAAA;QAC9D,IAAI,QAAQ,GAAyB,IAAI,CAAA;QACzC,IAAI,SAAS,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,CAAA;YAChF,IAAI,MAAM,EAAE,CAAC;gBACZ,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAA;gBACrB,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;YACzD,CAAC;QACF,CAAC;QAED,MAAM,WAAW,GAAG,QAAQ,IAAI,cAAc,CAAA;QAC9C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAA;QACrE,CAAC;QACD,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,IAAiB,EACjB,SAAiB,EACjB,cAAoC,EACpC,KAAsB;QAEtB,KAAK,CAAC,gBAAgB,EAAE,CAAA;QAExB,MAAM,KAAK,GAAgD;YAC1D,IAAI,EAAE,IAAI,CAAC,KAAK;YAChB,SAAS;YACT,KAAK,EAAE,KAAK,CAAC,mBAAmB;SAChC,CAAA;QACD,2FAA2F;QAC3F,gFAAgF;QAChF,IAAI,cAAc,EAAE,CAAC;YACpB,IAAI,OAAO,cAAc,CAAC,EAAE,KAAK,QAAQ;gBAAE,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAA;YAC7E,IAAI,cAAc,CAAC,OAAO;gBAAE,KAAK,CAAC,OAAO,GAAG,cAAc,CAAC,OAAO,CAAA;QACnE,CAAC;QAED,IAAI,UAA2B,CAAA;QAC/B,IAAI,CAAC;YACJ,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QAClD,CAAC;QAAC,MAAM,CAAC;YACR,yFAAyF;YACzF,qCAAqC;YACrC,OAAO,IAAI,CAAA;QACZ,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACxC,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAE,CAAA;QAC1B,IAAI,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,eAAe;YAAE,OAAO,IAAI,CAAA;QAClD,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;IAClD,CAAC;CACD;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,IAAiB,EAAE,QAAuB,EAAE,YAA6B;IAC9F,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC9D,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAA;QACzC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,mBAAmB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;QACtE,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;YAAE,IAAI,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7E,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;IACrB,CAAC;IACD,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;IACxB,IAAI,CAAC,QAAQ,GAAG,GAAG,QAAQ,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAA;IACtD,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAA;IACvB,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAA;IACvB,IAAI,CAAC,OAAO,GAAG,OAAO,QAAQ,CAAC,EAAE,EAAE,CAAA,CAAC,2DAA2D;IAC/F,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IACjC,CAAC;AACF,CAAC"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Resolver interface for Phase 4.3 — wires the address-component decoder to a place-id / coordinate
7
+ * lookup backend.
8
+ *
9
+ * The interface is deliberately decoupled from any specific resolver implementation. The first
10
+ * shipped impl is `@mailwoman/resolver-wof-sqlite`, but the same contract supports a future
11
+ * `RemoteResolver` adapter (Phase 4.4 — Pelias / BAN / Nominatim) without a public-API break.
12
+ *
13
+ * See `docs/plan/phases/PHASE_4_3_resolver_integration.md` for the design intent.
14
+ */
15
+ import type { AddressTree, ComponentTag } from "../decoder/types.js";
16
+ /**
17
+ * One candidate place returned by a resolver. Mirrors the shape used by
18
+ * `@mailwoman/resolver-wof-sqlite`'s `PlaceCandidate` — kept structurally compatible so a callsite
19
+ * holding a `PlaceCandidate` can be passed where a `ResolvedPlace` is expected.
20
+ */
21
+ export interface ResolvedPlace {
22
+ /** Resolver-specific place identifier (e.g. WOF id). */
23
+ id: number | string;
24
+ /** Canonical name of the place as the resolver knows it. */
25
+ name: string;
26
+ /** Resolver's placetype taxonomy label (e.g. WOF's `country` / `region` / `locality`). */
27
+ placetype: string;
28
+ /** ISO 3166-1 alpha-2 country code, if known. */
29
+ country: string;
30
+ /** Centroid latitude in WGS-84 decimal degrees. */
31
+ lat: number;
32
+ /** Centroid longitude in WGS-84 decimal degrees. */
33
+ lon: number;
34
+ /** Parent place id within the resolver's hierarchy, if any. */
35
+ parent_id?: number | string;
36
+ /**
37
+ * Resolver-defined ranking score. Higher = better fit for the query. Scale is implementation-
38
+ * defined; callers should treat as ordinal.
39
+ */
40
+ score: number;
41
+ }
42
+ /**
43
+ * Pull-based contract for a single resolver query. The resolver knows nothing about `AddressTree` —
44
+ * it just answers "what place is named X, optionally constrained by Y?"
45
+ *
46
+ * Structurally compatible with `PlaceLookup` from `@mailwoman/resolver-wof-sqlite` so the latter
47
+ * satisfies this interface without an adapter shim.
48
+ */
49
+ export interface ResolverBackend {
50
+ findPlace(query: {
51
+ text: string;
52
+ placetype?: string | string[];
53
+ country?: string;
54
+ parentId?: number | string;
55
+ limit?: number;
56
+ }): Promise<ResolvedPlace[]>;
57
+ }
58
+ /**
59
+ * Options for `resolveTree`. All optional with sensible defaults.
60
+ */
61
+ export interface ResolveOpts {
62
+ /**
63
+ * Hard cap on how many backend lookups one tree may issue. Default 10. Prevents a tree with
64
+ * dozens of candidate nodes from triggering dozens of queries.
65
+ */
66
+ maxLookups?: number;
67
+ /**
68
+ * Minimum candidate score before resolver attribution wins over the classifier's. Default 0. A
69
+ * higher threshold makes the resolver more conservative — it leaves more nodes with classifier
70
+ * provenance. Score scale is implementation-defined; tune per backend.
71
+ */
72
+ minWinningScore?: number;
73
+ /**
74
+ * Maximum candidates to request from the backend per lookup. Default 5 — we only use the top
75
+ * candidate after post-scoring, but the backend may benefit from over-fetching for ranking.
76
+ */
77
+ candidatesPerLookup?: number;
78
+ /**
79
+ * Override the default ComponentTag → resolver-placetype mapping. When set, this map FULLY
80
+ * REPLACES `DEFAULT_PLACETYPE_MAP` — start from the default by spreading it (`{
81
+ * ...DEFAULT_PLACETYPE_MAP, ... }`) if you want to extend rather than replace. The fully-
82
+ * replacing semantics let callers narrow the resolver scope (e.g. drop `locality` if the backend
83
+ * doesn't ship locality data for the current locale) without awkward `undefined`-as-delete
84
+ * tricks.
85
+ */
86
+ placetypeMap?: PlacetypeMap;
87
+ /**
88
+ * Optional locale hint. Currently unused by the v1 resolver but reserved so the contract doesn't
89
+ * break when locale-aware resolvers land in 4.4+.
90
+ */
91
+ locale?: string;
92
+ }
93
+ /**
94
+ * Mapping from mailwoman's address-component tags to the resolver's placetype taxonomy. Components
95
+ * not present in the map are NOT queried — the resolver pass leaves their classifier attribution
96
+ * untouched.
97
+ *
98
+ * Phase 4.3 default ships the obvious admin-level mappings; other tags (postcode, street, venue,
99
+ * dependent_locality, prefecture, etc.) are explicitly omitted because:
100
+ *
101
+ * - `postcode` lives in a separate WOF shard (Phase 4.3.x follow-up via the postalcode loader).
102
+ * - `street` / `house_number` aren't in WOF admin — would need OSM / OpenAddresses gazetteers and
103
+ * license diligence (Phase 4.4 candidate).
104
+ * - Non-US JP-specific tags wait on a different shard entirely.
105
+ */
106
+ export type PlacetypeMap = Partial<Record<ComponentTag, string>>;
107
+ export declare const DEFAULT_PLACETYPE_MAP: PlacetypeMap;
108
+ /**
109
+ * The interface implemented by `createWofResolver` and any future resolver factories.
110
+ *
111
+ * `resolveTree` returns a NEW `AddressTree` rather than mutating — keeps the input safe to inspect
112
+ * after the call. The new tree's `roots` are fresh `AddressNode` objects; nodes the resolver didn't
113
+ * touch are structurally cloned with their classifier attribution preserved.
114
+ */
115
+ export interface Resolver {
116
+ resolveTree(tree: AddressTree, opts?: ResolveOpts): Promise<AddressTree>;
117
+ }
118
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../resolver/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEpE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,wDAAwD;IACxD,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAA;IACX,oDAAoD;IACpD,GAAG,EAAE,MAAM,CAAA;IACX,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC3B;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;CACb;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,SAAS,CAAC,KAAK,EAAE;QAChB,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;QAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;KACd,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAA;AAEhE,eAAO,MAAM,qBAAqB,EAAE,YAUnC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,WAAW,QAAQ;IACxB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CACxE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * Resolver interface for Phase 4.3 — wires the address-component decoder to a place-id / coordinate
7
+ * lookup backend.
8
+ *
9
+ * The interface is deliberately decoupled from any specific resolver implementation. The first
10
+ * shipped impl is `@mailwoman/resolver-wof-sqlite`, but the same contract supports a future
11
+ * `RemoteResolver` adapter (Phase 4.4 — Pelias / BAN / Nominatim) without a public-API break.
12
+ *
13
+ * See `docs/plan/phases/PHASE_4_3_resolver_integration.md` for the design intent.
14
+ */
15
+ export const DEFAULT_PLACETYPE_MAP = {
16
+ country: "country",
17
+ region: "region",
18
+ locality: "locality",
19
+ dependent_locality: "locality",
20
+ subregion: "county",
21
+ // `postcode` (mailwoman tag) maps to WOF's `postalcode` placetype. Resolves only when the
22
+ // backend has the postcode shard available — `WofSqlitePlaceLookup` auto-routes `postalcode`
23
+ // queries to a `postalcode_us` (or similarly-named) shard, falling back to main if absent.
24
+ postcode: "postalcode",
25
+ };
26
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../resolver/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmGH,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IAClD,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,kBAAkB,EAAE,UAAU;IAC9B,SAAS,EAAE,QAAQ;IACnB,0FAA0F;IAC1F,6FAA6F;IAC7F,2FAA2F;IAC3F,QAAQ,EAAE,YAAY;CACtB,CAAA"}
@@ -15,7 +15,7 @@ export interface RepositorySource {
15
15
  export declare function prepareRepositoryDirectories({ name, owner }: RepositorySource, localRepoDirectory: PathBuilderLike): Promise<{
16
16
  ownerDirectory: PathBuilder<`${string}/${string}`>;
17
17
  repoDirectory: PathBuilder<`${string}/${string}/${string}`>;
18
- exists: import("fs").Stats | null;
18
+ exists: import("node:fs").Stats | null;
19
19
  }>;
20
20
  /**
21
21
  * Synchronize a repository source, i.e. clone or pull the repository.
@@ -4,7 +4,6 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
  export * from "./collections.js";
7
- export * from "./db/index.js";
8
7
  export * from "./debugging.js";
9
8
  export * from "./fs.js";
10
9
  export * from "./git.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA"}
@@ -4,7 +4,6 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
  export * from "./collections.js";
7
- export * from "./db/index.js";
8
7
  export * from "./debugging.js";
9
8
  export * from "./fs.js";
10
9
  export * from "./git.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,UAAU,CAAA;AACxB,cAAc,wBAAwB,CAAA"}
@@ -3,7 +3,6 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
- import "core-js/actual/disposable-stack/index.js";
7
6
  import { PlacetypeDataSource, type PlacetypeDataSourceOptions } from "./PlacetypeDataSource.js";
8
7
  export declare class DataSourceCache extends DisposableStack {
9
8
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"DataSourceCache.d.ts","sourceRoot":"","sources":["../../../resources/whosonfirst/DataSourceCache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,0CAA0C,CAAA;AAMjD,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAG/F,qBAAa,eAAgB,SAAQ,eAAe;;IAGnC,CAAC,MAAM,CAAC,WAAW,CAAC,SAAoB;IAExC,CAAC,MAAM,CAAC,OAAO,CAAC;IAMzB,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE,0BAA0B,GAAG,mBAAmB;CAsBxG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBvF"}
1
+ {"version":3,"file":"DataSourceCache.d.ts","sourceRoot":"","sources":["../../../resources/whosonfirst/DataSourceCache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AAG/F,qBAAa,eAAgB,SAAQ,eAAe;;IAGnC,CAAC,MAAM,CAAC,WAAW,CAAC,SAAoB;IAExC,CAAC,MAAM,CAAC,OAAO,CAAC;IAMzB,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE,0BAA0B,GAAG,mBAAmB;CAsBxG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBvF"}
@@ -3,7 +3,6 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
- import "core-js/actual/disposable-stack/index.js";
7
6
  import { mkdirSync } from "node:fs";
8
7
  import { setTimeout } from "node:timers/promises";
9
8
  import { dirname } from "path-ts";