@mailwoman/resolver-wof-sqlite 9.4.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/lib/address/{point-interpolation.ts → point/interpolation.ts} +40 -38
- package/lib/address/point/schema.ts +132 -0
- package/lib/address/point.ts +68 -81
- package/lib/{address/index.ts → address.ts} +2 -2
- package/lib/ancestry/backfill.ts +24 -88
- package/lib/{ancestry/index.ts → ancestry.ts} +19 -15
- package/lib/build/candidate.ts +608 -0
- package/lib/build/population-corrections.ts +64 -0
- package/lib/build/slim.ts +338 -0
- package/lib/candidate/alias-bags.ts +74 -14
- package/lib/candidate/ancestors/schema.ts +211 -0
- package/lib/candidate/{ancestors-sidecar.ts → ancestors/sidecar.ts} +17 -24
- package/lib/candidate/country-display-names.ts +6 -20
- package/lib/candidate/extract-fold.ts +12 -57
- package/lib/candidate/fts.ts +28 -0
- package/lib/candidate/importance.ts +221 -0
- package/lib/candidate/lookup.ts +669 -0
- package/lib/candidate/name-roles.ts +16 -34
- package/lib/candidate/own-name.ts +34 -31
- package/lib/candidate/place-attrs.ts +20 -13
- package/lib/candidate/schema.ts +211 -0
- package/lib/candidate/scoring.ts +222 -0
- package/lib/capital-schema.ts +21 -17
- package/lib/capitals.ts +26 -24
- package/lib/coincident-roles.ts +74 -55
- package/lib/convention/schema.ts +13 -7
- package/lib/convention.ts +144 -0
- package/lib/coverage-manifest-schema.ts +34 -39
- package/lib/currency-backfill.ts +24 -69
- package/lib/env.ts +1 -1
- package/lib/exact-match.ts +31 -20
- package/lib/extracts.ts +96 -73
- package/lib/fst/autocomplete.ts +52 -35
- package/lib/fst/builder.ts +30 -36
- package/lib/fst/deserialize-web.ts +8 -9
- package/lib/fst/format.ts +41 -23
- package/lib/fst/freshness.ts +17 -95
- package/lib/fst/matcher.ts +2 -2
- package/lib/fst/serialize.ts +45 -60
- package/lib/fst/types.ts +71 -59
- package/lib/fts/query.ts +5 -36
- package/lib/fts.ts +280 -0
- package/lib/geonames/aliases.ts +72 -149
- package/lib/geonames/postal.ts +162 -77
- package/lib/index.ts +20 -27
- package/lib/interpolation.ts +43 -96
- package/lib/lookup.ts +137 -257
- package/lib/name-score.ts +9 -7
- package/lib/nsul/lookup.ts +36 -53
- package/lib/nsul/schema.ts +16 -43
- package/lib/paths.ts +159 -0
- package/lib/place-importance-schema.ts +57 -164
- package/lib/poi/lookup.ts +100 -109
- package/lib/poi/schema.ts +42 -26
- package/lib/polygon-schema.ts +10 -6
- package/lib/postal/city/alias/lookup.ts +79 -0
- package/lib/postal/{city-alias-schema.ts → city/alias/schema.ts} +14 -10
- package/lib/postal/{city-candidate-schema.ts → city/candidate-schema.ts} +26 -20
- package/lib/postal.ts +9 -0
- package/lib/postcode-point-lookup.ts +9 -19
- package/lib/primary-preference.ts +45 -125
- package/lib/proximity-rerank.ts +43 -32
- package/lib/ranking-weights.ts +98 -76
- package/lib/region-keys.ts +68 -40
- package/lib/reverse.ts +108 -72
- package/lib/schema.ts +74 -42
- package/lib/search-fetch.ts +90 -68
- package/lib/sqlite/convention-source.ts +57 -0
- package/lib/sqlite/utils.ts +79 -0
- package/lib/street/centroid/schema.ts +149 -0
- package/lib/street/centroid.ts +16 -25
- package/lib/street/{morphology-fst-builder.ts → morphology/fst/builder.ts} +56 -41
- package/lib/street/{morphology-fst-loader.ts → morphology/fst/loader.ts} +36 -29
- package/lib/street/name-lookup.ts +43 -35
- package/lib/street/normalize.ts +85 -216
- package/lib/street/segment-schema.ts +116 -43
- package/lib/{street/index.ts → street.ts} +3 -3
- package/lib/types.ts +94 -140
- package/lib/unified-schema.ts +29 -29
- package/lib/uprn/existence.ts +30 -19
- package/lib/uprn/lookup.ts +28 -67
- package/lib/uprn/schema.ts +18 -40
- package/lib/weights-overlay-linker.ts +204 -232
- package/out/address/point/interpolation.d.ts +45 -0
- package/out/address/point/interpolation.d.ts.map +1 -0
- package/out/address/{point-interpolation.js → point/interpolation.js} +38 -38
- package/out/address/point/interpolation.js.map +1 -0
- package/out/address/point/schema.d.ts +74 -0
- package/out/address/point/schema.d.ts.map +1 -0
- package/out/address/{point-schema.js → point/schema.js} +4 -20
- package/out/address/point/schema.js.map +1 -0
- package/out/address/point.d.ts +24 -21
- package/out/address/point.d.ts.map +1 -1
- package/out/address/point.js +60 -77
- package/out/address/point.js.map +1 -1
- package/out/{address/index.js → address.d.ts} +3 -3
- package/out/address.d.ts.map +1 -0
- package/out/{address/index.d.ts → address.js} +3 -3
- package/out/address.js.map +1 -0
- package/out/ancestry/backfill.d.ts +11 -64
- package/out/ancestry/backfill.d.ts.map +1 -1
- package/out/ancestry/backfill.js +18 -76
- package/out/ancestry/backfill.js.map +1 -1
- package/out/ancestry.d.ts +49 -0
- package/out/ancestry.d.ts.map +1 -0
- package/out/ancestry.js +59 -0
- package/out/ancestry.js.map +1 -0
- package/out/build/candidate.d.ts +170 -0
- package/out/build/candidate.d.ts.map +1 -0
- package/out/{build-candidate.js → build/candidate.js} +33 -102
- package/out/build/candidate.js.map +1 -0
- package/out/build/population-corrections.d.ts +52 -0
- package/out/build/population-corrections.d.ts.map +1 -0
- package/out/build/population-corrections.js +40 -0
- package/out/build/population-corrections.js.map +1 -0
- package/out/build/slim.d.ts +44 -0
- package/out/build/slim.d.ts.map +1 -0
- package/out/{build-slim.js → build/slim.js} +33 -94
- package/out/build/slim.js.map +1 -0
- package/out/candidate/alias-bags.d.ts +13 -5
- package/out/candidate/alias-bags.d.ts.map +1 -1
- package/out/candidate/alias-bags.js +55 -12
- package/out/candidate/alias-bags.js.map +1 -1
- package/out/candidate/ancestors/schema.d.ts +166 -0
- package/out/candidate/ancestors/schema.d.ts.map +1 -0
- package/out/candidate/ancestors/schema.js +131 -0
- package/out/candidate/ancestors/schema.js.map +1 -0
- package/out/candidate/ancestors/sidecar.d.ts +27 -0
- package/out/candidate/ancestors/sidecar.d.ts.map +1 -0
- package/out/candidate/{ancestors-sidecar.js → ancestors/sidecar.js} +17 -24
- package/out/candidate/ancestors/sidecar.js.map +1 -0
- package/out/candidate/country-display-names.d.ts +5 -15
- package/out/candidate/country-display-names.d.ts.map +1 -1
- package/out/candidate/country-display-names.js +6 -20
- package/out/candidate/country-display-names.js.map +1 -1
- package/out/candidate/extract-fold.d.ts +8 -16
- package/out/candidate/extract-fold.d.ts.map +1 -1
- package/out/candidate/extract-fold.js +6 -48
- package/out/candidate/extract-fold.js.map +1 -1
- package/out/candidate/fts.d.ts +19 -0
- package/out/candidate/fts.d.ts.map +1 -0
- package/out/candidate/fts.js +22 -0
- package/out/candidate/fts.js.map +1 -0
- package/out/candidate/importance.d.ts +127 -0
- package/out/candidate/importance.d.ts.map +1 -0
- package/out/candidate/importance.js +162 -0
- package/out/candidate/importance.js.map +1 -0
- package/out/candidate/lookup.d.ts +36 -0
- package/out/candidate/lookup.d.ts.map +1 -0
- package/out/candidate/lookup.js +456 -0
- package/out/candidate/lookup.js.map +1 -0
- package/out/candidate/name-roles.d.ts +10 -22
- package/out/candidate/name-roles.d.ts.map +1 -1
- package/out/candidate/name-roles.js +15 -33
- package/out/candidate/name-roles.js.map +1 -1
- package/out/candidate/own-name.d.ts +23 -25
- package/out/candidate/own-name.d.ts.map +1 -1
- package/out/candidate/own-name.js +34 -31
- package/out/candidate/own-name.js.map +1 -1
- package/out/candidate/place-attrs.d.ts +20 -13
- package/out/candidate/place-attrs.d.ts.map +1 -1
- package/out/candidate/place-attrs.js +4 -5
- package/out/candidate/place-attrs.js.map +1 -1
- package/out/candidate/schema.d.ts +120 -0
- package/out/candidate/schema.d.ts.map +1 -0
- package/out/{candidate-schema.js → candidate/schema.js} +11 -23
- package/out/candidate/schema.js.map +1 -0
- package/out/{candidate-scoring.d.ts → candidate/scoring.d.ts} +8 -9
- package/out/candidate/scoring.d.ts.map +1 -0
- package/out/candidate/scoring.js +157 -0
- package/out/candidate/scoring.js.map +1 -0
- package/out/capital-schema.d.ts +21 -17
- package/out/capital-schema.d.ts.map +1 -1
- package/out/capital-schema.js +17 -15
- package/out/capital-schema.js.map +1 -1
- package/out/capitals.d.ts +26 -24
- package/out/capitals.d.ts.map +1 -1
- package/out/capitals.js +23 -21
- package/out/capitals.js.map +1 -1
- package/out/coincident-roles.d.ts +60 -43
- package/out/coincident-roles.d.ts.map +1 -1
- package/out/coincident-roles.js +61 -50
- package/out/coincident-roles.js.map +1 -1
- package/out/convention/schema.d.ts +12 -6
- package/out/convention/schema.d.ts.map +1 -1
- package/out/convention/schema.js +6 -4
- package/out/convention/schema.js.map +1 -1
- package/out/convention.d.ts +97 -0
- package/out/convention.d.ts.map +1 -0
- package/out/convention.js +81 -0
- package/out/convention.js.map +1 -0
- package/out/coverage-manifest-schema.d.ts +33 -38
- package/out/coverage-manifest-schema.d.ts.map +1 -1
- package/out/coverage-manifest-schema.js +20 -29
- package/out/coverage-manifest-schema.js.map +1 -1
- package/out/currency-backfill.d.ts +13 -35
- package/out/currency-backfill.d.ts.map +1 -1
- package/out/currency-backfill.js +12 -39
- package/out/currency-backfill.js.map +1 -1
- package/out/env.d.ts +2 -2
- package/out/env.js +1 -1
- package/out/exact-match.d.ts +19 -10
- package/out/exact-match.d.ts.map +1 -1
- package/out/exact-match.js +31 -20
- package/out/exact-match.js.map +1 -1
- package/out/extracts.d.ts +65 -54
- package/out/extracts.d.ts.map +1 -1
- package/out/extracts.js +63 -55
- package/out/extracts.js.map +1 -1
- package/out/fst/autocomplete.d.ts +28 -20
- package/out/fst/autocomplete.d.ts.map +1 -1
- package/out/fst/autocomplete.js +38 -27
- package/out/fst/autocomplete.js.map +1 -1
- package/out/fst/builder.d.ts.map +1 -1
- package/out/fst/builder.js +30 -36
- package/out/fst/builder.js.map +1 -1
- package/out/fst/deserialize-web.d.ts +3 -3
- package/out/fst/deserialize-web.d.ts.map +1 -1
- package/out/fst/deserialize-web.js +8 -9
- package/out/fst/deserialize-web.js.map +1 -1
- package/out/fst/format.d.ts +41 -23
- package/out/fst/format.d.ts.map +1 -1
- package/out/fst/format.js +41 -23
- package/out/fst/format.js.map +1 -1
- package/out/fst/freshness.d.ts +11 -73
- package/out/fst/freshness.d.ts.map +1 -1
- package/out/fst/freshness.js +12 -76
- package/out/fst/freshness.js.map +1 -1
- package/out/fst/matcher.d.ts +1 -1
- package/out/fst/matcher.d.ts.map +1 -1
- package/out/fst/matcher.js +2 -2
- package/out/fst/matcher.js.map +1 -1
- package/out/fst/serialize.d.ts +30 -26
- package/out/fst/serialize.d.ts.map +1 -1
- package/out/fst/serialize.js +44 -58
- package/out/fst/serialize.js.map +1 -1
- package/out/fst/types.d.ts +71 -59
- package/out/fst/types.d.ts.map +1 -1
- package/out/fst/types.js +1 -4
- package/out/fst/types.js.map +1 -1
- package/out/{fst/index.js → fst.d.ts} +1 -1
- package/out/fst.d.ts.map +1 -0
- package/out/{fst/index.d.ts → fst.js} +1 -1
- package/out/fst.js.map +1 -0
- package/out/fts/query.d.ts +2 -27
- package/out/fts/query.d.ts.map +1 -1
- package/out/fts/query.js +5 -36
- package/out/fts/query.js.map +1 -1
- package/out/fts.d.ts +126 -0
- package/out/fts.d.ts.map +1 -0
- package/out/fts.js +188 -0
- package/out/fts.js.map +1 -0
- package/out/geonames/aliases.d.ts +26 -67
- package/out/geonames/aliases.d.ts.map +1 -1
- package/out/geonames/aliases.js +44 -121
- package/out/geonames/aliases.js.map +1 -1
- package/out/geonames/postal.d.ts +84 -50
- package/out/geonames/postal.d.ts.map +1 -1
- package/out/geonames/postal.js +115 -78
- package/out/geonames/postal.js.map +1 -1
- package/out/{geonames/index.js → geonames.d.ts} +1 -1
- package/out/geonames.d.ts.map +1 -0
- package/out/{geonames/index.d.ts → geonames.js} +1 -1
- package/out/geonames.js.map +1 -0
- package/out/index.d.ts +20 -21
- package/out/index.d.ts.map +1 -1
- package/out/index.js +14 -15
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +15 -52
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +25 -68
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +24 -53
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +117 -223
- package/out/lookup.js.map +1 -1
- package/out/name-score.d.ts +2 -2
- package/out/name-score.d.ts.map +1 -1
- package/out/name-score.js +9 -7
- package/out/name-score.js.map +1 -1
- package/out/nsul/lookup.d.ts +33 -34
- package/out/nsul/lookup.d.ts.map +1 -1
- package/out/nsul/lookup.js +26 -40
- package/out/nsul/lookup.js.map +1 -1
- package/out/nsul/schema.d.ts +16 -43
- package/out/nsul/schema.d.ts.map +1 -1
- package/out/nsul/schema.js +9 -35
- package/out/nsul/schema.js.map +1 -1
- package/out/{nsul/index.d.ts → nsul.d.ts} +1 -1
- package/out/nsul.d.ts.map +1 -0
- package/out/{nsul/index.js → nsul.js} +1 -1
- package/out/nsul.js.map +1 -0
- package/out/paths.d.ts +124 -0
- package/out/paths.d.ts.map +1 -0
- package/out/paths.js +104 -0
- package/out/paths.js.map +1 -0
- package/out/place-importance-schema.d.ts +49 -141
- package/out/place-importance-schema.d.ts.map +1 -1
- package/out/place-importance-schema.js +25 -140
- package/out/place-importance-schema.js.map +1 -1
- package/out/poi/lookup.d.ts +38 -42
- package/out/poi/lookup.d.ts.map +1 -1
- package/out/poi/lookup.js +67 -90
- package/out/poi/lookup.js.map +1 -1
- package/out/poi/schema.d.ts +41 -25
- package/out/poi/schema.d.ts.map +1 -1
- package/out/poi/schema.js +25 -17
- package/out/poi/schema.js.map +1 -1
- package/out/{poi/index.js → poi.d.ts} +1 -1
- package/out/poi.d.ts.map +1 -0
- package/out/{poi/index.d.ts → poi.js} +1 -1
- package/out/poi.js.map +1 -0
- package/out/polygon-schema.d.ts +10 -6
- package/out/polygon-schema.d.ts.map +1 -1
- package/out/polygon-schema.js +2 -2
- package/out/polygon-schema.js.map +1 -1
- package/out/postal/{city-alias-lookup.d.ts → city/alias/lookup.d.ts} +22 -25
- package/out/postal/city/alias/lookup.d.ts.map +1 -0
- package/out/postal/city/alias/lookup.js +49 -0
- package/out/postal/city/alias/lookup.js.map +1 -0
- package/out/postal/{city-alias-schema.d.ts → city/alias/schema.d.ts} +15 -11
- package/out/postal/city/alias/schema.d.ts.map +1 -0
- package/out/postal/{city-alias-schema.js → city/alias/schema.js} +11 -9
- package/out/postal/city/alias/schema.js.map +1 -0
- package/out/postal/city/candidate-schema.d.ts +72 -0
- package/out/postal/city/candidate-schema.d.ts.map +1 -0
- package/out/postal/city/candidate-schema.js +60 -0
- package/out/postal/city/candidate-schema.js.map +1 -0
- package/out/postal.d.ts +9 -0
- package/out/postal.d.ts.map +1 -0
- package/out/postal.js +9 -0
- package/out/postal.js.map +1 -0
- package/out/postcode-point-lookup.d.ts +9 -19
- package/out/postcode-point-lookup.d.ts.map +1 -1
- package/out/postcode-point-lookup.js +5 -17
- package/out/postcode-point-lookup.js.map +1 -1
- package/out/primary-preference.d.ts +39 -93
- package/out/primary-preference.d.ts.map +1 -1
- package/out/primary-preference.js +13 -97
- package/out/primary-preference.js.map +1 -1
- package/out/proximity-rerank.d.ts +40 -29
- package/out/proximity-rerank.d.ts.map +1 -1
- package/out/proximity-rerank.js +38 -29
- package/out/proximity-rerank.js.map +1 -1
- package/out/ranking-weights.d.ts +91 -62
- package/out/ranking-weights.d.ts.map +1 -1
- package/out/ranking-weights.js +26 -25
- package/out/ranking-weights.js.map +1 -1
- package/out/region-keys.d.ts +48 -29
- package/out/region-keys.d.ts.map +1 -1
- package/out/region-keys.js +68 -40
- package/out/region-keys.js.map +1 -1
- package/out/reverse.d.ts +75 -50
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +61 -49
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +74 -42
- package/out/schema.d.ts.map +1 -1
- package/out/schema.js +4 -5
- package/out/schema.js.map +1 -1
- package/out/search-fetch.d.ts +16 -12
- package/out/search-fetch.d.ts.map +1 -1
- package/out/search-fetch.js +83 -63
- package/out/search-fetch.js.map +1 -1
- package/out/sqlite/convention-source.d.ts +25 -0
- package/out/sqlite/convention-source.d.ts.map +1 -0
- package/out/sqlite/convention-source.js +48 -0
- package/out/sqlite/convention-source.js.map +1 -0
- package/out/sqlite/utils.d.ts +45 -0
- package/out/sqlite/utils.d.ts.map +1 -0
- package/out/sqlite/utils.js +56 -0
- package/out/sqlite/utils.js.map +1 -0
- package/out/street/centroid/schema.d.ts +100 -0
- package/out/street/centroid/schema.d.ts.map +1 -0
- package/out/street/centroid/schema.js +66 -0
- package/out/street/centroid/schema.js.map +1 -0
- package/out/street/centroid.d.ts +9 -19
- package/out/street/centroid.d.ts.map +1 -1
- package/out/street/centroid.js +11 -22
- package/out/street/centroid.js.map +1 -1
- package/out/street/{morphology-fst-builder.d.ts → morphology/fst/builder.d.ts} +21 -11
- package/out/street/morphology/fst/builder.d.ts.map +1 -0
- package/out/street/{morphology-fst-builder.js → morphology/fst/builder.js} +40 -34
- package/out/street/morphology/fst/builder.js.map +1 -0
- package/out/street/morphology/fst/loader.d.ts +74 -0
- package/out/street/morphology/fst/loader.d.ts.map +1 -0
- package/out/street/{morphology-fst-loader.js → morphology/fst/loader.js} +21 -21
- package/out/street/morphology/fst/loader.js.map +1 -0
- package/out/street/name-lookup.d.ts +24 -18
- package/out/street/name-lookup.d.ts.map +1 -1
- package/out/street/name-lookup.js +32 -31
- package/out/street/name-lookup.js.map +1 -1
- package/out/street/normalize.d.ts +35 -136
- package/out/street/normalize.d.ts.map +1 -1
- package/out/street/normalize.js +74 -191
- package/out/street/normalize.js.map +1 -1
- package/out/street/segment-schema.d.ts +79 -39
- package/out/street/segment-schema.d.ts.map +1 -1
- package/out/street/segment-schema.js +71 -21
- package/out/street/segment-schema.js.map +1 -1
- package/out/{street/index.d.ts → street.d.ts} +4 -4
- package/out/street.d.ts.map +1 -0
- package/out/{street/index.js → street.js} +4 -4
- package/out/street.js.map +1 -0
- package/out/types.d.ts +69 -138
- package/out/types.d.ts.map +1 -1
- package/out/types.js +0 -6
- package/out/types.js.map +1 -1
- package/out/unified-schema.d.ts +8 -12
- package/out/unified-schema.d.ts.map +1 -1
- package/out/unified-schema.js +29 -29
- package/out/unified-schema.js.map +1 -1
- package/out/uprn/existence.d.ts +28 -17
- package/out/uprn/existence.d.ts.map +1 -1
- package/out/uprn/existence.js +26 -16
- package/out/uprn/existence.js.map +1 -1
- package/out/uprn/lookup.d.ts +14 -44
- package/out/uprn/lookup.d.ts.map +1 -1
- package/out/uprn/lookup.js +20 -56
- package/out/uprn/lookup.js.map +1 -1
- package/out/uprn/schema.d.ts +18 -40
- package/out/uprn/schema.d.ts.map +1 -1
- package/out/uprn/schema.js +10 -32
- package/out/uprn/schema.js.map +1 -1
- package/out/{uprn/index.d.ts → uprn.d.ts} +1 -1
- package/out/uprn.d.ts.map +1 -0
- package/out/{uprn/index.js → uprn.js} +1 -1
- package/out/uprn.js.map +1 -0
- package/out/weights-overlay-linker.d.ts +132 -141
- package/out/weights-overlay-linker.d.ts.map +1 -1
- package/out/weights-overlay-linker.js +86 -154
- package/out/weights-overlay-linker.js.map +1 -1
- package/package.json +94 -599
- package/lib/address/point-schema.ts +0 -155
- package/lib/build-candidate.ts +0 -632
- package/lib/build-slim.ts +0 -408
- package/lib/candidate-ancestors-schema.ts +0 -195
- package/lib/candidate-fts.ts +0 -46
- package/lib/candidate-importance.ts +0 -224
- package/lib/candidate-lookup.ts +0 -977
- package/lib/candidate-schema.ts +0 -247
- package/lib/candidate-scoring.ts +0 -261
- package/lib/convention/index.ts +0 -154
- package/lib/fts/index.ts +0 -361
- package/lib/postal/city-alias-lookup.ts +0 -97
- package/lib/postal/index.ts +0 -9
- package/lib/sqlite-convention-source.ts +0 -65
- package/lib/sqlite-utils.ts +0 -82
- package/lib/street/centroid-schema.ts +0 -154
- package/out/address/index.d.ts.map +0 -1
- package/out/address/index.js.map +0 -1
- package/out/address/point-interpolation.d.ts +0 -49
- package/out/address/point-interpolation.d.ts.map +0 -1
- package/out/address/point-interpolation.js.map +0 -1
- package/out/address/point-schema.d.ts +0 -97
- package/out/address/point-schema.d.ts.map +0 -1
- package/out/address/point-schema.js.map +0 -1
- package/out/ancestry/index.d.ts +0 -45
- package/out/ancestry/index.d.ts.map +0 -1
- package/out/ancestry/index.js +0 -55
- package/out/ancestry/index.js.map +0 -1
- package/out/build-candidate.d.ts +0 -184
- package/out/build-candidate.d.ts.map +0 -1
- package/out/build-candidate.js.map +0 -1
- package/out/build-slim.d.ts +0 -80
- package/out/build-slim.d.ts.map +0 -1
- package/out/build-slim.js.map +0 -1
- package/out/candidate/ancestors-sidecar.d.ts +0 -32
- package/out/candidate/ancestors-sidecar.d.ts.map +0 -1
- package/out/candidate/ancestors-sidecar.js.map +0 -1
- package/out/candidate-ancestors-schema.d.ts +0 -150
- package/out/candidate-ancestors-schema.d.ts.map +0 -1
- package/out/candidate-ancestors-schema.js +0 -123
- package/out/candidate-ancestors-schema.js.map +0 -1
- package/out/candidate-fts.d.ts +0 -37
- package/out/candidate-fts.d.ts.map +0 -1
- package/out/candidate-fts.js +0 -40
- package/out/candidate-fts.js.map +0 -1
- package/out/candidate-importance.d.ts +0 -132
- package/out/candidate-importance.d.ts.map +0 -1
- package/out/candidate-importance.js +0 -169
- package/out/candidate-importance.js.map +0 -1
- package/out/candidate-lookup.d.ts +0 -76
- package/out/candidate-lookup.d.ts.map +0 -1
- package/out/candidate-lookup.js +0 -768
- package/out/candidate-lookup.js.map +0 -1
- package/out/candidate-schema.d.ts +0 -155
- package/out/candidate-schema.d.ts.map +0 -1
- package/out/candidate-schema.js.map +0 -1
- package/out/candidate-scoring.d.ts.map +0 -1
- package/out/candidate-scoring.js +0 -196
- package/out/candidate-scoring.js.map +0 -1
- package/out/convention/index.d.ts +0 -106
- package/out/convention/index.d.ts.map +0 -1
- package/out/convention/index.js +0 -93
- package/out/convention/index.js.map +0 -1
- package/out/fst/index.d.ts.map +0 -1
- package/out/fst/index.js.map +0 -1
- package/out/fts/index.d.ts +0 -184
- package/out/fts/index.d.ts.map +0 -1
- package/out/fts/index.js +0 -277
- package/out/fts/index.js.map +0 -1
- package/out/geonames/index.d.ts.map +0 -1
- package/out/geonames/index.js.map +0 -1
- package/out/nsul/index.d.ts.map +0 -1
- package/out/nsul/index.js.map +0 -1
- package/out/poi/index.d.ts.map +0 -1
- package/out/poi/index.js.map +0 -1
- package/out/postal/city-alias-lookup.d.ts.map +0 -1
- package/out/postal/city-alias-lookup.js +0 -62
- package/out/postal/city-alias-lookup.js.map +0 -1
- package/out/postal/city-alias-schema.d.ts.map +0 -1
- package/out/postal/city-alias-schema.js.map +0 -1
- package/out/postal/city-candidate-schema.d.ts +0 -66
- package/out/postal/city-candidate-schema.d.ts.map +0 -1
- package/out/postal/city-candidate-schema.js +0 -56
- package/out/postal/city-candidate-schema.js.map +0 -1
- package/out/postal/index.d.ts +0 -9
- package/out/postal/index.d.ts.map +0 -1
- package/out/postal/index.js +0 -9
- package/out/postal/index.js.map +0 -1
- package/out/sqlite-convention-source.d.ts +0 -29
- package/out/sqlite-convention-source.d.ts.map +0 -1
- package/out/sqlite-convention-source.js +0 -57
- package/out/sqlite-convention-source.js.map +0 -1
- package/out/sqlite-utils.d.ts +0 -45
- package/out/sqlite-utils.d.ts.map +0 -1
- package/out/sqlite-utils.js +0 -57
- package/out/sqlite-utils.js.map +0 -1
- package/out/street/centroid-schema.d.ts +0 -105
- package/out/street/centroid-schema.d.ts.map +0 -1
- package/out/street/centroid-schema.js +0 -78
- package/out/street/centroid-schema.js.map +0 -1
- package/out/street/index.d.ts.map +0 -1
- package/out/street/index.js.map +0 -1
- package/out/street/morphology-fst-builder.d.ts.map +0 -1
- package/out/street/morphology-fst-builder.js.map +0 -1
- package/out/street/morphology-fst-loader.d.ts +0 -67
- package/out/street/morphology-fst-loader.d.ts.map +0 -1
- package/out/street/morphology-fst-loader.js.map +0 -1
- package/out/uprn/index.d.ts.map +0 -1
- package/out/uprn/index.js.map +0 -1
- /package/lib/{fst/index.ts → fst.ts} +0 -0
- /package/lib/{geonames/index.ts → geonames.ts} +0 -0
- /package/lib/{nsul/index.ts → nsul.ts} +0 -0
- /package/lib/{poi/index.ts → poi.ts} +0 -0
- /package/lib/{uprn/index.ts → uprn.ts} +0 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*/
|
|
6
|
+
import { expandPlacetypeFilter } from "@mailwoman/codex/placetype-map";
|
|
7
|
+
import { referentialFromPopulation } from "@mailwoman/core/resolver";
|
|
8
|
+
import { allRows } from "@mailwoman/core/utils";
|
|
9
|
+
import { jaroWinkler, levenshteinSimilarity } from "@mailwoman/match/comparators";
|
|
10
|
+
import { partitionByContainment } from "@mailwoman/resolver";
|
|
11
|
+
import { haversineKm } from "@mailwoman/spatial";
|
|
12
|
+
import { SQLiteLookup } from "@mailwoman/sqlite/lookup";
|
|
13
|
+
import { CANDIDATE_ANCESTOR_TABLE, CANDIDATE_INTERVAL_TABLE, intervalContains, } from "#candidate/ancestors/schema";
|
|
14
|
+
import { CANDIDATE_FTS_TABLE } from "#candidate/fts";
|
|
15
|
+
import { readGazetteerCoverageManifest } from "#coverage-manifest-schema";
|
|
16
|
+
import { POSTAL_CITY_CANDIDATE_TABLE } from "#postal/city/candidate-schema";
|
|
17
|
+
import { rankByPrimaryPreference, RERANK_FETCH } from "#primary-preference";
|
|
18
|
+
import { applyProximityRerank } from "#proximity-rerank";
|
|
19
|
+
import { REGION_CLASS_PLACETYPES, regionQualifierProbeKeys } from "#region-keys";
|
|
20
|
+
import { hasColumn, hasTable } from "#sqlite-utils";
|
|
21
|
+
import { normalizeLocalityForKey, stripLocalityQualifier } from "#street/normalize";
|
|
22
|
+
export { rankByPrimaryPreference } from "#primary-preference";
|
|
23
|
+
const FUZZY_FETCH = 40;
|
|
24
|
+
const WORD_FUZZY_MIN = 0.85;
|
|
25
|
+
function wordFuzzySimilarity(a, b) {
|
|
26
|
+
return Math.max(jaroWinkler(a, b), levenshteinSimilarity(a, b));
|
|
27
|
+
}
|
|
28
|
+
const POSTCODE_CONTAINMENT_THRESHOLD_KM = 25;
|
|
29
|
+
function ftsTrigramQuery(s) {
|
|
30
|
+
const grams = new Set();
|
|
31
|
+
for (let i = 0; i + 3 <= s.length; i++) {
|
|
32
|
+
const g = s.slice(i, i + 3);
|
|
33
|
+
if (/^[\p{L}\p{N} ]{3}$/u.test(g)) {
|
|
34
|
+
grams.add(g);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return [...grams].map((g) => `"${g}"`).join(" OR ");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Node {@link PlaceLookup} over `candidate.db`.
|
|
41
|
+
*/
|
|
42
|
+
export class WOFCandidateTableLookup extends SQLiteLookup {
|
|
43
|
+
#countryToID = new Map();
|
|
44
|
+
#idToCountry = new Map();
|
|
45
|
+
#placetypeToID = new Map();
|
|
46
|
+
#idToPlacetype = new Map();
|
|
47
|
+
#postalCityProbe;
|
|
48
|
+
#ftsProbe;
|
|
49
|
+
/**
|
|
50
|
+
* Prepared unfiltered `name_key` existence probe, so fuzzy fallback runs only for true name misses.
|
|
51
|
+
*/
|
|
52
|
+
#nameKeyExistsProbe;
|
|
53
|
+
artifactCoverage;
|
|
54
|
+
#importanceSelect;
|
|
55
|
+
#hasNameRole;
|
|
56
|
+
#variantAliasExemption;
|
|
57
|
+
#roleSelect;
|
|
58
|
+
#ancestorsProbe;
|
|
59
|
+
#ancestorsCache = new Map();
|
|
60
|
+
#intervalProbe;
|
|
61
|
+
#intervalCache = new Map();
|
|
62
|
+
#qualifierProbe;
|
|
63
|
+
/**
|
|
64
|
+
* Ancestor lineage accessor, nearest-first, present only when the artifact supports it.
|
|
65
|
+
*/
|
|
66
|
+
ancestors;
|
|
67
|
+
constructor(opts) {
|
|
68
|
+
super(opts);
|
|
69
|
+
for (const r of allRows(this.database.prepare("SELECT id, code FROM country_codes"))) {
|
|
70
|
+
const code = String(r.code).toUpperCase();
|
|
71
|
+
this.#countryToID.set(code, Number(r.id));
|
|
72
|
+
this.#idToCountry.set(Number(r.id), code);
|
|
73
|
+
}
|
|
74
|
+
for (const r of allRows(this.database.prepare("SELECT id, placetype FROM placetype_codes"))) {
|
|
75
|
+
this.#placetypeToID.set(String(r.placetype), Number(r.id));
|
|
76
|
+
this.#idToPlacetype.set(Number(r.id), String(r.placetype));
|
|
77
|
+
}
|
|
78
|
+
if (hasTable(this.database, POSTAL_CITY_CANDIDATE_TABLE)) {
|
|
79
|
+
this.#postalCityProbe = this.database.prepare(`SELECT spr_id, name, latitude, longitude FROM ${POSTAL_CITY_CANDIDATE_TABLE} WHERE name_key = ? AND postcode = ? LIMIT 1`);
|
|
80
|
+
}
|
|
81
|
+
if (hasTable(this.database, CANDIDATE_FTS_TABLE)) {
|
|
82
|
+
this.#ftsProbe = this.database.prepare(`SELECT name_key FROM ${CANDIDATE_FTS_TABLE} WHERE ${CANDIDATE_FTS_TABLE} MATCH ? ORDER BY bm25(${CANDIDATE_FTS_TABLE}) LIMIT ?`);
|
|
83
|
+
this.#nameKeyExistsProbe = this.database.prepare("SELECT 1 FROM candidate WHERE name_key = ? LIMIT 1");
|
|
84
|
+
}
|
|
85
|
+
// Optional columns are detected once here for hot-path reads.
|
|
86
|
+
this.#importanceSelect = hasColumn(this.database, "candidate", "importance") ? ", importance" : "";
|
|
87
|
+
this.#hasNameRole = hasColumn(this.database, "candidate", "name_role");
|
|
88
|
+
this.#variantAliasExemption = opts.variantAliasExemption === true;
|
|
89
|
+
this.#roleSelect = this.#hasNameRole ? ", name_role" : "";
|
|
90
|
+
if (hasTable(this.database, CANDIDATE_ANCESTOR_TABLE)) {
|
|
91
|
+
this.#ancestorsProbe = this.database.prepare(`SELECT parent_spr_id, parent_placetype_id, parent_name FROM ${CANDIDATE_ANCESTOR_TABLE}` +
|
|
92
|
+
" WHERE spr_id = ? ORDER BY depth ASC");
|
|
93
|
+
this.ancestors = (id) => this.#ancestorLineage(id);
|
|
94
|
+
}
|
|
95
|
+
if (this.#ancestorsProbe && hasTable(this.database, CANDIDATE_INTERVAL_TABLE)) {
|
|
96
|
+
this.#intervalProbe = this.database.prepare(`SELECT pre, post FROM ${CANDIDATE_INTERVAL_TABLE} WHERE spr_id = ?`);
|
|
97
|
+
const bandIDs = [...REGION_CLASS_PLACETYPES, "country"]
|
|
98
|
+
.map((placetype) => this.#placetypeToID.get(placetype))
|
|
99
|
+
.filter((id) => id !== undefined);
|
|
100
|
+
if (bandIDs.length) {
|
|
101
|
+
this.#qualifierProbe = this.database.prepare(`SELECT DISTINCT spr_id FROM candidate WHERE name_key = ? AND placetype_id IN (${bandIDs.join(",")}) LIMIT 8`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.artifactCoverage = readGazetteerCoverageManifest(this.database);
|
|
105
|
+
}
|
|
106
|
+
#ancestorLineage(id) {
|
|
107
|
+
const pid = typeof id === "number" ? id : Number(id);
|
|
108
|
+
if (!Number.isFinite(pid) || !this.#ancestorsProbe)
|
|
109
|
+
return [];
|
|
110
|
+
const cached = this.#ancestorsCache.get(pid);
|
|
111
|
+
if (cached)
|
|
112
|
+
return cached;
|
|
113
|
+
const rows = allRows(this.#ancestorsProbe, pid);
|
|
114
|
+
const lineage = rows.map((r) => ({
|
|
115
|
+
id: Number(r.parent_spr_id),
|
|
116
|
+
placetype: this.#idToPlacetype.get(Number(r.parent_placetype_id)) ?? "",
|
|
117
|
+
name: String(r.parent_name ?? ""),
|
|
118
|
+
}));
|
|
119
|
+
this.#ancestorsCache.set(pid, lineage);
|
|
120
|
+
return lineage;
|
|
121
|
+
}
|
|
122
|
+
#intervalLabel(sprID) {
|
|
123
|
+
if (!this.#intervalProbe)
|
|
124
|
+
return null;
|
|
125
|
+
const cached = this.#intervalCache.get(sprID);
|
|
126
|
+
if (cached !== undefined)
|
|
127
|
+
return cached;
|
|
128
|
+
const row = this.#intervalProbe.get(sprID);
|
|
129
|
+
const label = row ? { pre: Number(row.pre), post: Number(row.post) } : null;
|
|
130
|
+
this.#intervalCache.set(sprID, label);
|
|
131
|
+
return label;
|
|
132
|
+
}
|
|
133
|
+
#qualifierRegionIDs(qualifier, country) {
|
|
134
|
+
const ids = new Set();
|
|
135
|
+
if (!this.#qualifierProbe)
|
|
136
|
+
return ids;
|
|
137
|
+
for (const key of regionQualifierProbeKeys(qualifier, country)) {
|
|
138
|
+
if (!key)
|
|
139
|
+
continue;
|
|
140
|
+
for (const row of allRows(this.#qualifierProbe, key)) {
|
|
141
|
+
ids.add(Number(row.spr_id));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return ids;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Whether `sprID` is contained by any qualifier row, using interval labels first
|
|
148
|
+
* and the ancestor chain as fallback.
|
|
149
|
+
*/
|
|
150
|
+
#containedByQualifier(sprID, qualifierIDs, qualifierLabels) {
|
|
151
|
+
if (qualifierIDs.has(sprID))
|
|
152
|
+
return true;
|
|
153
|
+
const label = this.#intervalLabel(sprID);
|
|
154
|
+
if (label && qualifierLabels.some((outer) => intervalContains(outer, label)))
|
|
155
|
+
return true;
|
|
156
|
+
return this.#ancestorLineage(sprID).some((ancestor) => qualifierIDs.has(Number(ancestor.id)));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Apply admin-containment re-rank: stamp containment, inject contained misses,
|
|
160
|
+
* then partition contained-first.
|
|
161
|
+
*/
|
|
162
|
+
#applyAdminContainment(rows, qualifier, country, opts) {
|
|
163
|
+
const qualifierIDs = this.#qualifierRegionIDs(qualifier, country);
|
|
164
|
+
if (!qualifierIDs.size) {
|
|
165
|
+
for (const row of rows) {
|
|
166
|
+
row.containedByQualifier = false;
|
|
167
|
+
}
|
|
168
|
+
return rows;
|
|
169
|
+
}
|
|
170
|
+
const qualifierLabels = [...qualifierIDs]
|
|
171
|
+
.map((id) => this.#intervalLabel(id))
|
|
172
|
+
.filter((label) => label !== null);
|
|
173
|
+
const contained = (sprID) => this.#containedByQualifier(sprID, qualifierIDs, qualifierLabels);
|
|
174
|
+
for (const row of rows) {
|
|
175
|
+
row.containedByQualifier = contained(Number(row.spr_id));
|
|
176
|
+
}
|
|
177
|
+
const present = new Set(rows.map((row) => Number(row.spr_id)));
|
|
178
|
+
const injected = [];
|
|
179
|
+
const injectSQL = (primaryOnly) => "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
|
|
180
|
+
`${this.#importanceSelect} FROM candidate WHERE ${["name_key = ?", ...opts.shapeFilters, ...(primaryOnly ? ["is_primary = 1"] : [])].join(" AND ")} ` +
|
|
181
|
+
"ORDER BY neg_rank ASC LIMIT ?";
|
|
182
|
+
const injectFrom = (key, primaryOnly) => {
|
|
183
|
+
const fetched = allRows(this.database.prepare(injectSQL(primaryOnly)), key, ...opts.shapeParams, RERANK_FETCH);
|
|
184
|
+
for (const row of fetched) {
|
|
185
|
+
const sprID = Number(row.spr_id);
|
|
186
|
+
if (present.has(sprID) || !contained(sprID))
|
|
187
|
+
continue;
|
|
188
|
+
present.add(sprID);
|
|
189
|
+
injected.push({ ...row, effectiveNegRank: row.neg_rank, demoted: false, containedByQualifier: true });
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
injectFrom(opts.nameKey, false);
|
|
193
|
+
// Also inject contained neighborhood-band namesakes (primary-keyed only).
|
|
194
|
+
const bandIDs = ["neighbourhood", "macrohood", "microhood"]
|
|
195
|
+
.map((placetype) => this.#placetypeToID.get(placetype))
|
|
196
|
+
.filter((id) => id !== undefined);
|
|
197
|
+
if (bandIDs.length) {
|
|
198
|
+
const bandSQL = "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
|
|
199
|
+
`${this.#importanceSelect} FROM candidate WHERE name_key = ? AND placetype_id IN (${bandIDs.map(() => "?").join(",")}) AND is_primary = 1 ` +
|
|
200
|
+
"ORDER BY neg_rank ASC LIMIT ?";
|
|
201
|
+
const fetched = allRows(this.database.prepare(bandSQL), opts.nameKey, ...bandIDs, RERANK_FETCH);
|
|
202
|
+
for (const row of fetched) {
|
|
203
|
+
const sprID = Number(row.spr_id);
|
|
204
|
+
if (present.has(sprID) || !contained(sprID))
|
|
205
|
+
continue;
|
|
206
|
+
present.add(sprID);
|
|
207
|
+
injected.push({ ...row, effectiveNegRank: row.neg_rank, demoted: false, containedByQualifier: true });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Try stripped-key injection only when exact-key containment found no row.
|
|
211
|
+
if (!injected.length &&
|
|
212
|
+
!rows.some((row) => row.containedByQualifier) &&
|
|
213
|
+
opts.strippedKey &&
|
|
214
|
+
opts.strippedKey !== opts.nameKey) {
|
|
215
|
+
injectFrom(opts.strippedKey, true);
|
|
216
|
+
}
|
|
217
|
+
if (!injected.length && !rows.some((row) => row.containedByQualifier))
|
|
218
|
+
return rows;
|
|
219
|
+
return partitionByContainment([...rows, ...injected], (row) => row.containedByQualifier === true, (row) => !row.demoted && !row.fuzzy).slice(0, opts.limit);
|
|
220
|
+
}
|
|
221
|
+
#wantsLocality(placetype) {
|
|
222
|
+
if (!placetype)
|
|
223
|
+
return true;
|
|
224
|
+
const want = Array.isArray(placetype) ? placetype : [placetype];
|
|
225
|
+
return expandPlacetypeFilter(want).includes("locality");
|
|
226
|
+
}
|
|
227
|
+
#postcodeAnchor(postcode, country) {
|
|
228
|
+
const placetypeID = this.#placetypeToID.get("postalcode");
|
|
229
|
+
if (placetypeID === undefined)
|
|
230
|
+
return null;
|
|
231
|
+
const conds = ["name_key = ?", "placetype_id = ?"];
|
|
232
|
+
const params = [postcode.replaceAll(/\s+/g, ""), placetypeID];
|
|
233
|
+
if (country) {
|
|
234
|
+
const countryID = this.#countryToID.get(country.toUpperCase());
|
|
235
|
+
if (countryID === undefined)
|
|
236
|
+
return null; // Unknown country in this artifact.
|
|
237
|
+
conds.push("country_id = ?");
|
|
238
|
+
params.push(countryID);
|
|
239
|
+
}
|
|
240
|
+
const row = this.database
|
|
241
|
+
.prepare(`SELECT latitude, longitude FROM candidate WHERE ${conds.join(" AND ")} ORDER BY neg_rank ASC LIMIT 1`)
|
|
242
|
+
.get(...params);
|
|
243
|
+
if (!row || (Number(row.latitude) === 0 && Number(row.longitude) === 0))
|
|
244
|
+
return null;
|
|
245
|
+
return { lat: Number(row.latitude), lon: Number(row.longitude) };
|
|
246
|
+
}
|
|
247
|
+
async findPlace(query) {
|
|
248
|
+
let text = (query.text ?? "").trim();
|
|
249
|
+
if (!text)
|
|
250
|
+
return [];
|
|
251
|
+
// Postcode queries use whitespace-stripped keying.
|
|
252
|
+
const wantsPostcode = [query.placetype].flat().includes("postalcode");
|
|
253
|
+
if (wantsPostcode) {
|
|
254
|
+
text = text.replaceAll(/\s+/g, "");
|
|
255
|
+
}
|
|
256
|
+
const nameKey = normalizeLocalityForKey(text);
|
|
257
|
+
if (!nameKey)
|
|
258
|
+
return [];
|
|
259
|
+
if (query.postcode && this.#postalCityProbe && this.#wantsLocality(query.placetype)) {
|
|
260
|
+
const hit = this.#postalCityProbe.get(nameKey, query.postcode.trim());
|
|
261
|
+
if (hit) {
|
|
262
|
+
return [
|
|
263
|
+
{
|
|
264
|
+
id: Number(hit.spr_id),
|
|
265
|
+
name: String(hit.name ?? ""),
|
|
266
|
+
placetype: "locality",
|
|
267
|
+
country: query.country?.toUpperCase() ?? "",
|
|
268
|
+
lat: Number(hit.latitude),
|
|
269
|
+
lon: Number(hit.longitude),
|
|
270
|
+
score: 1,
|
|
271
|
+
exactMatch: true,
|
|
272
|
+
},
|
|
273
|
+
];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const limit = Math.max(1, query.limit ?? 10);
|
|
277
|
+
// Shape filters are tracked separately from the shared country scope for exact and stripped probes.
|
|
278
|
+
const filters = [];
|
|
279
|
+
const filterParams = [];
|
|
280
|
+
const shapeFilters = [];
|
|
281
|
+
const shapeParams = [];
|
|
282
|
+
if (query.country) {
|
|
283
|
+
const cid = this.#countryToID.get(query.country.toUpperCase());
|
|
284
|
+
if (cid === undefined)
|
|
285
|
+
return []; // Unknown country in this artifact.
|
|
286
|
+
filters.push("country_id = ?");
|
|
287
|
+
filterParams.push(cid);
|
|
288
|
+
}
|
|
289
|
+
if (query.placetype) {
|
|
290
|
+
// Expand placetype equivalents (e.g. locality includes borough/localadmin).
|
|
291
|
+
const want = Array.isArray(query.placetype) ? query.placetype : [query.placetype];
|
|
292
|
+
const ids = expandPlacetypeFilter(want)
|
|
293
|
+
.map((t) => this.#placetypeToID.get(t))
|
|
294
|
+
.filter((v) => v !== undefined);
|
|
295
|
+
if (!ids.length)
|
|
296
|
+
return [];
|
|
297
|
+
shapeFilters.push(`placetype_id IN (${ids.map(() => "?").join(",")})`);
|
|
298
|
+
shapeParams.push(...ids);
|
|
299
|
+
}
|
|
300
|
+
if (query.bbox) {
|
|
301
|
+
const b = query.bbox;
|
|
302
|
+
shapeFilters.push("latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?");
|
|
303
|
+
shapeParams.push(b.minLat, b.maxLat, b.minLon, b.maxLon);
|
|
304
|
+
}
|
|
305
|
+
// Optional guard: restrict to primary rows for token-extracted probes.
|
|
306
|
+
if (query.primaryOnly) {
|
|
307
|
+
shapeFilters.push("is_primary = 1");
|
|
308
|
+
}
|
|
309
|
+
// The role filter is skipped on an artifact lacking `name_role`.
|
|
310
|
+
if (query.excludeNameRoles?.length && this.#hasNameRole) {
|
|
311
|
+
shapeFilters.push(`(name_role IS NULL OR name_role NOT IN (${query.excludeNameRoles.map(() => "?").join(",")}))`);
|
|
312
|
+
shapeParams.push(...query.excludeNameRoles);
|
|
313
|
+
}
|
|
314
|
+
filters.push(...shapeFilters);
|
|
315
|
+
filterParams.push(...shapeParams);
|
|
316
|
+
// Region scope is optional (`region_id = parentID`); the fallback stays unscoped.
|
|
317
|
+
const regionParentID = query.parentID || undefined;
|
|
318
|
+
const probe = (nk, regionID, countryID) => {
|
|
319
|
+
const conds = ["name_key = ?", ...filters];
|
|
320
|
+
const params = [nk, ...filterParams];
|
|
321
|
+
if (regionID !== undefined) {
|
|
322
|
+
conds.push("region_id = ?");
|
|
323
|
+
params.push(regionID);
|
|
324
|
+
}
|
|
325
|
+
if (typeof countryID === "number") {
|
|
326
|
+
conds.push("country_id = ?");
|
|
327
|
+
params.push(countryID);
|
|
328
|
+
}
|
|
329
|
+
// Population-ordered fetch over-fetches for the bounded primary-preference rerank.
|
|
330
|
+
const sql = "SELECT spr_id, name, country_id, placetype_id, latitude, longitude, min_lat, min_lon, max_lat, max_lon, neg_rank, is_primary, population" +
|
|
331
|
+
`${this.#importanceSelect}${this.#roleSelect} FROM candidate WHERE ${conds.join(" AND ")} ORDER BY neg_rank ASC LIMIT ?`;
|
|
332
|
+
const fetched = allRows(this.database.prepare(sql), ...params, Math.max(limit, RERANK_FETCH));
|
|
333
|
+
return rankByPrimaryPreference(fetched, limit, undefined, this.#idToPlacetype, this.#variantAliasExemption);
|
|
334
|
+
};
|
|
335
|
+
const cascade = (regionID) => {
|
|
336
|
+
let rows = probe(nameKey, regionID);
|
|
337
|
+
if (!rows.length) {
|
|
338
|
+
const strippedKey = normalizeLocalityForKey(stripLocalityQualifier(text));
|
|
339
|
+
if (strippedKey && strippedKey !== nameKey) {
|
|
340
|
+
// Stripped probes only accept primary rows to avoid alias-scrape matches.
|
|
341
|
+
rows = probe(strippedKey, regionID).filter((r) => r.is_primary === 1);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Typo-tolerant fallback for true name misses only, skipping postcodes and respecting the fuzzy-country scope.
|
|
345
|
+
const fuzzyCountryID = !query.country && query.fuzzyCountry ? this.#countryToID.get(query.fuzzyCountry.toUpperCase()) : undefined;
|
|
346
|
+
const fuzzyScopedOut = !query.country && !!query.fuzzyCountry && typeof fuzzyCountryID !== "number";
|
|
347
|
+
if (!rows.length &&
|
|
348
|
+
!wantsPostcode &&
|
|
349
|
+
!fuzzyScopedOut &&
|
|
350
|
+
this.#ftsProbe &&
|
|
351
|
+
this.#nameKeyExistsProbe &&
|
|
352
|
+
!this.#nameKeyExistsProbe.get(nameKey)) {
|
|
353
|
+
const match = ftsTrigramQuery(nameKey);
|
|
354
|
+
if (match) {
|
|
355
|
+
const hits = allRows(this.#ftsProbe, match, FUZZY_FETCH);
|
|
356
|
+
const ranked = hits
|
|
357
|
+
.map((h) => ({ nk: String(h.name_key), s: wordFuzzySimilarity(nameKey, String(h.name_key)) }))
|
|
358
|
+
.filter((h) => h.s >= WORD_FUZZY_MIN)
|
|
359
|
+
// oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array. toSorted would double-allocate on a hot path
|
|
360
|
+
.sort((a, b) => b.s - a.s);
|
|
361
|
+
const seen = new Set();
|
|
362
|
+
for (const h of ranked) {
|
|
363
|
+
if (seen.has(h.nk))
|
|
364
|
+
continue;
|
|
365
|
+
seen.add(h.nk);
|
|
366
|
+
rows.push(...probe(h.nk, regionID, fuzzyCountryID).map((r) => ({ ...r, fuzzy: true })));
|
|
367
|
+
if (rows.length >= limit)
|
|
368
|
+
break;
|
|
369
|
+
}
|
|
370
|
+
rows = rows.slice(0, limit);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return rows;
|
|
374
|
+
};
|
|
375
|
+
let rows = cascade(regionParentID);
|
|
376
|
+
let regionScopeMiss = false;
|
|
377
|
+
if (!rows.length && regionParentID !== undefined) {
|
|
378
|
+
rows = cascade(undefined);
|
|
379
|
+
regionScopeMiss = rows.length > 0;
|
|
380
|
+
}
|
|
381
|
+
if (query.postcode &&
|
|
382
|
+
query.postcodeContainmentCoherence === true &&
|
|
383
|
+
this.#wantsLocality(query.placetype) &&
|
|
384
|
+
rows.length > 1) {
|
|
385
|
+
const anchor = this.#postcodeAnchor(query.postcode, query.country);
|
|
386
|
+
if (anchor) {
|
|
387
|
+
const insideThreshold = [];
|
|
388
|
+
const outsideThreshold = [];
|
|
389
|
+
for (const row of rows) {
|
|
390
|
+
const distanceKm = haversineKm(anchor.lat, anchor.lon, Number(row.latitude), Number(row.longitude));
|
|
391
|
+
if (distanceKm <= POSTCODE_CONTAINMENT_THRESHOLD_KM) {
|
|
392
|
+
insideThreshold.push({ row, distanceKm });
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
outsideThreshold.push(row);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (insideThreshold.length) {
|
|
399
|
+
// oxlint-disable-next-line unicorn/no-array-sort -- hot-path in-place sort
|
|
400
|
+
insideThreshold.sort((a, b) => a.distanceKm - b.distanceKm);
|
|
401
|
+
rows = [...insideThreshold.map(({ row }) => row), ...outsideThreshold];
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
// Admin-containment re-rank runs last.
|
|
406
|
+
if (query.regionQualifier?.trim() && this.#qualifierProbe && this.#wantsLocality(query.placetype)) {
|
|
407
|
+
rows = this.#applyAdminContainment(rows, query.regionQualifier.trim(), query.country, {
|
|
408
|
+
nameKey,
|
|
409
|
+
strippedKey: normalizeLocalityForKey(stripLocalityQualifier(text)),
|
|
410
|
+
shapeFilters,
|
|
411
|
+
shapeParams,
|
|
412
|
+
limit,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
const candidates = rows.map((row) => {
|
|
416
|
+
const hasBbox = row.min_lat != null && row.max_lat != null && row.min_lon != null && row.max_lon != null;
|
|
417
|
+
const parent = this.#ancestorLineage(Number(row.spr_id))[0];
|
|
418
|
+
return {
|
|
419
|
+
id: Number(row.spr_id),
|
|
420
|
+
name: String(row.name ?? ""),
|
|
421
|
+
placetype: (this.#idToPlacetype.get(Number(row.placetype_id)) ?? ""),
|
|
422
|
+
country: this.#idToCountry.get(Number(row.country_id)) ?? "",
|
|
423
|
+
lat: Number(row.latitude),
|
|
424
|
+
lon: Number(row.longitude),
|
|
425
|
+
...(parent ? { parent_id: Number(parent.id) } : {}),
|
|
426
|
+
score: -Number(row.neg_rank),
|
|
427
|
+
prominence: -Number(row.effectiveNegRank),
|
|
428
|
+
exactMatch: !row.demoted && !row.fuzzy,
|
|
429
|
+
...(regionScopeMiss ? { regionScopeMiss: true } : {}),
|
|
430
|
+
...(row.containedByQualifier === undefined ? {} : { containedByQualifier: row.containedByQualifier }),
|
|
431
|
+
...(row.variantExempted ? { variantAliasExempted: true } : {}),
|
|
432
|
+
...(row.population === null || row.population <= 0
|
|
433
|
+
? {}
|
|
434
|
+
: { population: row.population, referential: referentialFromPopulation(row.population) }),
|
|
435
|
+
...(typeof row.importance === "number" && Number.isFinite(row.importance)
|
|
436
|
+
? { importance: row.importance }
|
|
437
|
+
: {}),
|
|
438
|
+
...(hasBbox
|
|
439
|
+
? {
|
|
440
|
+
bbox: {
|
|
441
|
+
minLat: Number(row.min_lat),
|
|
442
|
+
maxLat: Number(row.max_lat),
|
|
443
|
+
minLon: Number(row.min_lon),
|
|
444
|
+
maxLon: Number(row.max_lon),
|
|
445
|
+
},
|
|
446
|
+
}
|
|
447
|
+
: {}),
|
|
448
|
+
};
|
|
449
|
+
});
|
|
450
|
+
if (query.bias && query.bias.length) {
|
|
451
|
+
applyProximityRerank(candidates, query.bias);
|
|
452
|
+
}
|
|
453
|
+
return candidates;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../lib/candidate/lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,38 +5,26 @@
|
|
|
5
5
|
* @file Pass 3c of the candidate build — the `name_role` detectors and the thresholds they are judged by.
|
|
6
6
|
*/
|
|
7
7
|
import type { DatabaseClient } from "@mailwoman/sqlite/client";
|
|
8
|
-
import type { CandidateDatabase } from "#candidate-schema";
|
|
9
8
|
import type { PlaceAttrs } from "#candidate/place-attrs";
|
|
9
|
+
import type { CandidateDatabase } from "#candidate/schema";
|
|
10
10
|
import type { WOFDatabase } from "#schema";
|
|
11
11
|
/**
|
|
12
|
-
* Key-count threshold for the gloss anomaly detector
|
|
13
|
-
*
|
|
14
|
-
* this number
|
|
12
|
+
* Key-count threshold for the gloss anomaly detector.
|
|
13
|
+
*
|
|
14
|
+
* A legitimate famous place is separated by the prominence check rather than this number by itself.
|
|
15
15
|
*/
|
|
16
16
|
export declare const GLOSS_KEY_THRESHOLD = 50;
|
|
17
17
|
/**
|
|
18
|
-
* Placetypes the gloss detector never flags
|
|
19
|
-
*
|
|
20
|
-
* tail, where a place named by a common noun ("Poisson", "Sunday") accumulating 200+ translations is a
|
|
21
|
-
* machine-translated gloss set, not fame.
|
|
18
|
+
* Placetypes the gloss detector never flags: a country or region legitimately has a
|
|
19
|
+
* name in every language, so key volume provides no signal there.
|
|
22
20
|
*/
|
|
23
21
|
export declare const GLOSS_EXCLUDED_PLACETYPES: ReadonlySet<string>;
|
|
24
22
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* regression check). Both stamp `is_primary = 0` rows only — a place's canonical name and the `place_abbr` region
|
|
28
|
-
* abbreviations are never a gloss or a variant.
|
|
29
|
-
*
|
|
30
|
-
* - `gloss` is ANOMALY-based, and stamps only the certain core: key volume at/over the threshold + a non-admin placetype
|
|
31
|
-
*
|
|
32
|
-
* - NO measured prominence (population absent AND importance unmeasured). Provenance cannot separate a gloss from an
|
|
33
|
-
* exonym — WOF imported both as `x_preferred` — and prominence is what rescues New York/Paris.
|
|
34
|
-
* - `abbr` is PROVENANCE-based — the #936 signal: a WOF `variant` name in one of the country's official languages (or
|
|
35
|
-
* English), measured there at a 13× key-collision rate. A source without a `names` table (fixture-scale admin DBs)
|
|
36
|
-
* skips this detector loudly.
|
|
23
|
+
* Stamp `name_role` on non-primary rows: `abbr` by provenance, `variant` by
|
|
24
|
+
* own-name verdict, then `gloss` by key-volume anomaly.
|
|
37
25
|
*
|
|
38
|
-
*
|
|
39
|
-
* any role.
|
|
26
|
+
* @returns The stamp counts plus the census the prototype exists to report:
|
|
27
|
+
* how much of the ≥-threshold key tail has any role.
|
|
40
28
|
*/
|
|
41
29
|
export declare function stampNameRoles(ctx: {
|
|
42
30
|
src: DatabaseClient<WOFDatabase>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name-roles.d.ts","sourceRoot":"","sources":["../../lib/candidate/name-roles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"name-roles.d.ts","sourceRoot":"","sources":["../../lib/candidate/name-roles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAI9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG1C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CASxD,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE;IACnC,GAAG,EAAE,cAAc,CAAC,WAAW,CAAC,CAAA;IAChC,GAAG,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IACtC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAClD,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAoK/G"}
|
|
@@ -9,16 +9,14 @@ import { tableExists } from "@mailwoman/sqlite/introspection";
|
|
|
9
9
|
import { isOwnNameVariant } from "#candidate/own-name";
|
|
10
10
|
import { normalizeLocalityForKey } from "#street/normalize";
|
|
11
11
|
/**
|
|
12
|
-
* Key-count threshold for the gloss anomaly detector
|
|
13
|
-
*
|
|
14
|
-
* this number
|
|
12
|
+
* Key-count threshold for the gloss anomaly detector.
|
|
13
|
+
*
|
|
14
|
+
* A legitimate famous place is separated by the prominence check rather than this number by itself.
|
|
15
15
|
*/
|
|
16
16
|
export const GLOSS_KEY_THRESHOLD = 50;
|
|
17
17
|
/**
|
|
18
|
-
* Placetypes the gloss detector never flags
|
|
19
|
-
*
|
|
20
|
-
* tail, where a place named by a common noun ("Poisson", "Sunday") accumulating 200+ translations is a
|
|
21
|
-
* machine-translated gloss set, not fame.
|
|
18
|
+
* Placetypes the gloss detector never flags: a country or region legitimately has a
|
|
19
|
+
* name in every language, so key volume provides no signal there.
|
|
22
20
|
*/
|
|
23
21
|
export const GLOSS_EXCLUDED_PLACETYPES = new Set([
|
|
24
22
|
"country",
|
|
@@ -31,21 +29,11 @@ export const GLOSS_EXCLUDED_PLACETYPES = new Set([
|
|
|
31
29
|
"county",
|
|
32
30
|
]);
|
|
33
31
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* regression check). Both stamp `is_primary = 0` rows only — a place's canonical name and the `place_abbr` region
|
|
37
|
-
* abbreviations are never a gloss or a variant.
|
|
38
|
-
*
|
|
39
|
-
* - `gloss` is ANOMALY-based, and stamps only the certain core: key volume at/over the threshold + a non-admin placetype
|
|
40
|
-
*
|
|
41
|
-
* - NO measured prominence (population absent AND importance unmeasured). Provenance cannot separate a gloss from an
|
|
42
|
-
* exonym — WOF imported both as `x_preferred` — and prominence is what rescues New York/Paris.
|
|
43
|
-
* - `abbr` is PROVENANCE-based — the #936 signal: a WOF `variant` name in one of the country's official languages (or
|
|
44
|
-
* English), measured there at a 13× key-collision rate. A source without a `names` table (fixture-scale admin DBs)
|
|
45
|
-
* skips this detector loudly.
|
|
32
|
+
* Stamp `name_role` on non-primary rows: `abbr` by provenance, `variant` by
|
|
33
|
+
* own-name verdict, then `gloss` by key-volume anomaly.
|
|
46
34
|
*
|
|
47
|
-
*
|
|
48
|
-
* any role.
|
|
35
|
+
* @returns The stamp counts plus the census the prototype exists to report:
|
|
36
|
+
* how much of the ≥-threshold key tail has any role.
|
|
49
37
|
*/
|
|
50
38
|
export function stampNameRoles(ctx) {
|
|
51
39
|
const { src, out, attrs, keyCounts, glossThreshold, progress } = ctx;
|
|
@@ -63,7 +51,7 @@ export function stampNameRoles(ctx) {
|
|
|
63
51
|
continue;
|
|
64
52
|
if (GLOSS_EXCLUDED_PLACETYPES.has(ptNameByID.get(a.ptid) ?? ""))
|
|
65
53
|
continue;
|
|
66
|
-
if (a.pop > 0 || a.imp != null)
|
|
54
|
+
if ((a.pop ?? 0) > 0 || a.imp != null)
|
|
67
55
|
continue;
|
|
68
56
|
glossSids.push(sid);
|
|
69
57
|
}
|
|
@@ -73,9 +61,8 @@ export function stampNameRoles(ctx) {
|
|
|
73
61
|
const hasSourceNames = tableExists(src, "names");
|
|
74
62
|
if (hasSourceNames) {
|
|
75
63
|
out.exec("BEGIN");
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
// qualify by kind alone; everything else qualifies as a variant in an official language.
|
|
64
|
+
// WOF's abbreviation/short name kinds qualify by kind only.
|
|
65
|
+
// Everything else qualifies as a variant in an official language.
|
|
79
66
|
for (const r of src
|
|
80
67
|
.prepare("SELECT id, name, language FROM names WHERE privateuse = 'variant' OR language IN ('abbr', 'short')")
|
|
81
68
|
.iterate()) {
|
|
@@ -98,19 +85,14 @@ export function stampNameRoles(ctx) {
|
|
|
98
85
|
else {
|
|
99
86
|
progress("roles", "source carries no `names` table — abbr detector skipped (gloss still runs)");
|
|
100
87
|
}
|
|
101
|
-
// Stamp order is precedence:
|
|
102
|
-
// then gloss fills what neither claimed.
|
|
88
|
+
// Stamp order is precedence: abbr first, then the own-name variant verdict, then gloss fills what neither claimed.
|
|
103
89
|
const roleAbbr = Number(out
|
|
104
90
|
.prepare(`UPDATE cand_stage SET name_role = 'abbr'
|
|
105
91
|
WHERE is_primary = 0 AND EXISTS (
|
|
106
92
|
SELECT 1 FROM role_key rk WHERE rk.spr_id = cand_stage.spr_id AND rk.name_key = cand_stage.name_key)`)
|
|
107
93
|
.run().changes);
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
// is per (alias key, primary key) pair, so it runs in JS over the still-unstamped alias rows;
|
|
111
|
-
// an uncovered script answers no-verdict and stamps nothing (own-name.ts owns the predicate and
|
|
112
|
-
// its measured threshold). Runs BEFORE gloss on purpose: a surface that IS the place's own name
|
|
113
|
-
// is not a translation, whatever the key volume says.
|
|
94
|
+
// Runs before gloss so the place's own name remains its source name.
|
|
95
|
+
// An uncovered script answers no-verdict.
|
|
114
96
|
out.exec("CREATE TEMP TABLE variant_key (spr_id INTEGER NOT NULL, name_key TEXT NOT NULL, PRIMARY KEY (spr_id, name_key)) WITHOUT ROWID");
|
|
115
97
|
const insVariantKey = out.prepare("INSERT OR IGNORE INTO variant_key VALUES (?, ?)");
|
|
116
98
|
let variantScanned = 0;
|