@mailwoman/resolver-wof-sqlite 10.0.0 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -8
- package/lib/address/point/interpolation.ts +45 -39
- package/lib/address/point/schema.ts +17 -40
- package/lib/address/point.ts +316 -0
- package/lib/{address/index.ts → address.ts} +1 -1
- package/lib/ancestry/backfill.ts +20 -86
- package/lib/{ancestry/index.ts → ancestry.ts} +19 -15
- package/lib/build/candidate.ts +122 -174
- package/lib/build/population-corrections.ts +64 -0
- package/lib/build/slim.ts +44 -114
- package/lib/candidate/alias-bags.ts +16 -17
- package/lib/candidate/ancestors/schema.ts +77 -61
- package/lib/candidate/ancestors/sidecar.ts +15 -22
- package/lib/candidate/country-display-names.ts +6 -20
- package/lib/candidate/extract-fold.ts +10 -55
- package/lib/candidate/fts.ts +5 -23
- package/lib/candidate/importance.ts +65 -68
- package/lib/candidate/lookup.ts +124 -415
- package/lib/candidate/name-roles.ts +15 -33
- package/lib/candidate/own-name.ts +35 -32
- package/lib/candidate/place-attrs.ts +20 -13
- package/lib/candidate/schema.ts +29 -65
- package/lib/candidate/scoring.ts +54 -93
- package/lib/capital-schema.ts +21 -17
- package/lib/capitals.ts +29 -27
- package/lib/coincident-roles.ts +85 -55
- package/lib/convention/schema.ts +15 -16
- package/lib/convention.ts +144 -0
- package/lib/coverage-manifest-schema.ts +40 -45
- package/lib/currency-backfill.ts +34 -79
- package/lib/env.ts +1 -1
- package/lib/exact-match.ts +32 -21
- package/lib/extracts.ts +97 -74
- package/lib/fst/autocomplete.ts +54 -37
- package/lib/fst/builder.ts +37 -41
- package/lib/fst/deserialize-web.ts +16 -17
- package/lib/fst/format.ts +41 -23
- package/lib/fst/freshness.ts +43 -120
- package/lib/fst/matcher.ts +7 -5
- package/lib/fst/serialize.ts +54 -74
- package/lib/fst/types.ts +78 -75
- package/lib/{fst/index.ts → fst.ts} +1 -0
- package/lib/fts/query.ts +5 -36
- package/lib/fts.ts +280 -0
- package/lib/geonames/aliases.ts +73 -144
- package/lib/geonames/postal.ts +162 -71
- package/lib/index.ts +9 -8
- package/lib/interpolation.ts +48 -100
- package/lib/lookup.ts +155 -270
- package/lib/name-score.ts +9 -7
- package/lib/nsul/lookup.ts +37 -54
- package/lib/nsul/schema.ts +16 -43
- package/lib/paths.ts +159 -0
- package/lib/place-importance-schema.ts +62 -169
- package/lib/poi/lookup.ts +104 -121
- package/lib/poi/schema.ts +42 -26
- package/lib/polygon-schema.ts +10 -6
- package/lib/postal/city/alias/lookup.ts +22 -40
- package/lib/postal/city/alias/schema.ts +14 -10
- package/lib/postal/city/candidate-schema.ts +26 -20
- package/lib/postcode-point-lookup.ts +8 -27
- package/lib/primary-preference.ts +46 -126
- package/lib/proximity-rerank.ts +44 -33
- package/lib/ranking-weights.ts +105 -78
- package/lib/region-keys.ts +70 -42
- package/lib/reverse.ts +149 -86
- package/lib/schema.ts +73 -50
- package/lib/search-fetch.ts +90 -68
- package/lib/sqlite/convention-source.ts +15 -23
- package/lib/sqlite/utils.ts +19 -22
- package/lib/street/centroid/schema.ts +37 -42
- package/lib/street/{centroid/index.ts → centroid.ts} +16 -25
- package/lib/street/morphology/fst/builder.ts +60 -42
- package/lib/street/morphology/fst/loader.ts +40 -32
- package/lib/street/name-lookup.ts +45 -41
- package/lib/street/normalize.ts +88 -219
- package/lib/street/segment-schema.ts +116 -43
- package/lib/{street/index.ts → street.ts} +1 -1
- package/lib/types.ts +109 -150
- package/lib/unified-schema.ts +29 -29
- package/lib/uprn/existence.ts +30 -19
- package/lib/uprn/lookup.ts +29 -68
- package/lib/uprn/schema.ts +18 -40
- package/lib/weights-overlay-linker.ts +236 -252
- package/out/address/point/interpolation.d.ts +20 -23
- package/out/address/point/interpolation.d.ts.map +1 -1
- package/out/address/point/interpolation.js +42 -39
- package/out/address/point/interpolation.js.map +1 -1
- package/out/address/point/schema.d.ts +12 -35
- package/out/address/point/schema.d.ts.map +1 -1
- package/out/address/point/schema.js +3 -19
- package/out/address/point/schema.js.map +1 -1
- package/out/address/point.d.ts +57 -0
- package/out/address/point.d.ts.map +1 -0
- package/out/address/point.js +206 -0
- package/out/address/point.js.map +1 -0
- package/out/{address/index.js → address.d.ts} +2 -2
- package/out/address.d.ts.map +1 -0
- package/out/{address/index.d.ts → address.js} +2 -2
- 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 +14 -74
- 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 +82 -112
- package/out/build/candidate.d.ts.map +1 -1
- package/out/build/candidate.js +17 -100
- package/out/build/candidate.js.map +1 -1
- 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 +8 -44
- package/out/build/slim.d.ts.map +1 -1
- package/out/build/slim.js +33 -94
- package/out/build/slim.js.map +1 -1
- package/out/candidate/alias-bags.d.ts +6 -6
- package/out/candidate/alias-bags.d.ts.map +1 -1
- package/out/candidate/alias-bags.js +16 -17
- package/out/candidate/alias-bags.js.map +1 -1
- package/out/candidate/ancestors/schema.d.ts +73 -57
- package/out/candidate/ancestors/schema.d.ts.map +1 -1
- package/out/candidate/ancestors/schema.js +56 -48
- package/out/candidate/ancestors/schema.js.map +1 -1
- package/out/candidate/ancestors/sidecar.d.ts +3 -8
- package/out/candidate/ancestors/sidecar.d.ts.map +1 -1
- package/out/candidate/ancestors/sidecar.js +15 -22
- package/out/candidate/ancestors/sidecar.js.map +1 -1
- 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 +7 -15
- package/out/candidate/extract-fold.d.ts.map +1 -1
- package/out/candidate/extract-fold.js +5 -47
- package/out/candidate/extract-fold.js.map +1 -1
- package/out/candidate/fts.d.ts +5 -23
- package/out/candidate/fts.d.ts.map +1 -1
- package/out/candidate/fts.js +5 -23
- package/out/candidate/fts.js.map +1 -1
- package/out/candidate/importance.d.ts +60 -65
- package/out/candidate/importance.d.ts.map +1 -1
- package/out/candidate/importance.js +56 -63
- package/out/candidate/importance.js.map +1 -1
- package/out/candidate/lookup.d.ts +18 -55
- package/out/candidate/lookup.d.ts.map +1 -1
- package/out/candidate/lookup.js +82 -385
- package/out/candidate/lookup.js.map +1 -1
- package/out/candidate/name-roles.d.ts +9 -21
- 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 +35 -32
- 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 +27 -62
- package/out/candidate/schema.d.ts.map +1 -1
- package/out/candidate/schema.js +10 -22
- package/out/candidate/schema.js.map +1 -1
- package/out/candidate/scoring.d.ts +7 -8
- package/out/candidate/scoring.d.ts.map +1 -1
- package/out/candidate/scoring.js +52 -89
- package/out/candidate/scoring.js.map +1 -1
- 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 +27 -25
- 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 +72 -50
- package/out/coincident-roles.js.map +1 -1
- package/out/convention/schema.d.ts +14 -14
- 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 +34 -39
- package/out/coverage-manifest-schema.d.ts.map +1 -1
- package/out/coverage-manifest-schema.js +25 -34
- package/out/coverage-manifest-schema.js.map +1 -1
- package/out/currency-backfill.d.ts +16 -38
- package/out/currency-backfill.d.ts.map +1 -1
- package/out/currency-backfill.js +19 -46
- package/out/currency-backfill.js.map +1 -1
- package/out/env.d.ts +1 -1
- 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 +32 -21
- package/out/exact-match.js.map +1 -1
- package/out/extracts.d.ts +66 -55
- 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 +29 -21
- package/out/fst/autocomplete.d.ts.map +1 -1
- package/out/fst/autocomplete.js +39 -28
- package/out/fst/autocomplete.js.map +1 -1
- package/out/fst/builder.d.ts.map +1 -1
- package/out/fst/builder.js +37 -41
- package/out/fst/builder.js.map +1 -1
- package/out/fst/deserialize-web.d.ts +4 -4
- package/out/fst/deserialize-web.d.ts.map +1 -1
- package/out/fst/deserialize-web.js +15 -16
- 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 +19 -81
- package/out/fst/freshness.d.ts.map +1 -1
- package/out/fst/freshness.js +31 -94
- package/out/fst/freshness.js.map +1 -1
- package/out/fst/matcher.d.ts +5 -4
- 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 +28 -28
- package/out/fst/serialize.d.ts.map +1 -1
- package/out/fst/serialize.js +53 -71
- package/out/fst/serialize.js.map +1 -1
- package/out/fst/types.d.ts +78 -74
- 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} +2 -1
- package/out/fst.d.ts.map +1 -0
- package/out/{fst/index.d.ts → fst.js} +2 -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 -62
- package/out/geonames/aliases.d.ts.map +1 -1
- package/out/geonames/aliases.js +45 -117
- package/out/geonames/aliases.js.map +1 -1
- package/out/geonames/postal.d.ts +84 -44
- package/out/geonames/postal.d.ts.map +1 -1
- package/out/geonames/postal.js +115 -73
- 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 +9 -8
- package/out/index.d.ts.map +1 -1
- package/out/index.js +6 -5
- package/out/index.js.map +1 -1
- package/out/interpolation.d.ts +18 -55
- package/out/interpolation.d.ts.map +1 -1
- package/out/interpolation.js +27 -69
- package/out/interpolation.js.map +1 -1
- package/out/lookup.d.ts +23 -51
- package/out/lookup.d.ts.map +1 -1
- package/out/lookup.js +136 -234
- 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 +51 -143
- package/out/place-importance-schema.d.ts.map +1 -1
- package/out/place-importance-schema.js +28 -143
- package/out/place-importance-schema.js.map +1 -1
- package/out/poi/lookup.d.ts +40 -47
- package/out/poi/lookup.d.ts.map +1 -1
- package/out/poi/lookup.js +69 -96
- 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 +20 -23
- package/out/postal/city/alias/lookup.d.ts.map +1 -1
- package/out/postal/city/alias/lookup.js +17 -30
- package/out/postal/city/alias/lookup.js.map +1 -1
- package/out/postal/city/alias/schema.d.ts +14 -10
- package/out/postal/city/alias/schema.d.ts.map +1 -1
- package/out/postal/city/alias/schema.js +10 -8
- package/out/postal/city/alias/schema.js.map +1 -1
- package/out/postal/city/candidate-schema.d.ts +25 -19
- package/out/postal/city/candidate-schema.d.ts.map +1 -1
- package/out/postal/city/candidate-schema.js +21 -17
- package/out/postal/city/candidate-schema.js.map +1 -1
- package/out/{postal/index.d.ts → postal.d.ts} +1 -1
- package/out/postal.d.ts.map +1 -0
- package/out/{postal/index.js → postal.js} +1 -1
- package/out/postal.js.map +1 -0
- package/out/postcode-point-lookup.d.ts +6 -24
- 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 +38 -92
- package/out/primary-preference.d.ts.map +1 -1
- package/out/primary-preference.js +15 -99
- package/out/primary-preference.js.map +1 -1
- package/out/proximity-rerank.d.ts +41 -30
- 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 +98 -64
- 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 +50 -31
- 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 +78 -50
- package/out/reverse.d.ts.map +1 -1
- package/out/reverse.js +98 -61
- package/out/reverse.js.map +1 -1
- package/out/schema.d.ts +72 -49
- 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 +12 -16
- package/out/sqlite/convention-source.d.ts.map +1 -1
- package/out/sqlite/convention-source.js +13 -22
- package/out/sqlite/convention-source.js.map +1 -1
- package/out/sqlite/utils.d.ts +19 -19
- package/out/sqlite/utils.d.ts.map +1 -1
- package/out/sqlite/utils.js +14 -15
- package/out/sqlite/utils.js.map +1 -1
- package/out/street/centroid/schema.d.ts +37 -42
- package/out/street/centroid/schema.d.ts.map +1 -1
- package/out/street/centroid/schema.js +9 -21
- package/out/street/centroid/schema.js.map +1 -1
- package/out/street/centroid.d.ts +30 -0
- package/out/street/centroid.d.ts.map +1 -0
- package/out/street/{centroid/index.js → centroid.js} +13 -24
- package/out/street/centroid.js.map +1 -0
- package/out/street/morphology/fst/builder.d.ts +20 -10
- package/out/street/morphology/fst/builder.d.ts.map +1 -1
- package/out/street/morphology/fst/builder.js +44 -34
- package/out/street/morphology/fst/builder.js.map +1 -1
- package/out/street/morphology/fst/loader.d.ts +33 -26
- package/out/street/morphology/fst/loader.d.ts.map +1 -1
- package/out/street/morphology/fst/loader.js +23 -22
- package/out/street/morphology/fst/loader.js.map +1 -1
- 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 +34 -35
- 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 +77 -194
- 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.js → street.d.ts} +2 -2
- package/out/street.d.ts.map +1 -0
- package/out/{street/index.d.ts → street.js} +2 -2
- package/out/street.js.map +1 -0
- package/out/types.d.ts +84 -149
- 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 +21 -57
- 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 +138 -144
- package/out/weights-overlay-linker.d.ts.map +1 -1
- package/out/weights-overlay-linker.js +105 -159
- package/out/weights-overlay-linker.js.map +1 -1
- package/package.json +91 -596
- package/lib/address/point/index.ts +0 -328
- package/lib/convention/index.ts +0 -154
- package/lib/fts/index.ts +0 -361
- package/out/address/index.d.ts.map +0 -1
- package/out/address/index.js.map +0 -1
- package/out/address/point/index.d.ts +0 -53
- package/out/address/point/index.d.ts.map +0 -1
- package/out/address/point/index.js +0 -222
- package/out/address/point/index.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/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/index.d.ts.map +0 -1
- package/out/postal/index.js.map +0 -1
- package/out/street/centroid/index.d.ts +0 -40
- package/out/street/centroid/index.d.ts.map +0 -1
- package/out/street/centroid/index.js.map +0 -1
- package/out/street/index.d.ts.map +0 -1
- package/out/street/index.js.map +0 -1
- package/out/uprn/index.d.ts.map +0 -1
- package/out/uprn/index.js.map +0 -1
- /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/{postal/index.ts → postal.ts} +0 -0
- /package/lib/{uprn/index.ts → uprn.ts} +0 -0
|
@@ -2,132 +2,78 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* Bounded cross-country PRIMARY-NAME preference over a population-ordered candidate row set — the
|
|
7
|
-
* `is_primary` ranking signal, PURE and platform-free so the Node candidate lookup
|
|
8
|
-
* (`candidate-lookup.ts`) and the browser twin (`packages/resolver-wof-wasm/lib/httpvfs/resolver.ts`) rank with
|
|
9
|
-
* the SAME function rather than two copies that drift (the #861 server↔browser parity contract).
|
|
10
|
-
*
|
|
11
|
-
* Only type imports and arithmetic live here: anything with a `node:` import stays out.
|
|
12
5
|
*/
|
|
13
6
|
import type { CandidateTable } from "#candidate/schema";
|
|
14
7
|
/**
|
|
15
|
-
* The row
|
|
16
|
-
*
|
|
17
|
-
*
|
|
8
|
+
* The candidate-row fields that {@link rankByPrimaryPreference} reads.
|
|
9
|
+
*
|
|
10
|
+
* `is_primary` is optional, so an older artifact without the column skips the re-rank without an error.
|
|
18
11
|
*/
|
|
19
12
|
export type PrimaryPreferenceRow = Pick<CandidateTable, "neg_rank" | "country_id"> & Partial<Pick<CandidateTable, "is_primary" | "placetype_id" | "population" | "name_role">>;
|
|
20
13
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* The raw candidate order is population-first (`neg_rank ASC`) and treats an ALIAS row (a place's alt-name / exonym,
|
|
24
|
-
* `is_primary=0`) and a PRIMARY-name row (`is_primary=1`) on equal footing. So a foreign place whose transliterated
|
|
25
|
-
* exonym coincidentally normalizes to a query — Changchun CN stores the Turkish exonym "Çançun" (`name_key="cancun"`),
|
|
26
|
-
* 4.19 M pop — outranks the PRIMARY-name place the query actually means (Cancún MX, 0.89 M pop). This penalty makes a
|
|
27
|
-
* same-key alias have to clear a population MARGIN over a foreign primary before it wins.
|
|
14
|
+
* The log10-population penalty applied to an alias row when the top primary-name
|
|
15
|
+
* row for the same key is in another country.
|
|
28
16
|
*
|
|
29
|
-
*
|
|
30
|
-
* every alias and break the alt-names users depend on — "NYC"→New York, "LA"→Los Angeles, "Frisco"→San Francisco). Two
|
|
31
|
-
* bounds keep it a soft prior:
|
|
32
|
-
*
|
|
33
|
-
* 1. **Cross-country only.** The penalty applies to an alias ONLY when the top-population primary sharing the key is in a
|
|
34
|
-
* DIFFERENT country. A SAME-country nickname contest (San Francisco's alias "Frisco" vs the primary Frisco, TX —
|
|
35
|
-
* both US) is left on pure population, so the legitimate alias still wins.
|
|
36
|
-
* 2. **Population-bounded.** The penalty is {@link PRIMARY_PREFERENCE_LOG10} in log10-population units — an alias must be
|
|
37
|
-
* at least 10x more populous than the foreign primary to still win. So a genuinely dominant alias keeps winning
|
|
38
|
-
* ("Los Angeles" over La, Ghana — gap 1.6; "Las Vegas" over Vegas, Cuba — gap 2.4) while a near-tie coincidental
|
|
39
|
-
* collision defers to the primary (Cancún over Changchun — gap 0.7).
|
|
17
|
+
* An alias at least 10 times as populous still wins, so alternate names such as "LA" keep working.
|
|
40
18
|
*/
|
|
41
19
|
export declare const PRIMARY_PREFERENCE_LOG10 = 1;
|
|
42
20
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
21
|
+
* The number of population-ordered rows fetched per name key before
|
|
22
|
+
* {@link rankByPrimaryPreference} re-ranks them.
|
|
23
|
+
*
|
|
24
|
+
* A fetch of only the caller's `limit` could miss the intended primary behind more populous foreign aliases.
|
|
47
25
|
*/
|
|
48
26
|
export declare const RERANK_FETCH = 64;
|
|
49
27
|
/**
|
|
50
|
-
* A candidate row
|
|
28
|
+
* A candidate row with its re-ranked `effectiveNegRank` and its `demoted` flag.
|
|
51
29
|
*/
|
|
52
30
|
export type RankedRow<R> = R & {
|
|
53
31
|
/**
|
|
54
|
-
* `neg_rank` plus
|
|
55
|
-
*
|
|
56
|
-
*
|
|
32
|
+
* `neg_rank` plus any cross-country alias penalty.
|
|
33
|
+
*
|
|
34
|
+
* Rows are ordered by this value.
|
|
35
|
+
* The emitted `prominence` derives from it.
|
|
36
|
+
*
|
|
37
|
+
* The raw `neg_rank` stays on the row for the resolver's minimum winning score.
|
|
57
38
|
*/
|
|
58
39
|
effectiveNegRank: number;
|
|
59
40
|
/**
|
|
60
|
-
* True when this row is a cross-country alias that
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
41
|
+
* True when this row is a cross-country alias that the penalty moved behind
|
|
42
|
+
* the top primary for the same key.
|
|
43
|
+
*
|
|
44
|
+
* A demoted row loses `exactMatch`, so the resolver's country pin cannot promote
|
|
45
|
+
* a coincidental foreign exonym back over the primary.
|
|
46
|
+
* A dominant alias and a same-country alias are never demoted.
|
|
66
47
|
*/
|
|
67
48
|
demoted: boolean;
|
|
68
49
|
/**
|
|
69
|
-
* True when this row came from the
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* has always done and what every `exactMatch`-filtering consumer assumed.
|
|
50
|
+
* True when this row came from the typo-correction fallback.
|
|
51
|
+
* The fallback runs only after the exact probes miss.
|
|
52
|
+
*
|
|
53
|
+
* The row is still returned and ranked, but it never claims `exactMatch`.
|
|
74
54
|
*/
|
|
75
55
|
fuzzy?: boolean;
|
|
76
56
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
57
|
+
* Whether the row lies inside the query's region qualifier.
|
|
58
|
+
*
|
|
59
|
+
* The candidate lookup sets it when the artifact has the ancestors sidecar.
|
|
60
|
+
*
|
|
61
|
+
* When the field is absent, containment was not checked.
|
|
81
62
|
*/
|
|
82
63
|
containedByQualifier?: boolean;
|
|
83
64
|
/**
|
|
84
|
-
*
|
|
85
|
-
* `exemptVariantAliases` prevented it. PRESENT only when the exemption changed this row's treatment; absent on every
|
|
86
|
-
* row it merely inspected — an in-country variant, a primary, a set with no foreign top primary. The winner-level
|
|
87
|
-
* receipt downstream (`mechanism_fired_on.variant_alias_exemption`) counts this mark only when it survives onto the
|
|
88
|
-
* selected candidate.
|
|
65
|
+
* Set only when the variant-alias exemption spared this row the cross-country alias penalty.
|
|
89
66
|
*/
|
|
90
67
|
variantExempted?: true;
|
|
91
68
|
};
|
|
92
69
|
/**
|
|
93
|
-
*
|
|
94
|
-
* `candidate-lookup.test.ts` can exercise it on synthetic rows. `rows` arrive population-ordered (`neg_rank ASC`); an
|
|
95
|
-
* alias (`is_primary=0`) is pushed back by `delta` in log10-population units ONLY when the top-population primary
|
|
96
|
-
* sharing the key is in a different country, and is `demoted` out of the exact tier when that penalty leaves it BEHIND
|
|
97
|
-
* the primary. Returns the top `limit` after the re-rank, each annotated.
|
|
98
|
-
*
|
|
99
|
-
* `placetypes` (the artifact's own `placetype_codes` map) enables the LAST tiebreak, the SEAT preference: when
|
|
100
|
-
* `effectiveNegRank` and raw `neg_rank` both tie — two same-key rows population cannot separate at all — a
|
|
101
|
-
* {@link SEAT_PLACETYPE} row carrying a real population outranks every other placetype. Omit the map and every row
|
|
102
|
-
* scores 0, the term cancels, and the order is exactly the population-then-scan-order it was before.
|
|
103
|
-
*
|
|
104
|
-
* The tie it exists for is a DUPLICATE, not a contest. A district and its identically-named seat town are stored as two
|
|
105
|
-
* rows carrying the SAME population, so `neg_rank` is equal to the bit and `referential` follows it
|
|
106
|
-
* (`referentialFromPopulation` is a pure function of population). Turkey's `Of` is the measured case — locality
|
|
107
|
-
* 8114738869649 and its parent county 8837168432019 both hold population 44212 — and 358 locality/parent-county pairs
|
|
108
|
-
* across 15 countries share the shape in `admin-global-priority.db` (TR 162, CA 77, US 47, HR 24, DO 14). Without the
|
|
109
|
-
* term their order is whatever the scan hands the sorter.
|
|
70
|
+
* Re-ranks population-ordered candidate rows.
|
|
110
71
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* `PLACETYPE_FILTER_GROUPS` (core/resolver) never mixes `locality` with `county`: the `Of`-shape locality/county pair
|
|
114
|
-
* is PARTITIONED before this ranker runs, the locality probe fetches one row, and the walk's own `locality` request
|
|
115
|
-
* selects the seat by construction — the same winner, decided upstream. The tie that reaches an end-to-end answer
|
|
116
|
-
* through this term is the IN-GROUP residue: a locality/localadmin (or borough) duplicate whose `importance` values
|
|
117
|
-
* also tie. Downstream the resolver re-sorts by importance (`resolver/toponym-prior.ts`) but is stable on equal keys,
|
|
118
|
-
* so the order stamped here is the order that answers — inverting this term moves bare `Pu-cheng-hsien` 1,100 km
|
|
119
|
-
* (locality Pucheng over the 浦城县 localadmin, identical population and importance). Where importance separates the pair,
|
|
120
|
-
* the fame prior overrides by design; a probe with NO placetype filter (the browser cascade's last resort, the dev
|
|
121
|
-
* lookup tools) presents the full tie and this term is all that breaks it.
|
|
72
|
+
* A cross-country alias must beat the top primary by `delta` in log10 population.
|
|
73
|
+
* The function returns the top `limit` rows.
|
|
122
74
|
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* were contests between genuinely distinct places that merely tie — 2,885 `locality → neighbourhood` (a bare city name
|
|
126
|
-
* losing to a same-named hood), 2,973 `region → county`, 2,662 `postalcode → locality` — and 7,179 of the 11,377 sat at
|
|
127
|
-
* population 0, where a tie means NO EVIDENCE rather than equal evidence. Requiring a real population keeps the term
|
|
128
|
-
* off every no-evidence tie; promoting the populated-place tier specifically, rather than whatever is finer, keeps it
|
|
129
|
-
* off the admin-tier and hood contests. It can never reach a pair population separates: it does not override a
|
|
130
|
-
* population gap, it replaces an undetermined order with a stated one.
|
|
75
|
+
* When `placetypes` is given, an exact tie prefers a populated `locality`.
|
|
76
|
+
* This places a seat town ahead of a district with the same name and population.
|
|
131
77
|
*/
|
|
132
78
|
export declare function rankByPrimaryPreference<R extends PrimaryPreferenceRow>(rows: readonly R[], limit: number, delta?: number, placetypes?: ReadonlyMap<number, string>, exemptVariantAliases?: boolean): Array<RankedRow<R>>;
|
|
133
79
|
//# sourceMappingURL=primary-preference.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary-preference.d.ts","sourceRoot":"","sources":["../lib/primary-preference.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"primary-preference.d.ts","sourceRoot":"","sources":["../lib/primary-preference.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEvD;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,YAAY,CAAC,GACjF,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAA;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAA;AAIzC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG;IAC9B;;;;;;;OAOG;IACH,gBAAgB,EAAE,MAAM,CAAA;IAExB;;;;;;;OAOG;IACH,OAAO,EAAE,OAAO,CAAA;IAEhB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAE9B;;OAEG;IACH,eAAe,CAAC,EAAE,IAAI,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,oBAAoB,EACrE,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,KAAK,EAAE,MAAM,EACb,KAAK,SAA2B,EAChC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACxC,oBAAoB,UAAQ,GAC1B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CA2DrB"}
|
|
@@ -2,116 +2,44 @@
|
|
|
2
2
|
* @copyright Sister Software
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
|
-
*
|
|
6
|
-
* Bounded cross-country PRIMARY-NAME preference over a population-ordered candidate row set — the
|
|
7
|
-
* `is_primary` ranking signal, PURE and platform-free so the Node candidate lookup
|
|
8
|
-
* (`candidate-lookup.ts`) and the browser twin (`packages/resolver-wof-wasm/lib/httpvfs/resolver.ts`) rank with
|
|
9
|
-
* the SAME function rather than two copies that drift (the #861 server↔browser parity contract).
|
|
10
|
-
*
|
|
11
|
-
* Only type imports and arithmetic live here: anything with a `node:` import stays out.
|
|
12
5
|
*/
|
|
13
6
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* The raw candidate order is population-first (`neg_rank ASC`) and treats an ALIAS row (a place's alt-name / exonym,
|
|
17
|
-
* `is_primary=0`) and a PRIMARY-name row (`is_primary=1`) on equal footing. So a foreign place whose transliterated
|
|
18
|
-
* exonym coincidentally normalizes to a query — Changchun CN stores the Turkish exonym "Çançun" (`name_key="cancun"`),
|
|
19
|
-
* 4.19 M pop — outranks the PRIMARY-name place the query actually means (Cancún MX, 0.89 M pop). This penalty makes a
|
|
20
|
-
* same-key alias have to clear a population MARGIN over a foreign primary before it wins.
|
|
7
|
+
* The log10-population penalty applied to an alias row when the top primary-name
|
|
8
|
+
* row for the same key is in another country.
|
|
21
9
|
*
|
|
22
|
-
*
|
|
23
|
-
* every alias and break the alt-names users depend on — "NYC"→New York, "LA"→Los Angeles, "Frisco"→San Francisco). Two
|
|
24
|
-
* bounds keep it a soft prior:
|
|
25
|
-
*
|
|
26
|
-
* 1. **Cross-country only.** The penalty applies to an alias ONLY when the top-population primary sharing the key is in a
|
|
27
|
-
* DIFFERENT country. A SAME-country nickname contest (San Francisco's alias "Frisco" vs the primary Frisco, TX —
|
|
28
|
-
* both US) is left on pure population, so the legitimate alias still wins.
|
|
29
|
-
* 2. **Population-bounded.** The penalty is {@link PRIMARY_PREFERENCE_LOG10} in log10-population units — an alias must be
|
|
30
|
-
* at least 10x more populous than the foreign primary to still win. So a genuinely dominant alias keeps winning
|
|
31
|
-
* ("Los Angeles" over La, Ghana — gap 1.6; "Las Vegas" over Vegas, Cuba — gap 2.4) while a near-tie coincidental
|
|
32
|
-
* collision defers to the primary (Cancún over Changchun — gap 0.7).
|
|
10
|
+
* An alias at least 10 times as populous still wins, so alternate names such as "LA" keep working.
|
|
33
11
|
*/
|
|
34
12
|
export const PRIMARY_PREFERENCE_LOG10 = 1;
|
|
35
|
-
/**
|
|
36
|
-
* The placetype the seat preference promotes: the populated-place tier a district duplicate shares its name and its
|
|
37
|
-
* population with. Named rather than inlined because narrowing the term to this ONE tier is what keeps it off the
|
|
38
|
-
* region/county and locality/neighbourhood contests — see `rankByPrimaryPreference` for the measurement.
|
|
39
|
-
*/
|
|
40
13
|
const SEAT_PLACETYPE = "locality";
|
|
41
14
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
15
|
+
* The number of population-ordered rows fetched per name key before
|
|
16
|
+
* {@link rankByPrimaryPreference} re-ranks them.
|
|
17
|
+
*
|
|
18
|
+
* A fetch of only the caller's `limit` could miss the intended primary behind more populous foreign aliases.
|
|
46
19
|
*/
|
|
47
20
|
export const RERANK_FETCH = 64;
|
|
48
21
|
/**
|
|
49
|
-
*
|
|
50
|
-
* `candidate-lookup.test.ts` can exercise it on synthetic rows. `rows` arrive population-ordered (`neg_rank ASC`); an
|
|
51
|
-
* alias (`is_primary=0`) is pushed back by `delta` in log10-population units ONLY when the top-population primary
|
|
52
|
-
* sharing the key is in a different country, and is `demoted` out of the exact tier when that penalty leaves it BEHIND
|
|
53
|
-
* the primary. Returns the top `limit` after the re-rank, each annotated.
|
|
54
|
-
*
|
|
55
|
-
* `placetypes` (the artifact's own `placetype_codes` map) enables the LAST tiebreak, the SEAT preference: when
|
|
56
|
-
* `effectiveNegRank` and raw `neg_rank` both tie — two same-key rows population cannot separate at all — a
|
|
57
|
-
* {@link SEAT_PLACETYPE} row carrying a real population outranks every other placetype. Omit the map and every row
|
|
58
|
-
* scores 0, the term cancels, and the order is exactly the population-then-scan-order it was before.
|
|
59
|
-
*
|
|
60
|
-
* The tie it exists for is a DUPLICATE, not a contest. A district and its identically-named seat town are stored as two
|
|
61
|
-
* rows carrying the SAME population, so `neg_rank` is equal to the bit and `referential` follows it
|
|
62
|
-
* (`referentialFromPopulation` is a pure function of population). Turkey's `Of` is the measured case — locality
|
|
63
|
-
* 8114738869649 and its parent county 8837168432019 both hold population 44212 — and 358 locality/parent-county pairs
|
|
64
|
-
* across 15 countries share the shape in `admin-global-priority.db` (TR 162, CA 77, US 47, HR 24, DO 14). Without the
|
|
65
|
-
* term their order is whatever the scan hands the sorter.
|
|
22
|
+
* Re-ranks population-ordered candidate rows.
|
|
66
23
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `PLACETYPE_FILTER_GROUPS` (core/resolver) never mixes `locality` with `county`: the `Of`-shape locality/county pair
|
|
70
|
-
* is PARTITIONED before this ranker runs, the locality probe fetches one row, and the walk's own `locality` request
|
|
71
|
-
* selects the seat by construction — the same winner, decided upstream. The tie that reaches an end-to-end answer
|
|
72
|
-
* through this term is the IN-GROUP residue: a locality/localadmin (or borough) duplicate whose `importance` values
|
|
73
|
-
* also tie. Downstream the resolver re-sorts by importance (`resolver/toponym-prior.ts`) but is stable on equal keys,
|
|
74
|
-
* so the order stamped here is the order that answers — inverting this term moves bare `Pu-cheng-hsien` 1,100 km
|
|
75
|
-
* (locality Pucheng over the 浦城县 localadmin, identical population and importance). Where importance separates the pair,
|
|
76
|
-
* the fame prior overrides by design; a probe with NO placetype filter (the browser cascade's last resort, the dev
|
|
77
|
-
* lookup tools) presents the full tie and this term is all that breaks it.
|
|
24
|
+
* A cross-country alias must beat the top primary by `delta` in log10 population.
|
|
25
|
+
* The function returns the top `limit` rows.
|
|
78
26
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* were contests between genuinely distinct places that merely tie — 2,885 `locality → neighbourhood` (a bare city name
|
|
82
|
-
* losing to a same-named hood), 2,973 `region → county`, 2,662 `postalcode → locality` — and 7,179 of the 11,377 sat at
|
|
83
|
-
* population 0, where a tie means NO EVIDENCE rather than equal evidence. Requiring a real population keeps the term
|
|
84
|
-
* off every no-evidence tie; promoting the populated-place tier specifically, rather than whatever is finer, keeps it
|
|
85
|
-
* off the admin-tier and hood contests. It can never reach a pair population separates: it does not override a
|
|
86
|
-
* population gap, it replaces an undetermined order with a stated one.
|
|
27
|
+
* When `placetypes` is given, an exact tie prefers a populated `locality`.
|
|
28
|
+
* This places a seat town ahead of a district with the same name and population.
|
|
87
29
|
*/
|
|
88
30
|
export function rankByPrimaryPreference(rows, limit, delta = PRIMARY_PREFERENCE_LOG10, placetypes, exemptVariantAliases = false) {
|
|
89
|
-
|
|
90
|
-
// when the set has no primary → nothing to prefer, penalty is 0, order stays population-first (today's behavior).
|
|
91
|
-
let topPrimary;
|
|
31
|
+
let topPrimary = null;
|
|
92
32
|
for (const r of rows) {
|
|
93
33
|
if (r.is_primary === 1 && (topPrimary == null || r.neg_rank < topPrimary.neg_rank)) {
|
|
94
34
|
topPrimary = r;
|
|
95
35
|
}
|
|
96
36
|
}
|
|
97
37
|
const topCountry = topPrimary?.country_id;
|
|
98
|
-
// A cross-country alias (different country than the top primary) is penalized; it is DEMOTED when even after — i.e.
|
|
99
|
-
// the penalty leaves its effective rank behind the primary's raw rank (it lost the bounded population contest).
|
|
100
|
-
//
|
|
101
|
-
// #1882 exemption (opt-in): a `name_role = 'variant'` alias is the holder's OWN primary name in another
|
|
102
|
-
// orthography (`Брэст` → `brest`, `George Town` → `georgetown` — the build's own-name detector), so the
|
|
103
|
-
// query is naming THAT place, not colliding with it; the penalty exists for the coincidental-collision
|
|
104
|
-
// class ("Çançun"/`cancun`), which the detector's measured threshold keeps un-stamped. An artifact
|
|
105
|
-
// predating the role column carries no 'variant' rows, so the flag no-ops there by construction.
|
|
106
38
|
const wouldPenalize = (r) => typeof topCountry === "number" && r.is_primary !== 1 && r.country_id !== topCountry;
|
|
107
39
|
const isCrossCountryAlias = (r) => wouldPenalize(r) && !(exemptVariantAliases && r.name_role === "variant");
|
|
108
40
|
const annotate = (r) => {
|
|
109
41
|
const penalized = isCrossCountryAlias(r);
|
|
110
42
|
const effectiveNegRank = r.neg_rank + (penalized ? delta : 0);
|
|
111
|
-
// The firing mark (#1893): this row WOULD have taken the cross-country penalty and the exemption
|
|
112
|
-
// prevented it — conditions the winner-level receipt needs, computed where the decision is made. A
|
|
113
|
-
// variant row that was in-country, primary, or keyed under a set with no foreign primary never
|
|
114
|
-
// fired, and stays unmarked.
|
|
115
43
|
const exempted = !penalized && exemptVariantAliases && r.name_role === "variant" && wouldPenalize(r);
|
|
116
44
|
return {
|
|
117
45
|
...r,
|
|
@@ -120,29 +48,17 @@ export function rankByPrimaryPreference(rows, limit, delta = PRIMARY_PREFERENCE_
|
|
|
120
48
|
...(exempted ? { variantExempted: true } : {}),
|
|
121
49
|
};
|
|
122
50
|
};
|
|
123
|
-
|
|
124
|
-
// placetype on the row, an id the map does not carry, a placetype that is not the seat tier, or no
|
|
125
|
-
// recorded population. Every row scoring 0 cancels the term, leaving exactly the
|
|
126
|
-
// population-then-scan-order the sort had before it existed.
|
|
127
|
-
const seatPreference = (r) => placetypes != null &&
|
|
51
|
+
const seatPreference = (r) => placetypes &&
|
|
128
52
|
typeof r.placetype_id === "number" &&
|
|
129
53
|
typeof r.population === "number" &&
|
|
130
54
|
r.population > 0 &&
|
|
131
55
|
placetypes.get(r.placetype_id) === SEAT_PLACETYPE
|
|
132
56
|
? 1
|
|
133
57
|
: 0;
|
|
134
|
-
// 1 for a PRIMARY-name row whose prominence is unmeasured (population 0), 0 for everything else. Two unmeasured
|
|
135
|
-
// rows tie on `neg_rank`, and that tie used to fall through to scan order — the B-tree's `spr_id`, which is no
|
|
136
|
-
// evidence about either place. A row that IS named X ranks ahead of one merely also-known-as X when nothing else
|
|
137
|
-
// separates them: Taiwan's 溪州鄉 township row (its own name, unmeasured) over the village 溪洲 30 km away that
|
|
138
|
-
// carries `溪州鄉` as an alias (unmeasured), which the lower WOF id had been winning. Populated ties are untouched —
|
|
139
|
-
// a populated alias ("NYC") never reaches this term, and two populated rows keep the order they had.
|
|
140
58
|
const unmeasuredPrimary = (r) => r.is_primary === 1 && typeof r.population === "number" && r.population === 0 ? 1 : 0;
|
|
141
59
|
return (rows
|
|
142
60
|
.map((r, i) => ({ row: annotate(r), i }))
|
|
143
|
-
//
|
|
144
|
-
// among unmeasured rows, then original index (stable).
|
|
145
|
-
// oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array; toSorted would double-allocate on a hot path
|
|
61
|
+
// oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array. toSorted would double-allocate on a hot path
|
|
146
62
|
.sort((a, b) => a.row.effectiveNegRank - b.row.effectiveNegRank ||
|
|
147
63
|
a.row.neg_rank - b.row.neg_rank ||
|
|
148
64
|
seatPreference(b.row) - seatPreference(a.row) ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primary-preference.js","sourceRoot":"","sources":["../lib/primary-preference.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"primary-preference.js","sourceRoot":"","sources":["../lib/primary-preference.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAEzC,MAAM,cAAc,GAAG,UAAU,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAiD9B;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACtC,IAAkB,EAClB,KAAa,EACb,KAAK,GAAG,wBAAwB,EAChC,UAAwC,EACxC,oBAAoB,GAAG,KAAK;IAE5B,IAAI,UAAU,GAAa,IAAI,CAAA;IAE/B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpF,UAAU,GAAG,CAAC,CAAA;QACf,CAAC;IACF,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,EAAE,UAAU,CAAA;IAEzC,MAAM,aAAa,GAAG,CAAC,CAAI,EAAW,EAAE,CACvC,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU,CAAA;IAEpF,MAAM,mBAAmB,GAAG,CAAC,CAAI,EAAW,EAAE,CAC7C,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IAEzE,MAAM,QAAQ,GAAG,CAAC,CAAI,EAAgB,EAAE;QACvC,MAAM,SAAS,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,gBAAgB,GAAG,CAAC,CAAC,QAAQ,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE7D,MAAM,QAAQ,GAAG,CAAC,SAAS,IAAI,oBAAoB,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,aAAa,CAAC,CAAC,CAAC,CAAA;QAEpG,OAAO;YACN,GAAG,CAAC;YACJ,gBAAgB;YAChB,OAAO,EAAE,SAAS,IAAI,gBAAgB,GAAG,UAAW,CAAC,QAAQ;YAC7D,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAA;IACF,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,CAAC,CAAI,EAAU,EAAE,CACvC,UAAU;QACV,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ;QAClC,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ;QAChC,CAAC,CAAC,UAAU,GAAG,CAAC;QAChB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,cAAc;QAChD,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,CAAC,CAAA;IAEL,MAAM,iBAAiB,GAAG,CAAC,CAAI,EAAU,EAAE,CAC1C,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAErF,OAAO,CACN,IAAI;SACF,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAEzC,8HAA8H;SAC7H,IAAI,CACJ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACR,CAAC,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB;QAC/C,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ;QAC/B,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7C,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC;QACnD,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CACV;SACA,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CACnB,CAAA;AACF,CAAC"}
|
|
@@ -3,23 +3,24 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* filter.
|
|
6
|
+
* Re-order exact-match candidates by population and nearness on one additive scale when bias hints
|
|
7
|
+
* are present (the demo's map viewport, a user location), so an in-view namesake wins a tie
|
|
8
|
+
* without a hard filter. With no bias the order is plain population order, byte-identical.
|
|
9
9
|
*
|
|
10
|
-
* This lives in its own platform-free module because it has to run identically in two places
|
|
11
|
-
* reader and the browser byte-range twin. That is the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* This lives in its own platform-free module because it has to run identically in two places, the
|
|
11
|
+
* Node candidate reader and the browser byte-range twin. That is the server and demo parity
|
|
12
|
+
* interface held by construction. Constants by themselves were not enough, since the two copies agreed on
|
|
13
|
+
* every literal and still diverged on which field the population term reads and on whether the
|
|
14
|
+
* combined value is written back.
|
|
15
15
|
*
|
|
16
16
|
* Two properties are required and easy to lose when transcribing:
|
|
17
17
|
*
|
|
18
|
-
* 1. The population base is `prominence ?? score
|
|
19
|
-
* primary preference, so reading raw score lets a coincidental foreign alias ride population
|
|
20
|
-
* whenever a viewport hint happens to be present.
|
|
21
|
-
* 2. The combined value is
|
|
22
|
-
* caller that only returns the array in bias order has its
|
|
18
|
+
* 1. The population base is `prominence ?? score`. `prominence` contains the bounded cross-country
|
|
19
|
+
* primary preference, so reading raw score lets a coincidental foreign alias ride population
|
|
20
|
+
* back over a primary whenever a viewport hint happens to be present.
|
|
21
|
+
* 2. The combined value is persisted into `prominence`. The resolver walk re-sorts by
|
|
22
|
+
* `prominence ?? score`, so a caller that only returns the array in bias order has its
|
|
23
|
+
* ordering silently discarded downstream.
|
|
23
24
|
*/
|
|
24
25
|
/**
|
|
25
26
|
* Full magnitude of the nearness term at distance 0, before decay.
|
|
@@ -30,22 +31,25 @@ export declare const BIAS_BOOST = 4;
|
|
|
30
31
|
*/
|
|
31
32
|
export declare const POP_BOOST = 4;
|
|
32
33
|
/**
|
|
33
|
-
* `log10(population + 1)` at which the population term saturates
|
|
34
|
-
*
|
|
34
|
+
* `log10(population + 1)` at which the population term saturates.
|
|
35
|
+
*
|
|
36
|
+
* A value of 6 means a population of one million warrants the whole {@link POP_BOOST},
|
|
37
|
+
* and larger populations warrant no more.
|
|
35
38
|
*/
|
|
36
39
|
export declare const POP_SCALE_LOG10 = 6;
|
|
37
40
|
/**
|
|
38
41
|
* Distance at which the nearness term halves.
|
|
39
42
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* Sharper than the FTS reader's 100 km on purpose, because the candidate backend's
|
|
44
|
+
* score is log-population by itself with no bm25 document term.
|
|
45
|
+
* This weakens the population signal relative to the bias.
|
|
46
|
+
*
|
|
47
|
+
* At around 30 km the boost reaches only candidates the user is looking at,
|
|
48
|
+
* so an in-view namesake still wins and a distant one does not.
|
|
45
49
|
*/
|
|
46
50
|
export declare const PROX_SCALE_KM = 30;
|
|
47
51
|
/**
|
|
48
|
-
* One bias hint
|
|
52
|
+
* One bias hint, a coordinate the user is looking at or standing on, optionally weighted.
|
|
49
53
|
*/
|
|
50
54
|
export interface ProximityBias {
|
|
51
55
|
lat: number;
|
|
@@ -53,25 +57,32 @@ export interface ProximityBias {
|
|
|
53
57
|
weight?: number;
|
|
54
58
|
}
|
|
55
59
|
/**
|
|
56
|
-
* The candidate fields the re-rank reads and writes.
|
|
57
|
-
*
|
|
60
|
+
* The candidate fields the re-rank reads and writes.
|
|
61
|
+
*
|
|
62
|
+
* This is structural, so the Node reader's `PlaceCandidate` and the browser twin's
|
|
63
|
+
* row shape both satisfy it without an adapter.
|
|
58
64
|
*/
|
|
59
65
|
export interface ProximityRerankable {
|
|
60
66
|
lat: number;
|
|
61
67
|
lon: number;
|
|
62
68
|
score: number;
|
|
63
|
-
prominence?: number;
|
|
69
|
+
prominence?: number | null;
|
|
64
70
|
}
|
|
65
71
|
/**
|
|
66
|
-
* Population plus nearness on one additive scale.
|
|
67
|
-
*
|
|
72
|
+
* Population plus nearness on one additive scale.
|
|
73
|
+
*
|
|
74
|
+
* Exported for tests and for a caller that wants the value without the sort.
|
|
75
|
+
* Ordinary callers want {@link applyProximityRerank}.
|
|
68
76
|
*/
|
|
69
77
|
export declare function combinedProminence(candidate: ProximityRerankable, bias: readonly ProximityBias[]): number;
|
|
70
78
|
/**
|
|
71
|
-
* Re-order `candidates` in place by {@link combinedProminence}, persisting each
|
|
72
|
-
* resolver walk's own `prominence ?? score`
|
|
73
|
-
*
|
|
74
|
-
*
|
|
79
|
+
* Re-order `candidates` in place by {@link combinedProminence}, persisting each
|
|
80
|
+
* combined value into `prominence` so the resolver walk's own `prominence ?? score`
|
|
81
|
+
* sort preserves the bias order rather than undoing it.
|
|
82
|
+
*
|
|
83
|
+
* Stable within equal prominence, preserving the population order the index already gave.
|
|
84
|
+
* A caller with no bias hints must not call this.
|
|
85
|
+
* The no-bias path is plain population order by construction.
|
|
75
86
|
*/
|
|
76
87
|
export declare function applyProximityRerank<T extends ProximityRerankable>(candidates: T[], bias: readonly ProximityBias[]): T[];
|
|
77
88
|
//# sourceMappingURL=proximity-rerank.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proximity-rerank.d.ts","sourceRoot":"","sources":["../lib/proximity-rerank.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"proximity-rerank.d.ts","sourceRoot":"","sources":["../lib/proximity-rerank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH;;GAEG;AACH,eAAO,MAAM,UAAU,IAAI,CAAA;AAE3B;;GAEG;AACH,eAAO,MAAM,SAAS,IAAI,CAAA;AAE1B;;;;;GAKG;AACH,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,CAmBzG;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,mBAAmB,EACjE,UAAU,EAAE,CAAC,EAAE,EACf,IAAI,EAAE,SAAS,aAAa,EAAE,GAC5B,CAAC,EAAE,CAYL"}
|
package/out/proximity-rerank.js
CHANGED
|
@@ -3,23 +3,24 @@
|
|
|
3
3
|
* @license AGPL-3.0
|
|
4
4
|
* @author Teffen Ellis, et al.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* filter.
|
|
6
|
+
* Re-order exact-match candidates by population and nearness on one additive scale when bias hints
|
|
7
|
+
* are present (the demo's map viewport, a user location), so an in-view namesake wins a tie
|
|
8
|
+
* without a hard filter. With no bias the order is plain population order, byte-identical.
|
|
9
9
|
*
|
|
10
|
-
* This lives in its own platform-free module because it has to run identically in two places
|
|
11
|
-
* reader and the browser byte-range twin. That is the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* This lives in its own platform-free module because it has to run identically in two places, the
|
|
11
|
+
* Node candidate reader and the browser byte-range twin. That is the server and demo parity
|
|
12
|
+
* interface held by construction. Constants by themselves were not enough, since the two copies agreed on
|
|
13
|
+
* every literal and still diverged on which field the population term reads and on whether the
|
|
14
|
+
* combined value is written back.
|
|
15
15
|
*
|
|
16
16
|
* Two properties are required and easy to lose when transcribing:
|
|
17
17
|
*
|
|
18
|
-
* 1. The population base is `prominence ?? score
|
|
19
|
-
* primary preference, so reading raw score lets a coincidental foreign alias ride population
|
|
20
|
-
* whenever a viewport hint happens to be present.
|
|
21
|
-
* 2. The combined value is
|
|
22
|
-
* caller that only returns the array in bias order has its
|
|
18
|
+
* 1. The population base is `prominence ?? score`. `prominence` contains the bounded cross-country
|
|
19
|
+
* primary preference, so reading raw score lets a coincidental foreign alias ride population
|
|
20
|
+
* back over a primary whenever a viewport hint happens to be present.
|
|
21
|
+
* 2. The combined value is persisted into `prominence`. The resolver walk re-sorts by
|
|
22
|
+
* `prominence ?? score`, so a caller that only returns the array in bias order has its
|
|
23
|
+
* ordering silently discarded downstream.
|
|
23
24
|
*/
|
|
24
25
|
import { haversineKm } from "@mailwoman/spatial";
|
|
25
26
|
/**
|
|
@@ -31,30 +32,35 @@ export const BIAS_BOOST = 4;
|
|
|
31
32
|
*/
|
|
32
33
|
export const POP_BOOST = 4;
|
|
33
34
|
/**
|
|
34
|
-
* `log10(population + 1)` at which the population term saturates
|
|
35
|
-
*
|
|
35
|
+
* `log10(population + 1)` at which the population term saturates.
|
|
36
|
+
*
|
|
37
|
+
* A value of 6 means a population of one million warrants the whole {@link POP_BOOST},
|
|
38
|
+
* and larger populations warrant no more.
|
|
36
39
|
*/
|
|
37
40
|
export const POP_SCALE_LOG10 = 6;
|
|
38
41
|
/**
|
|
39
42
|
* Distance at which the nearness term halves.
|
|
40
43
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
44
|
+
* Sharper than the FTS reader's 100 km on purpose, because the candidate backend's
|
|
45
|
+
* score is log-population by itself with no bm25 document term.
|
|
46
|
+
* This weakens the population signal relative to the bias.
|
|
47
|
+
*
|
|
48
|
+
* At around 30 km the boost reaches only candidates the user is looking at,
|
|
49
|
+
* so an in-view namesake still wins and a distant one does not.
|
|
46
50
|
*/
|
|
47
51
|
export const PROX_SCALE_KM = 30;
|
|
48
52
|
/**
|
|
49
|
-
* Population plus nearness on one additive scale.
|
|
50
|
-
*
|
|
53
|
+
* Population plus nearness on one additive scale.
|
|
54
|
+
*
|
|
55
|
+
* Exported for tests and for a caller that wants the value without the sort.
|
|
56
|
+
* Ordinary callers want {@link applyProximityRerank}.
|
|
51
57
|
*/
|
|
52
58
|
export function combinedProminence(candidate, bias) {
|
|
53
59
|
const popBase = candidate.prominence ?? candidate.score;
|
|
54
60
|
const popTerm = POP_BOOST * Math.min(1, Math.max(0, popBase) / POP_SCALE_LOG10);
|
|
55
61
|
let proxTerm = 0;
|
|
56
|
-
// A candidate at the null island has no coordinate,
|
|
57
|
-
//
|
|
62
|
+
// A candidate at the null island has no coordinate, so it warrants no nearness term.
|
|
63
|
+
// A 0,0 pair interpreted as a real coordinate would receive an enormous score.
|
|
58
64
|
if (!(candidate.lat === 0 && candidate.lon === 0)) {
|
|
59
65
|
for (const b of bias) {
|
|
60
66
|
const d = haversineKm(b.lat, b.lon, candidate.lat, candidate.lon);
|
|
@@ -67,10 +73,13 @@ export function combinedProminence(candidate, bias) {
|
|
|
67
73
|
return popTerm + proxTerm;
|
|
68
74
|
}
|
|
69
75
|
/**
|
|
70
|
-
* Re-order `candidates` in place by {@link combinedProminence}, persisting each
|
|
71
|
-
* resolver walk's own `prominence ?? score`
|
|
72
|
-
*
|
|
73
|
-
*
|
|
76
|
+
* Re-order `candidates` in place by {@link combinedProminence}, persisting each
|
|
77
|
+
* combined value into `prominence` so the resolver walk's own `prominence ?? score`
|
|
78
|
+
* sort preserves the bias order rather than undoing it.
|
|
79
|
+
*
|
|
80
|
+
* Stable within equal prominence, preserving the population order the index already gave.
|
|
81
|
+
* A caller with no bias hints must not call this.
|
|
82
|
+
* The no-bias path is plain population order by construction.
|
|
74
83
|
*/
|
|
75
84
|
export function applyProximityRerank(candidates, bias) {
|
|
76
85
|
candidates
|
|
@@ -78,7 +87,7 @@ export function applyProximityRerank(candidates, bias) {
|
|
|
78
87
|
c.prominence = combinedProminence(c, bias);
|
|
79
88
|
return { c, i, p: c.prominence };
|
|
80
89
|
})
|
|
81
|
-
// oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array
|
|
90
|
+
// oxlint-disable-next-line unicorn/no-array-sort -- sorts a freshly-built array. toSorted would double-allocate on a hot path
|
|
82
91
|
.sort((a, b) => b.p - a.p || a.i - b.i)
|
|
83
92
|
.forEach((x, j) => (candidates[j] = x.c));
|
|
84
93
|
return candidates;
|