@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.
- package/out/api/APIClient.d.ts +57 -0
- package/out/api/APIClient.d.ts.map +1 -0
- package/out/api/APIClient.js +108 -0
- package/out/api/APIClient.js.map +1 -0
- package/out/api/headless.d.ts +17 -0
- package/out/api/headless.d.ts.map +1 -0
- package/out/api/headless.js +18 -0
- package/out/api/headless.js.map +1 -0
- package/out/api/index.d.ts +11 -0
- package/out/api/index.d.ts.map +1 -0
- package/out/api/index.js +11 -0
- package/out/api/index.js.map +1 -0
- package/out/api/responses.d.ts +48 -0
- package/out/api/responses.d.ts.map +1 -0
- package/out/api/responses.js +68 -0
- package/out/api/responses.js.map +1 -0
- package/out/collections.d.ts +66 -0
- package/out/collections.d.ts.map +1 -0
- package/out/collections.js +97 -0
- package/out/collections.js.map +1 -0
- package/out/db/schema.d.ts +21 -0
- package/out/db/schema.d.ts.map +1 -0
- package/out/db/schema.js +16 -0
- package/out/db/schema.js.map +1 -0
- package/out/decoder/build-tree.d.ts +14 -1
- package/out/decoder/build-tree.d.ts.map +1 -1
- package/out/decoder/build-tree.js +37 -9
- package/out/decoder/build-tree.js.map +1 -1
- package/out/decoder/proposals-to-tree.d.ts.map +1 -1
- package/out/decoder/proposals-to-tree.js +2 -0
- package/out/decoder/proposals-to-tree.js.map +1 -1
- package/out/decoder/serialize-xml.d.ts +22 -1
- package/out/decoder/serialize-xml.d.ts.map +1 -1
- package/out/decoder/serialize-xml.js +64 -4
- package/out/decoder/serialize-xml.js.map +1 -1
- package/out/decoder/types.d.ts +45 -0
- package/out/decoder/types.d.ts.map +1 -1
- package/out/decoder/types.js +6 -0
- package/out/decoder/types.js.map +1 -1
- package/out/errors/index.d.ts +9 -0
- package/out/errors/index.d.ts.map +1 -0
- package/out/errors/index.js +9 -0
- package/out/errors/index.js.map +1 -0
- package/out/errors/schema.d.ts +69 -0
- package/out/errors/schema.d.ts.map +1 -0
- package/out/errors/schema.js +102 -0
- package/out/errors/schema.js.map +1 -0
- package/out/identifiers.d.ts +18 -0
- package/out/identifiers.d.ts.map +1 -0
- package/out/identifiers.js +49 -0
- package/out/identifiers.js.map +1 -0
- package/out/index.d.ts +3 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +3 -4
- package/out/index.js.map +1 -1
- package/out/kysley/adapter.d.ts +13 -0
- package/out/kysley/adapter.d.ts.map +1 -0
- package/out/kysley/adapter.js +25 -0
- package/out/kysley/adapter.js.map +1 -0
- package/out/kysley/client.d.ts +16 -0
- package/out/kysley/client.d.ts.map +1 -0
- package/out/kysley/client.js +22 -0
- package/out/kysley/client.js.map +1 -0
- package/out/kysley/dialect-config.d.ts +27 -0
- package/out/kysley/dialect-config.d.ts.map +1 -0
- package/out/kysley/dialect-config.js +7 -0
- package/out/kysley/dialect-config.js.map +1 -0
- package/out/kysley/dialect.d.ts +39 -0
- package/out/kysley/dialect.d.ts.map +1 -0
- package/out/kysley/dialect.js +49 -0
- package/out/kysley/dialect.js.map +1 -0
- package/out/kysley/driver.d.ts +22 -0
- package/out/kysley/driver.d.ts.map +1 -0
- package/out/kysley/driver.js +114 -0
- package/out/kysley/driver.js.map +1 -0
- package/out/lifecycle/ServiceSymbol.d.ts +59 -0
- package/out/lifecycle/ServiceSymbol.d.ts.map +1 -0
- package/out/lifecycle/ServiceSymbol.js +62 -0
- package/out/lifecycle/ServiceSymbol.js.map +1 -0
- package/out/lifecycle/index.d.ts +11 -0
- package/out/lifecycle/index.d.ts.map +1 -0
- package/out/lifecycle/index.js +11 -0
- package/out/lifecycle/index.js.map +1 -0
- package/out/lifecycle/lru-cache.d.ts +22 -0
- package/out/lifecycle/lru-cache.d.ts.map +1 -0
- package/out/lifecycle/lru-cache.js +31 -0
- package/out/lifecycle/lru-cache.js.map +1 -0
- package/out/lifecycle/services.d.ts +145 -0
- package/out/lifecycle/services.d.ts.map +1 -0
- package/out/lifecycle/services.js +190 -0
- package/out/lifecycle/services.js.map +1 -0
- package/out/logging/index.d.ts +7 -0
- package/out/logging/index.d.ts.map +1 -0
- package/out/logging/index.js +7 -0
- package/out/logging/index.js.map +1 -0
- package/out/logging/shared.d.ts +60 -0
- package/out/logging/shared.d.ts.map +1 -0
- package/out/logging/shared.js +100 -0
- package/out/logging/shared.js.map +1 -0
- package/out/logging/tables.d.ts +7 -0
- package/out/logging/tables.d.ts.map +1 -0
- package/out/logging/tables.js +75 -0
- package/out/logging/tables.js.map +1 -0
- package/out/objects.d.ts +96 -0
- package/out/objects.d.ts.map +1 -0
- package/out/objects.js +96 -0
- package/out/objects.js.map +1 -0
- package/out/parser/proposal-pipeline.d.ts.map +1 -1
- package/out/parser/proposal-pipeline.js +0 -1
- package/out/parser/proposal-pipeline.js.map +1 -1
- package/out/pipeline/index.d.ts +14 -0
- package/out/pipeline/index.d.ts.map +1 -0
- package/out/pipeline/index.js +11 -0
- package/out/pipeline/index.js.map +1 -0
- package/out/pipeline/reconcile.d.ts +135 -0
- package/out/pipeline/reconcile.d.ts.map +1 -0
- package/out/pipeline/reconcile.js +355 -0
- package/out/pipeline/reconcile.js.map +1 -0
- package/out/pipeline/runtime-pipeline.d.ts +29 -0
- package/out/pipeline/runtime-pipeline.d.ts.map +1 -0
- package/out/pipeline/runtime-pipeline.js +339 -0
- package/out/pipeline/runtime-pipeline.js.map +1 -0
- package/out/pipeline/span-logit-aggregation.d.ts +57 -0
- package/out/pipeline/span-logit-aggregation.d.ts.map +1 -0
- package/out/pipeline/span-logit-aggregation.js +105 -0
- package/out/pipeline/span-logit-aggregation.js.map +1 -0
- package/out/pipeline/types.d.ts +215 -0
- package/out/pipeline/types.d.ts.map +1 -0
- package/out/pipeline/types.js +16 -0
- package/out/pipeline/types.js.map +1 -0
- package/out/resolver/index.d.ts +9 -0
- package/out/resolver/index.d.ts.map +1 -0
- package/out/resolver/index.js +8 -0
- package/out/resolver/index.js.map +1 -0
- package/out/resolver/resolve.d.ts +21 -0
- package/out/resolver/resolve.d.ts.map +1 -0
- package/out/resolver/resolve.js +118 -0
- package/out/resolver/resolve.js.map +1 -0
- package/out/resolver/types.d.ts +118 -0
- package/out/resolver/types.d.ts.map +1 -0
- package/out/resolver/types.js +26 -0
- package/out/resolver/types.js.map +1 -0
- package/out/resources/git.d.ts +1 -1
- package/out/resources/index.d.ts +0 -1
- package/out/resources/index.d.ts.map +1 -1
- package/out/resources/index.js +0 -1
- package/out/resources/index.js.map +1 -1
- package/out/resources/whosonfirst/DataSourceCache.d.ts +0 -1
- package/out/resources/whosonfirst/DataSourceCache.d.ts.map +1 -1
- package/out/resources/whosonfirst/DataSourceCache.js +0 -1
- package/out/resources/whosonfirst/DataSourceCache.js.map +1 -1
- package/out/resources/whosonfirst/PlacetypeDataSource.d.ts +2 -2
- package/out/resources/whosonfirst/PlacetypeDataSource.d.ts.map +1 -1
- package/out/resources/whosonfirst/PlacetypeDataSource.js +9 -6
- package/out/resources/whosonfirst/PlacetypeDataSource.js.map +1 -1
- package/out/resources/whosonfirst/placetypes/admin.d.ts +23 -1
- package/out/resources/whosonfirst/placetypes/admin.d.ts.map +1 -1
- package/out/resources/whosonfirst/placetypes/admin.js +14 -1
- package/out/resources/whosonfirst/placetypes/admin.js.map +1 -1
- package/out/routing/index.d.ts +67 -0
- package/out/routing/index.d.ts.map +1 -0
- package/out/routing/index.js +114 -0
- package/out/routing/index.js.map +1 -0
- package/out/sets.d.ts +2 -0
- package/out/sets.d.ts.map +1 -0
- package/out/sets.js +2 -0
- package/out/sets.js.map +1 -0
- package/package.json +28 -2
- package/out/resources/db/index.d.ts +0 -57
- package/out/resources/db/index.d.ts.map +0 -1
- package/out/resources/db/index.js +0 -57
- 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 @@
|
|
|
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":"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"}
|
|
@@ -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"}
|
package/out/resources/git.d.ts
CHANGED
|
@@ -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.
|
package/out/resources/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,
|
|
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"}
|
package/out/resources/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../resources/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,
|
|
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;
|
|
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"}
|