@mailwoman/corpus 8.0.0 → 8.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/out/src/adapter.d.ts +15 -5
- package/out/src/adapter.d.ts.map +1 -1
- package/out/src/adapter.js +11 -9
- package/out/src/adapter.js.map +1 -1
- package/out/src/adapters/ban/adapter.d.ts +7 -0
- package/out/src/adapters/ban/adapter.d.ts.map +1 -1
- package/out/src/adapters/ban/adapter.js +9 -2
- package/out/src/adapters/ban/adapter.js.map +1 -1
- package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/ban/street-decompose.js +5 -1
- package/out/src/adapters/ban/street-decompose.js.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts +14 -1
- package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
- package/out/src/adapters/fcc-bdc/adapter.js +15 -2
- package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
- package/out/src/adapters/geonames/adapter.d.ts +11 -0
- package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames/adapter.js +24 -5
- package/out/src/adapters/geonames/adapter.js.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.d.ts +11 -0
- package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
- package/out/src/adapters/geonames-postal/adapter.js +14 -1
- package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/adapter.d.ts +10 -1
- package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
- package/out/src/adapters/gnaf/adapter.js +11 -2
- package/out/src/adapters/gnaf/adapter.js.map +1 -1
- package/out/src/adapters/gnaf/assemble.d.ts +18 -6
- package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
- package/out/src/adapters/gnaf/assemble.js +16 -6
- package/out/src/adapters/gnaf/assemble.js.map +1 -1
- package/out/src/adapters/index.d.ts.map +1 -1
- package/out/src/adapters/index.js.map +1 -1
- package/out/src/adapters/openaddresses/adapter.d.ts +11 -0
- package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
- package/out/src/adapters/openaddresses/adapter.js +18 -3
- package/out/src/adapters/openaddresses/adapter.js.map +1 -1
- package/out/src/adapters/overture/adapter.d.ts +11 -0
- package/out/src/adapters/overture/adapter.d.ts.map +1 -1
- package/out/src/adapters/overture/adapter.js +12 -1
- package/out/src/adapters/overture/adapter.js.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.d.ts +11 -0
- package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-hi-schools/adapter.js +11 -0
- package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.d.ts +11 -0
- package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ia-contractors/adapter.js +11 -0
- package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.d.ts +11 -0
- package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-ny-notaries/adapter.js +11 -0
- package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.d.ts +11 -0
- package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
- package/out/src/adapters/state-tx-notaries/adapter.js +15 -2
- package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.d.ts +11 -0
- package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
- package/out/src/adapters/synth-po-box/adapter.js +13 -2
- package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
- package/out/src/adapters/tiger/adapter.d.ts +14 -1
- package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
- package/out/src/adapters/tiger/adapter.js +19 -4
- package/out/src/adapters/tiger/adapter.js.map +1 -1
- package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
- package/out/src/adapters/tiger/street-decompose.js.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +12 -1
- package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-imls-pls/adapter.js +11 -0
- package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-irs-bmf/adapter.js +17 -2
- package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nad/adapter.js +12 -1
- package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-nppes/adapter.js +11 -0
- package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +11 -0
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +15 -2
- package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.d.ts +7 -0
- package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-jp/adapter.js +18 -3
- package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.d.ts +13 -3
- package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-admin-json/adapter.js +15 -5
- package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts +7 -0
- package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
- package/out/src/adapters/wof-postalcode-json/adapter.js +9 -2
- package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
- package/out/src/align.d.ts +12 -4
- package/out/src/align.d.ts.map +1 -1
- package/out/src/align.js +9 -5
- package/out/src/align.js.map +1 -1
- package/out/src/build.d.ts +24 -8
- package/out/src/build.d.ts.map +1 -1
- package/out/src/build.js +3 -3
- package/out/src/build.js.map +1 -1
- package/out/src/codex/us-fips-state.d.ts +6 -2
- package/out/src/codex/us-fips-state.d.ts.map +1 -1
- package/out/src/codex/us-fips-state.js +3 -1
- package/out/src/codex/us-fips-state.js.map +1 -1
- package/out/src/golden.d.ts +21 -7
- package/out/src/golden.d.ts.map +1 -1
- package/out/src/golden.js +18 -10
- package/out/src/golden.js.map +1 -1
- package/out/src/license.d.ts +3 -1
- package/out/src/license.d.ts.map +1 -1
- package/out/src/license.js +4 -2
- package/out/src/license.js.map +1 -1
- package/out/src/parquet-wrapper/reader.d.ts +4 -2
- package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
- package/out/src/parquet-wrapper/reader.js +5 -4
- package/out/src/parquet-wrapper/reader.js.map +1 -1
- package/out/src/parquet-wrapper/schema.d.ts +14 -10
- package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
- package/out/src/parquet-wrapper/schema.js +6 -2
- package/out/src/parquet-wrapper/schema.js.map +1 -1
- package/out/src/parquet-wrapper/writer.d.ts +12 -4
- package/out/src/parquet-wrapper/writer.d.ts.map +1 -1
- package/out/src/parquet-wrapper/writer.js +12 -4
- package/out/src/parquet-wrapper/writer.js.map +1 -1
- package/out/src/parquet.d.ts +21 -7
- package/out/src/parquet.d.ts.map +1 -1
- package/out/src/parquet.js +15 -4
- package/out/src/parquet.js.map +1 -1
- package/out/src/runner.d.ts +39 -13
- package/out/src/runner.d.ts.map +1 -1
- package/out/src/runner.js +7 -3
- package/out/src/runner.js.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.d.ts +4 -0
- package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
- package/out/src/shard-recipes/anchor-absorption.js +14 -5
- package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
- package/out/src/shard-recipes/boundary-stress.d.ts +4 -0
- package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
- package/out/src/shard-recipes/boundary-stress.js +13 -7
- package/out/src/shard-recipes/boundary-stress.js.map +1 -1
- package/out/src/shard-recipes/country-balanced.d.ts +4 -0
- package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
- package/out/src/shard-recipes/country-balanced.js +39 -11
- package/out/src/shard-recipes/country-balanced.js.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts +4 -0
- package/out/src/shard-recipes/cz-pcfirst-preposition.d.ts.map +1 -1
- package/out/src/shard-recipes/cz-pcfirst-preposition.js +4 -0
- package/out/src/shard-recipes/cz-pcfirst-preposition.js.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.d.ts +4 -0
- package/out/src/shard-recipes/fr-admin-split.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-admin-split.js +14 -3
- package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.d.ts +4 -0
- package/out/src/shard-recipes/fr-bare-street.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-bare-street.js +4 -0
- package/out/src/shard-recipes/fr-bare-street.js.map +1 -1
- package/out/src/shard-recipes/fr-fragment.d.ts +4 -0
- package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-fragment.js +25 -8
- package/out/src/shard-recipes/fr-fragment.js.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.d.ts +4 -0
- package/out/src/shard-recipes/fr-lieudit.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-lieudit.js +21 -8
- package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
- package/out/src/shard-recipes/fr-order.d.ts +4 -0
- package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
- package/out/src/shard-recipes/fr-order.js +27 -8
- package/out/src/shard-recipes/fr-order.js.map +1 -1
- package/out/src/shard-recipes/german.d.ts +4 -0
- package/out/src/shard-recipes/german.d.ts.map +1 -1
- package/out/src/shard-recipes/german.js +16 -6
- package/out/src/shard-recipes/german.js.map +1 -1
- package/out/src/shard-recipes/house-venue.d.ts +4 -0
- package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
- package/out/src/shard-recipes/house-venue.js +4 -0
- package/out/src/shard-recipes/house-venue.js.map +1 -1
- package/out/src/shard-recipes/index.d.ts +9 -3
- package/out/src/shard-recipes/index.d.ts.map +1 -1
- package/out/src/shard-recipes/index.js +12 -4
- package/out/src/shard-recipes/index.js.map +1 -1
- package/out/src/shard-recipes/intersection.d.ts +4 -0
- package/out/src/shard-recipes/intersection.d.ts.map +1 -1
- package/out/src/shard-recipes/intersection.js +27 -13
- package/out/src/shard-recipes/intersection.js.map +1 -1
- package/out/src/shard-recipes/locale.d.ts +4 -0
- package/out/src/shard-recipes/locale.d.ts.map +1 -1
- package/out/src/shard-recipes/locale.js +9 -4
- package/out/src/shard-recipes/locale.js.map +1 -1
- package/out/src/shard-recipes/nl-postcode.d.ts +4 -0
- package/out/src/shard-recipes/nl-postcode.d.ts.map +1 -1
- package/out/src/shard-recipes/nl-postcode.js +8 -2
- package/out/src/shard-recipes/nl-postcode.js.map +1 -1
- package/out/src/shard-recipes/no-fragment.d.ts +4 -0
- package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
- package/out/src/shard-recipes/no-fragment.js +8 -2
- package/out/src/shard-recipes/no-fragment.js.map +1 -1
- package/out/src/shard-recipes/no-street-led.d.ts +4 -0
- package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street-led.js +5 -1
- package/out/src/shard-recipes/no-street-led.js.map +1 -1
- package/out/src/shard-recipes/no-street.d.ts +4 -0
- package/out/src/shard-recipes/no-street.d.ts.map +1 -1
- package/out/src/shard-recipes/no-street.js +4 -0
- package/out/src/shard-recipes/no-street.js.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.d.ts +4 -0
- package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box-cedex.js +99 -43
- package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
- package/out/src/shard-recipes/po-box.d.ts +4 -0
- package/out/src/shard-recipes/po-box.d.ts.map +1 -1
- package/out/src/shard-recipes/po-box.js +4 -0
- package/out/src/shard-recipes/po-box.js.map +1 -1
- package/out/src/shard-recipes/scaffold.d.ts +48 -16
- package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
- package/out/src/shard-recipes/scaffold.js +10 -6
- package/out/src/shard-recipes/scaffold.js.map +1 -1
- package/out/src/shard-recipes/si-bare-village.d.ts +4 -0
- package/out/src/shard-recipes/si-bare-village.d.ts.map +1 -1
- package/out/src/shard-recipes/si-bare-village.js +4 -0
- package/out/src/shard-recipes/si-bare-village.js.map +1 -1
- package/out/src/shard-recipes/street-affix.d.ts +4 -0
- package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
- package/out/src/shard-recipes/street-affix.js +29 -10
- package/out/src/shard-recipes/street-affix.js.map +1 -1
- package/out/src/shard-recipes/street-bare.d.ts +4 -0
- package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
- package/out/src/shard-recipes/street-bare.js +4 -0
- package/out/src/shard-recipes/street-bare.js.map +1 -1
- package/out/src/shard-recipes/street.d.ts +4 -0
- package/out/src/shard-recipes/street.d.ts.map +1 -1
- package/out/src/shard-recipes/street.js +4 -0
- package/out/src/shard-recipes/street.js.map +1 -1
- package/out/src/shard-recipes/unit.d.ts +4 -0
- package/out/src/shard-recipes/unit.d.ts.map +1 -1
- package/out/src/shard-recipes/unit.js +45 -14
- package/out/src/shard-recipes/unit.js.map +1 -1
- package/out/src/split.d.ts +18 -6
- package/out/src/split.d.ts.map +1 -1
- package/out/src/split.js +4 -2
- package/out/src/split.js.map +1 -1
- package/out/src/synthesize-anchor-absorption.d.ts +7 -1
- package/out/src/synthesize-anchor-absorption.d.ts.map +1 -1
- package/out/src/synthesize-anchor-absorption.js +28 -14
- package/out/src/synthesize-anchor-absorption.js.map +1 -1
- package/out/src/synthesize-boundary-stress.d.ts +3 -1
- package/out/src/synthesize-boundary-stress.d.ts.map +1 -1
- package/out/src/synthesize-boundary-stress.js +35 -28
- package/out/src/synthesize-boundary-stress.js.map +1 -1
- package/out/src/synthesize-german.d.ts +15 -5
- package/out/src/synthesize-german.d.ts.map +1 -1
- package/out/src/synthesize-german.js +9 -3
- package/out/src/synthesize-german.js.map +1 -1
- package/out/src/synthesize-house-venue.d.ts.map +1 -1
- package/out/src/synthesize-house-venue.js +15 -15
- package/out/src/synthesize-house-venue.js.map +1 -1
- package/out/src/synthesize-intersection.d.ts +9 -3
- package/out/src/synthesize-intersection.d.ts.map +1 -1
- package/out/src/synthesize-intersection.js +25 -6
- package/out/src/synthesize-intersection.js.map +1 -1
- package/out/src/synthesize-no-street.d.ts +3 -1
- package/out/src/synthesize-no-street.d.ts.map +1 -1
- package/out/src/synthesize-no-street.js +5 -6
- package/out/src/synthesize-no-street.js.map +1 -1
- package/out/src/synthesize-po-box.d.ts +15 -5
- package/out/src/synthesize-po-box.d.ts.map +1 -1
- package/out/src/synthesize-po-box.js +21 -7
- package/out/src/synthesize-po-box.js.map +1 -1
- package/out/src/synthesize-street.d.ts +3 -1
- package/out/src/synthesize-street.d.ts.map +1 -1
- package/out/src/synthesize-street.js +6 -1
- package/out/src/synthesize-street.js.map +1 -1
- package/out/src/synthesize.d.ts +39 -13
- package/out/src/synthesize.d.ts.map +1 -1
- package/out/src/synthesize.js +66 -36
- package/out/src/synthesize.js.map +1 -1
- package/out/src/tokenize.d.ts +15 -5
- package/out/src/tokenize.d.ts.map +1 -1
- package/out/src/tokenize.js.map +1 -1
- package/out/src/tools/align-shard.d.ts.map +1 -1
- package/out/src/tools/align-shard.js +3 -1
- package/out/src/tools/align-shard.js.map +1 -1
- package/out/src/tools/audit.d.ts.map +1 -1
- package/out/src/tools/audit.js +20 -8
- package/out/src/tools/audit.js.map +1 -1
- package/out/src/tools/corpus-stats.d.ts.map +1 -1
- package/out/src/tools/corpus-stats.js.map +1 -1
- package/out/src/tools/fetch/ban.d.ts.map +1 -1
- package/out/src/tools/fetch/ban.js +17 -10
- package/out/src/tools/fetch/ban.js.map +1 -1
- package/out/src/tools/fetch/download.d.ts +30 -10
- package/out/src/tools/fetch/download.d.ts.map +1 -1
- package/out/src/tools/fetch/download.js +26 -6
- package/out/src/tools/fetch/download.js.map +1 -1
- package/out/src/tools/fetch/hrsa.d.ts.map +1 -1
- package/out/src/tools/fetch/hrsa.js.map +1 -1
- package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
- package/out/src/tools/fetch/imls-pls.js +18 -18
- package/out/src/tools/fetch/imls-pls.js.map +1 -1
- package/out/src/tools/fetch/index.d.ts +3 -1
- package/out/src/tools/fetch/index.d.ts.map +1 -1
- package/out/src/tools/fetch/index.js +3 -1
- package/out/src/tools/fetch/index.js.map +1 -1
- package/out/src/tools/fetch/nad.d.ts +21 -7
- package/out/src/tools/fetch/nad.d.ts.map +1 -1
- package/out/src/tools/fetch/nad.js +5 -5
- package/out/src/tools/fetch/nad.js.map +1 -1
- package/out/src/tools/fetch/nppes.d.ts.map +1 -1
- package/out/src/tools/fetch/nppes.js +9 -15
- package/out/src/tools/fetch/nppes.js.map +1 -1
- package/out/src/tools/fetch/openaddresses.d.ts +3 -1
- package/out/src/tools/fetch/openaddresses.d.ts.map +1 -1
- package/out/src/tools/fetch/openaddresses.js +32 -23
- package/out/src/tools/fetch/openaddresses.js.map +1 -1
- package/out/src/tools/fetch/ppd.d.ts +3 -1
- package/out/src/tools/fetch/ppd.d.ts.map +1 -1
- package/out/src/tools/fetch/ppd.js +14 -3
- package/out/src/tools/fetch/ppd.js.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.d.ts.map +1 -1
- package/out/src/tools/fetch/state-hi-schools.js +13 -6
- package/out/src/tools/fetch/state-hi-schools.js.map +1 -1
- package/out/src/tools/fetch/state-sources.d.ts.map +1 -1
- package/out/src/tools/fetch/state-sources.js +8 -3
- package/out/src/tools/fetch/state-sources.js.map +1 -1
- package/out/src/tools/fetch/tiger-full.d.ts +9 -3
- package/out/src/tools/fetch/tiger-full.d.ts.map +1 -1
- package/out/src/tools/fetch/tiger-full.js +35 -20
- package/out/src/tools/fetch/tiger-full.js.map +1 -1
- package/out/src/tools/gb-title-case.d.ts.map +1 -1
- package/out/src/tools/gb-title-case.js.map +1 -1
- package/out/src/tools/golden-expand.d.ts +24 -8
- package/out/src/tools/golden-expand.d.ts.map +1 -1
- package/out/src/tools/golden-expand.js +20 -12
- package/out/src/tools/golden-expand.js.map +1 -1
- package/out/src/tools/golden-promote.d.ts +18 -6
- package/out/src/tools/golden-promote.d.ts.map +1 -1
- package/out/src/tools/golden-promote.js +22 -7
- package/out/src/tools/golden-promote.js.map +1 -1
- package/out/src/tools/ingest-csv.d.ts +3 -1
- package/out/src/tools/ingest-csv.d.ts.map +1 -1
- package/out/src/tools/ingest-csv.js +17 -19
- package/out/src/tools/ingest-csv.js.map +1 -1
- package/out/src/tools/jsonl-to-parquet.d.ts +18 -6
- package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
- package/out/src/tools/jsonl-to-parquet.js +11 -5
- package/out/src/tools/jsonl-to-parquet.js.map +1 -1
- package/out/src/tools/lint-shard-vocab.d.ts +36 -12
- package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
- package/out/src/tools/lint-shard-vocab.js +25 -11
- package/out/src/tools/lint-shard-vocab.js.map +1 -1
- package/out/src/tools/lint-shard.d.ts +30 -10
- package/out/src/tools/lint-shard.d.ts.map +1 -1
- package/out/src/tools/lint-shard.js +33 -20
- package/out/src/tools/lint-shard.js.map +1 -1
- package/out/src/tools/overlay-manifest.d.ts.map +1 -1
- package/out/src/tools/overlay-manifest.js +6 -4
- package/out/src/tools/overlay-manifest.js.map +1 -1
- package/out/src/tools/shard-kryptonite.d.ts +6 -2
- package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
- package/out/src/tools/shard-kryptonite.js +1 -1
- package/out/src/tools/shard-kryptonite.js.map +1 -1
- package/out/src/tools/shard-translit.d.ts +9 -3
- package/out/src/tools/shard-translit.d.ts.map +1 -1
- package/out/src/tools/shard-translit.js +2 -2
- package/out/src/tools/shard-translit.js.map +1 -1
- package/out/src/types.d.ts +51 -17
- package/out/src/types.d.ts.map +1 -1
- package/out/src/wof-json.d.ts +9 -3
- package/out/src/wof-json.d.ts.map +1 -1
- package/out/src/wof-json.js +6 -4
- package/out/src/wof-json.js.map +1 -1
- package/package.json +7 -6
- package/src/adapter.ts +24 -13
- package/src/adapters/ban/adapter.ts +12 -2
- package/src/adapters/ban/street-decompose.ts +7 -1
- package/src/adapters/fcc-bdc/adapter.ts +19 -3
- package/src/adapters/geonames/adapter.ts +28 -5
- package/src/adapters/geonames-postal/adapter.ts +17 -1
- package/src/adapters/gnaf/adapter.ts +15 -2
- package/src/adapters/gnaf/assemble.ts +40 -10
- package/src/adapters/index.ts +13 -0
- package/src/adapters/openaddresses/adapter.ts +22 -3
- package/src/adapters/overture/adapter.ts +18 -2
- package/src/adapters/state-hi-schools/adapter.ts +15 -0
- package/src/adapters/state-ia-contractors/adapter.ts +15 -0
- package/src/adapters/state-ny-notaries/adapter.ts +15 -0
- package/src/adapters/state-tx-notaries/adapter.ts +18 -2
- package/src/adapters/synth-po-box/adapter.ts +19 -2
- package/src/adapters/tiger/adapter.ts +23 -4
- package/src/adapters/tiger/street-decompose.ts +1 -0
- package/src/adapters/usgov-hrsa-fqhc/adapter.ts +18 -2
- package/src/adapters/usgov-imls-pls/adapter.ts +15 -0
- package/src/adapters/usgov-irs-bmf/adapter.ts +19 -2
- package/src/adapters/usgov-nad/adapter.ts +14 -1
- package/src/adapters/usgov-nppes/adapter.ts +13 -0
- package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +21 -3
- package/src/adapters/wof-admin-jp/adapter.ts +20 -3
- package/src/adapters/wof-admin-json/adapter.ts +22 -7
- package/src/adapters/wof-postalcode-json/adapter.ts +10 -2
- package/src/align.ts +21 -8
- package/src/build.ts +48 -11
- package/src/codex/us-fips-state.ts +6 -2
- package/src/golden.ts +28 -13
- package/src/license.ts +4 -2
- package/src/parquet-wrapper/reader.ts +6 -4
- package/src/parquet-wrapper/schema.ts +14 -10
- package/src/parquet-wrapper/writer.ts +12 -4
- package/src/parquet.ts +39 -8
- package/src/runner.ts +49 -15
- package/src/shard-recipes/anchor-absorption.ts +21 -5
- package/src/shard-recipes/boundary-stress.ts +20 -7
- package/src/shard-recipes/country-balanced.ts +78 -13
- package/src/shard-recipes/cz-pcfirst-preposition.ts +9 -0
- package/src/shard-recipes/fr-admin-split.ts +30 -5
- package/src/shard-recipes/fr-bare-street.ts +10 -0
- package/src/shard-recipes/fr-fragment.ts +33 -8
- package/src/shard-recipes/fr-lieudit.ts +35 -9
- package/src/shard-recipes/fr-order.ts +47 -9
- package/src/shard-recipes/german.ts +32 -6
- package/src/shard-recipes/house-venue.ts +7 -0
- package/src/shard-recipes/index.ts +12 -4
- package/src/shard-recipes/intersection.ts +63 -14
- package/src/shard-recipes/locale.ts +37 -4
- package/src/shard-recipes/nl-postcode.ts +12 -2
- package/src/shard-recipes/no-fragment.ts +12 -2
- package/src/shard-recipes/no-street-led.ts +11 -1
- package/src/shard-recipes/no-street.ts +7 -0
- package/src/shard-recipes/po-box-cedex.ts +145 -45
- package/src/shard-recipes/po-box.ts +7 -0
- package/src/shard-recipes/scaffold.ts +52 -20
- package/src/shard-recipes/si-bare-village.ts +9 -0
- package/src/shard-recipes/street-affix.ts +88 -13
- package/src/shard-recipes/street-bare.ts +10 -0
- package/src/shard-recipes/street.ts +7 -0
- package/src/shard-recipes/unit.ts +79 -16
- package/src/split.ts +28 -7
- package/src/synthesize-anchor-absorption.ts +41 -14
- package/src/synthesize-boundary-stress.ts +57 -30
- package/src/synthesize-german.ts +30 -7
- package/src/synthesize-house-venue.ts +22 -16
- package/src/synthesize-intersection.ts +34 -7
- package/src/synthesize-no-street.ts +18 -10
- package/src/synthesize-po-box.ts +42 -10
- package/src/synthesize-street.ts +10 -2
- package/src/synthesize.ts +81 -38
- package/src/tokenize.ts +15 -5
- package/src/tools/align-shard.ts +6 -1
- package/src/tools/audit.ts +57 -11
- package/src/tools/corpus-stats.ts +9 -0
- package/src/tools/fetch/ban.ts +32 -10
- package/src/tools/fetch/download.ts +49 -12
- package/src/tools/fetch/hrsa.ts +3 -0
- package/src/tools/fetch/imls-pls.ts +28 -18
- package/src/tools/fetch/index.ts +3 -1
- package/src/tools/fetch/nad.ts +39 -12
- package/src/tools/fetch/nppes.ts +17 -15
- package/src/tools/fetch/openaddresses.ts +52 -24
- package/src/tools/fetch/ppd.ts +22 -3
- package/src/tools/fetch/state-hi-schools.ts +17 -6
- package/src/tools/fetch/state-sources.ts +16 -3
- package/src/tools/fetch/tiger-full.ts +66 -23
- package/src/tools/gb-title-case.ts +1 -0
- package/src/tools/golden-expand.ts +64 -20
- package/src/tools/golden-promote.ts +53 -13
- package/src/tools/ingest-csv.ts +41 -26
- package/src/tools/jsonl-to-parquet.ts +30 -10
- package/src/tools/lint-shard-vocab.ts +75 -24
- package/src/tools/lint-shard.ts +75 -31
- package/src/tools/overlay-manifest.ts +7 -4
- package/src/tools/shard-kryptonite.ts +11 -3
- package/src/tools/shard-translit.ts +20 -5
- package/src/types.ts +51 -17
- package/src/wof-json.ts +18 -7
|
@@ -38,6 +38,21 @@ import { readJSONL, sha256File, writeJSONL } from "@mailwoman/core/utils"
|
|
|
38
38
|
|
|
39
39
|
// ── Types ──────────────────────────────────────────────────────────────────
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Components a candidate needs before it is rich enough to be worth a golden-set slot.
|
|
43
|
+
*/
|
|
44
|
+
const MIN_GOLDEN_COMPONENTS = 5
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Components an existing entry must still carry to survive promotion.
|
|
48
|
+
*/
|
|
49
|
+
const MIN_PROMOTABLE_COMPONENTS = 4
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Quote-delimited segments above which the raw line is malformed rather than merely quoted.
|
|
53
|
+
*/
|
|
54
|
+
const MAX_QUOTE_SEGMENTS = 3
|
|
55
|
+
|
|
41
56
|
interface GoldenEntry {
|
|
42
57
|
raw: string
|
|
43
58
|
components: Record<string, string>
|
|
@@ -58,24 +73,36 @@ export interface PromoteStats {
|
|
|
58
73
|
}
|
|
59
74
|
|
|
60
75
|
export interface PromoteGoldenOptions {
|
|
61
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Candidates JSONL (required).
|
|
78
|
+
*/
|
|
62
79
|
input: string
|
|
63
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* Target golden version dir (required, e.g. `v0.1.1`).
|
|
82
|
+
*/
|
|
64
83
|
bumpTo: string
|
|
65
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Previous version to forward-copy + dedup against. Default `v0.1.0`.
|
|
86
|
+
*/
|
|
66
87
|
prior?: string
|
|
67
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Golden dir root. Default `data/eval/golden`.
|
|
90
|
+
*/
|
|
68
91
|
goldenRoot?: string
|
|
69
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Skip the human-typed-likelihood filters (keep everything that passed expand-golden's validator).
|
|
94
|
+
*/
|
|
70
95
|
noFilters?: boolean
|
|
71
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Report what would be written but don't touch disk.
|
|
98
|
+
*/
|
|
72
99
|
dryRun?: boolean
|
|
73
100
|
}
|
|
74
101
|
|
|
75
102
|
// ── Filters ───────────────────────────────────────────────────────────────
|
|
76
103
|
|
|
77
104
|
function normalize(s: string): string {
|
|
78
|
-
return s.toLowerCase().
|
|
105
|
+
return s.toLowerCase().replaceAll(/\s+/g, " ").trim()
|
|
79
106
|
}
|
|
80
107
|
|
|
81
108
|
/**
|
|
@@ -85,7 +112,7 @@ function normalize(s: string): string {
|
|
|
85
112
|
function isComponentsGlued(entry: GoldenEntry): boolean {
|
|
86
113
|
const componentCount = Object.keys(entry.components).length
|
|
87
114
|
|
|
88
|
-
if (componentCount <
|
|
115
|
+
if (componentCount < MIN_GOLDEN_COMPONENTS) return false
|
|
89
116
|
const separators = (entry.raw.match(/[,\n;]/g) ?? []).length
|
|
90
117
|
|
|
91
118
|
return separators < 2
|
|
@@ -97,7 +124,7 @@ function isComponentsGlued(entry: GoldenEntry): boolean {
|
|
|
97
124
|
* often precedes locality there).
|
|
98
125
|
*/
|
|
99
126
|
function isPostcodeBadlyLeading(entry: GoldenEntry): boolean {
|
|
100
|
-
if (Object.keys(entry.components).length <
|
|
127
|
+
if (Object.keys(entry.components).length < MIN_PROMOTABLE_COMPONENTS) return false
|
|
101
128
|
|
|
102
129
|
if (entry.country === "FR" || entry.country === "France") return false
|
|
103
130
|
const postcode = entry.components.postcode
|
|
@@ -118,13 +145,13 @@ function isSuspicious(entry: GoldenEntry): boolean {
|
|
|
118
145
|
const raw = entry.raw
|
|
119
146
|
|
|
120
147
|
// eslint-disable-next-line no-control-regex
|
|
121
|
-
if (/[\
|
|
148
|
+
if (/[\u0000-\u001F\u007F]/.test(raw)) return true
|
|
122
149
|
const openBrackets = (raw.match(/[[({<]/g) ?? []).length
|
|
123
150
|
const closeBrackets = (raw.match(/[\])}>]/g) ?? []).length
|
|
124
151
|
|
|
125
152
|
if (openBrackets !== closeBrackets) return true
|
|
126
153
|
|
|
127
|
-
if (raw.split('"').length >
|
|
154
|
+
if (raw.split('"').length > MAX_QUOTE_SEGMENTS) return true
|
|
128
155
|
|
|
129
156
|
// too many quote marks
|
|
130
157
|
return false
|
|
@@ -132,7 +159,9 @@ function isSuspicious(entry: GoldenEntry): boolean {
|
|
|
132
159
|
|
|
133
160
|
// ── IO ─────────────────────────────────────────────────────────────────────
|
|
134
161
|
|
|
135
|
-
/**
|
|
162
|
+
/**
|
|
163
|
+
* Read a JSONL, tolerating a missing file (returns `[]`) — prior golden dirs may lack a bucket.
|
|
164
|
+
*/
|
|
136
165
|
function readJSONLIfPresent<T>(path: string): T[] {
|
|
137
166
|
if (!existsSync(path)) return []
|
|
138
167
|
|
|
@@ -169,6 +198,7 @@ export async function promoteGolden(
|
|
|
169
198
|
for (const e of entries) {
|
|
170
199
|
seenNormalized.add(normalize(e.raw))
|
|
171
200
|
}
|
|
201
|
+
|
|
172
202
|
report?.(` prior ${country}: ${entries.length} entries (forward-copy base)`)
|
|
173
203
|
}
|
|
174
204
|
} else {
|
|
@@ -182,6 +212,7 @@ export async function promoteGolden(
|
|
|
182
212
|
kept: 0,
|
|
183
213
|
perCountry: {},
|
|
184
214
|
}
|
|
215
|
+
|
|
185
216
|
const accepted: GoldenEntry[] = []
|
|
186
217
|
const seenInBatch = new Set<string>()
|
|
187
218
|
|
|
@@ -191,34 +222,40 @@ export async function promoteGolden(
|
|
|
191
222
|
// Dedup pass 1: against prior versioned golden
|
|
192
223
|
if (seenNormalized.has(norm)) {
|
|
193
224
|
stats.filteredOut.forwardDup++
|
|
225
|
+
|
|
194
226
|
continue
|
|
195
227
|
}
|
|
196
228
|
|
|
197
229
|
// Dedup pass 2: against this batch
|
|
198
230
|
if (seenInBatch.has(norm)) {
|
|
199
231
|
stats.filteredOut.duplicate++
|
|
232
|
+
|
|
200
233
|
continue
|
|
201
234
|
}
|
|
202
235
|
|
|
203
236
|
if (applyFilters) {
|
|
204
237
|
if (isComponentsGlued(cand)) {
|
|
205
238
|
stats.filteredOut.glued++
|
|
239
|
+
|
|
206
240
|
continue
|
|
207
241
|
}
|
|
208
242
|
|
|
209
243
|
if (isPostcodeBadlyLeading(cand)) {
|
|
210
244
|
stats.filteredOut.postcodeLeading++
|
|
245
|
+
|
|
211
246
|
continue
|
|
212
247
|
}
|
|
213
248
|
|
|
214
249
|
if (isSuspicious(cand)) {
|
|
215
250
|
stats.filteredOut.suspicious++
|
|
251
|
+
|
|
216
252
|
continue
|
|
217
253
|
}
|
|
218
254
|
}
|
|
219
255
|
|
|
220
256
|
accepted.push(cand)
|
|
221
257
|
seenInBatch.add(norm)
|
|
258
|
+
|
|
222
259
|
stats.kept++
|
|
223
260
|
const country = cand.country || "OTHER"
|
|
224
261
|
stats.perCountry[country] = (stats.perCountry[country] ?? 0) + 1
|
|
@@ -238,6 +275,7 @@ export async function promoteGolden(
|
|
|
238
275
|
if (!buckets.has(key)) {
|
|
239
276
|
buckets.set(key, [])
|
|
240
277
|
}
|
|
278
|
+
|
|
241
279
|
buckets.get(key)!.push(cand)
|
|
242
280
|
}
|
|
243
281
|
|
|
@@ -249,6 +287,7 @@ export async function promoteGolden(
|
|
|
249
287
|
for (const [key, entries] of buckets) {
|
|
250
288
|
report?.(` ${key.toLowerCase()}.jsonl: ${entries.length} entries`)
|
|
251
289
|
}
|
|
290
|
+
|
|
252
291
|
report?.(`=== filter stats ===`)
|
|
253
292
|
report?.(`candidates in: ${stats.candidatesIn}`)
|
|
254
293
|
report?.(` filtered (glued): ${stats.filteredOut.glued}`)
|
|
@@ -259,7 +298,7 @@ export async function promoteGolden(
|
|
|
259
298
|
report?.(` kept: ${stats.kept}`)
|
|
260
299
|
report?.(`per-country (kept):`)
|
|
261
300
|
|
|
262
|
-
for (const [c, n] of Object.entries(stats.perCountry).
|
|
301
|
+
for (const [c, n] of Object.entries(stats.perCountry).toSorted((a, b) => b[1] - a[1])) {
|
|
263
302
|
report?.(` ${c}: ${n}`)
|
|
264
303
|
}
|
|
265
304
|
|
|
@@ -270,6 +309,7 @@ export async function promoteGolden(
|
|
|
270
309
|
}
|
|
271
310
|
|
|
272
311
|
mkdirSync(outDir, { recursive: true })
|
|
312
|
+
|
|
273
313
|
const manifest: {
|
|
274
314
|
promoted_at: string
|
|
275
315
|
from: string
|
package/src/tools/ingest-csv.ts
CHANGED
|
@@ -31,9 +31,7 @@ import type { SQLInputValue } from "node:sqlite"
|
|
|
31
31
|
|
|
32
32
|
import { TextSpliterator } from "spliterator"
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
// Core: quote-aware CSV field splitting
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
34
|
+
//#region Core: quote-aware CSV field splitting
|
|
37
35
|
|
|
38
36
|
const COMMA = 44
|
|
39
37
|
const DOUBLE_QUOTE = 34
|
|
@@ -59,6 +57,7 @@ function splitCSVLine(line: string, separator: number = COMMA): string[] {
|
|
|
59
57
|
start = i + 1
|
|
60
58
|
}
|
|
61
59
|
}
|
|
60
|
+
|
|
62
61
|
fields.push(line.slice(start))
|
|
63
62
|
|
|
64
63
|
return fields
|
|
@@ -68,24 +67,24 @@ function stripQuotes(field: string): string {
|
|
|
68
67
|
const trimmed = field.trim()
|
|
69
68
|
|
|
70
69
|
if (trimmed.length >= 2 && trimmed.startsWith('"') && trimmed.endsWith('"')) {
|
|
71
|
-
return trimmed.slice(1, -1).
|
|
70
|
+
return trimmed.slice(1, -1).replaceAll('""', '"')
|
|
72
71
|
}
|
|
73
72
|
|
|
74
73
|
return trimmed
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
//#endregion
|
|
77
|
+
|
|
78
|
+
//#region Column name normalization
|
|
80
79
|
|
|
81
80
|
function normalizeColumnName(raw: string): string {
|
|
82
81
|
return (
|
|
83
82
|
raw
|
|
84
83
|
.trim()
|
|
85
|
-
.
|
|
84
|
+
.replaceAll(/^"+|"+$/g, "")
|
|
86
85
|
.toLowerCase()
|
|
87
|
-
.
|
|
88
|
-
.
|
|
86
|
+
.replaceAll(/[^a-z0-9]+/g, "_")
|
|
87
|
+
.replaceAll(/^_|_$/g, "") || "unnamed"
|
|
89
88
|
)
|
|
90
89
|
}
|
|
91
90
|
|
|
@@ -100,9 +99,9 @@ function dedupColumns(names: string[]): string[] {
|
|
|
100
99
|
})
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
//#endregion
|
|
103
|
+
|
|
104
|
+
//#region Type inference
|
|
106
105
|
|
|
107
106
|
type SQLiteColType = "INTEGER" | "REAL" | "TEXT"
|
|
108
107
|
|
|
@@ -116,7 +115,7 @@ function normalizeField(raw: string): string | null {
|
|
|
116
115
|
let s = raw.trim()
|
|
117
116
|
|
|
118
117
|
if (s.length >= 2 && s.startsWith('"') && s.endsWith('"')) {
|
|
119
|
-
s = s.slice(1, -1).
|
|
118
|
+
s = s.slice(1, -1).replaceAll('""', '"')
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
// Normalize common null-like values
|
|
@@ -136,6 +135,7 @@ function inferColumnType(samples: (string | null)[]): ColumnInfo {
|
|
|
136
135
|
for (const s of samples) {
|
|
137
136
|
if (s === null) {
|
|
138
137
|
nullCount++
|
|
138
|
+
|
|
139
139
|
continue
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -154,9 +154,9 @@ function inferColumnType(samples: (string | null)[]): ColumnInfo {
|
|
|
154
154
|
return { name: "", type, nullable: nullCount / total >= 0.5 }
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
//#endregion
|
|
158
|
+
|
|
159
|
+
//#region Main: read CSV, infer schema, produce SQL
|
|
160
160
|
|
|
161
161
|
interface IngestOptions {
|
|
162
162
|
inputPath: string
|
|
@@ -192,6 +192,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
192
192
|
|
|
193
193
|
if (!headerLine && opts.hasHeader) {
|
|
194
194
|
headerLine = line
|
|
195
|
+
|
|
195
196
|
continue
|
|
196
197
|
}
|
|
197
198
|
|
|
@@ -226,6 +227,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
226
227
|
|
|
227
228
|
return normalizeField(raw)
|
|
228
229
|
})
|
|
230
|
+
|
|
229
231
|
const info = inferColumnType(samples)
|
|
230
232
|
info.name = name
|
|
231
233
|
|
|
@@ -263,6 +265,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
263
265
|
// Use the .import approach via a temp table, then INSERT INTO ... SELECT to handle
|
|
264
266
|
// NULL normalization and type coercion.
|
|
265
267
|
const csvBasename = basename(opts.inputPath)
|
|
268
|
+
|
|
266
269
|
const importSQL = [
|
|
267
270
|
`CREATE TEMP TABLE "${opts.tableName}_source" (${colDefs});`,
|
|
268
271
|
`.mode csv`,
|
|
@@ -291,15 +294,16 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
291
294
|
for (const row of batch) {
|
|
292
295
|
insertStmt.run(...row)
|
|
293
296
|
}
|
|
297
|
+
|
|
294
298
|
db.exec("COMMIT")
|
|
295
|
-
} catch (
|
|
299
|
+
} catch (error) {
|
|
296
300
|
db.exec("ROLLBACK")
|
|
297
|
-
throw
|
|
301
|
+
throw error
|
|
298
302
|
}
|
|
299
303
|
}
|
|
300
304
|
|
|
301
305
|
const batch: SQLInputValue[][] = []
|
|
302
|
-
const BATCH_SIZE =
|
|
306
|
+
const BATCH_SIZE = 10_000
|
|
303
307
|
|
|
304
308
|
for await (const line of TextSpliterator.fromAsync(opts.inputPath)) {
|
|
305
309
|
lineNum++
|
|
@@ -308,19 +312,21 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
308
312
|
|
|
309
313
|
if (opts.hasHeader && !headerSkipped) {
|
|
310
314
|
headerSkipped = true
|
|
315
|
+
|
|
311
316
|
continue
|
|
312
317
|
}
|
|
313
318
|
|
|
314
319
|
const fields = splitCSVLine(line, sep).map(stripQuotes)
|
|
320
|
+
|
|
315
321
|
const values = fields.map((f, i) => {
|
|
316
322
|
const v = normalizeField(f)
|
|
317
323
|
|
|
318
324
|
if (v === null) return null
|
|
319
325
|
const col = columns[i]
|
|
320
326
|
|
|
321
|
-
if (col?.type === "INTEGER" && /^-?\d+$/.test(v)) return parseInt(v, 10)
|
|
327
|
+
if (col?.type === "INTEGER" && /^-?\d+$/.test(v)) return Number.parseInt(v, 10)
|
|
322
328
|
|
|
323
|
-
if (col?.type === "REAL" && /^-?\d+\.?\d+$/.test(v)) return parseFloat(v)
|
|
329
|
+
if (col?.type === "REAL" && /^-?\d+\.?\d+$/.test(v)) return Number.parseFloat(v)
|
|
324
330
|
|
|
325
331
|
return v
|
|
326
332
|
})
|
|
@@ -329,6 +335,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
329
335
|
while (values.length < columns.length) {
|
|
330
336
|
values.push(null)
|
|
331
337
|
}
|
|
338
|
+
|
|
332
339
|
values.length = columns.length
|
|
333
340
|
|
|
334
341
|
batch.push(values)
|
|
@@ -338,14 +345,14 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
338
345
|
imported += batch.length
|
|
339
346
|
batch.length = 0
|
|
340
347
|
|
|
341
|
-
if (imported %
|
|
348
|
+
if (imported % 100_000 === 0) {
|
|
342
349
|
process.stderr.write(` ${(imported / 1_000_000).toFixed(1)}M rows...\n`)
|
|
343
350
|
}
|
|
344
351
|
}
|
|
345
352
|
}
|
|
346
353
|
|
|
347
354
|
// Flush remaining
|
|
348
|
-
if (batch.length
|
|
355
|
+
if (batch.length) {
|
|
349
356
|
doInsert()
|
|
350
357
|
imported += batch.length
|
|
351
358
|
}
|
|
@@ -357,6 +364,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
357
364
|
|
|
358
365
|
if (firstTextCol) {
|
|
359
366
|
process.stderr.write(`Building index on "${firstTextCol.name}"...\n`)
|
|
367
|
+
|
|
360
368
|
db.exec(
|
|
361
369
|
`CREATE INDEX IF NOT EXISTS idx_${opts.tableName}_${firstTextCol.name} ON "${opts.tableName}"("${firstTextCol.name}");`
|
|
362
370
|
)
|
|
@@ -367,6 +375,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
367
375
|
// Write MANIFEST
|
|
368
376
|
const fileSize = (await import("node:fs/promises")).stat
|
|
369
377
|
const stat = await (await import("node:fs/promises")).stat(opts.outputPath)
|
|
378
|
+
|
|
370
379
|
const manifest = {
|
|
371
380
|
ingested_at: new Date().toISOString(),
|
|
372
381
|
source_csv: basename(opts.inputPath),
|
|
@@ -375,6 +384,7 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
375
384
|
row_count: imported,
|
|
376
385
|
db_bytes: stat.size,
|
|
377
386
|
}
|
|
387
|
+
|
|
378
388
|
const manifestPath = opts.outputPath.replace(/\.db$/, ".manifest.json")
|
|
379
389
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n")
|
|
380
390
|
|
|
@@ -383,7 +393,9 @@ async function runIngest(opts: IngestOptions): Promise<void> {
|
|
|
383
393
|
)
|
|
384
394
|
}
|
|
385
395
|
|
|
386
|
-
/**
|
|
396
|
+
/**
|
|
397
|
+
* Flag-shaped options for {@linkcode ingestCSV} — `table`/`output` derive from `input` when omitted.
|
|
398
|
+
*/
|
|
387
399
|
export interface IngestCSVOptions {
|
|
388
400
|
input: string
|
|
389
401
|
table?: string
|
|
@@ -405,11 +417,12 @@ export async function ingestCSV(options: IngestCSVOptions): Promise<void> {
|
|
|
405
417
|
if (!existsSync(options.input)) {
|
|
406
418
|
throw new Error(`File not found: ${options.input}`)
|
|
407
419
|
}
|
|
420
|
+
|
|
408
421
|
const csvName = basename(options.input, extname(options.input))
|
|
409
422
|
|
|
410
423
|
await runIngest({
|
|
411
424
|
inputPath: options.input,
|
|
412
|
-
tableName: options.table ?? csvName.
|
|
425
|
+
tableName: options.table ?? csvName.replaceAll(/[^a-zA-Z0-9_]/g, "_"),
|
|
413
426
|
outputPath: options.output ?? join(dirname(options.input), csvName + ".db"),
|
|
414
427
|
sampleSize: options.sample ?? 100,
|
|
415
428
|
separator: options.separator ?? ",",
|
|
@@ -418,3 +431,5 @@ export async function ingestCSV(options: IngestCSVOptions): Promise<void> {
|
|
|
418
431
|
dryRun: options.dryRun ?? false,
|
|
419
432
|
})
|
|
420
433
|
}
|
|
434
|
+
|
|
435
|
+
//#endregion
|
|
@@ -82,17 +82,27 @@ const COLUMN_TYPES: Record<(typeof REQUIRED_COLUMNS)[number], string> = {
|
|
|
82
82
|
synth_base_id: "VARCHAR",
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* Options for {@linkcode jsonlToParquet}.
|
|
87
|
+
*/
|
|
86
88
|
export interface JSONLToParquetOptions {
|
|
87
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* The labeled-row JSONL to convert.
|
|
91
|
+
*/
|
|
88
92
|
input: string
|
|
89
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* The parquet shard to write.
|
|
95
|
+
*/
|
|
90
96
|
output: string
|
|
91
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* Parquet row-group size. Default 50000.
|
|
99
|
+
*/
|
|
92
100
|
rowGroupSize?: number
|
|
93
101
|
}
|
|
94
102
|
|
|
95
|
-
/**
|
|
103
|
+
/**
|
|
104
|
+
* Summary returned by {@linkcode jsonlToParquet}.
|
|
105
|
+
*/
|
|
96
106
|
export interface JSONLToParquetSummary {
|
|
97
107
|
read: number
|
|
98
108
|
written: number
|
|
@@ -115,6 +125,7 @@ function assertSpanTriple(row: Record<string, unknown>, lineNo: number): void {
|
|
|
115
125
|
"must carry span_starts/span_ends/span_tags; re-emit this shard through alignRow."
|
|
116
126
|
)
|
|
117
127
|
}
|
|
128
|
+
|
|
118
129
|
const n = (row.span_starts as unknown[]).length
|
|
119
130
|
|
|
120
131
|
if ((row.span_ends as unknown[]).length !== n || (row.span_tags as unknown[]).length !== n) {
|
|
@@ -126,17 +137,21 @@ function assertSpanTriple(row: Record<string, unknown>, lineNo: number): void {
|
|
|
126
137
|
}
|
|
127
138
|
}
|
|
128
139
|
|
|
129
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Escape a path for single-quoted SQL string literals.
|
|
142
|
+
*/
|
|
130
143
|
function sqlString(value: string): string {
|
|
131
|
-
return value.
|
|
144
|
+
return value.replaceAll("'", "''")
|
|
132
145
|
}
|
|
133
146
|
|
|
134
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* Convert a labeled-row JSONL to a v0.5.0-schema Parquet shard.
|
|
149
|
+
*/
|
|
135
150
|
export async function jsonlToParquet(
|
|
136
151
|
options: JSONLToParquetOptions,
|
|
137
152
|
report?: (line: string) => void
|
|
138
153
|
): Promise<JSONLToParquetSummary> {
|
|
139
|
-
const rowGroupSize = options.rowGroupSize ??
|
|
154
|
+
const rowGroupSize = options.rowGroupSize ?? 50_000
|
|
140
155
|
|
|
141
156
|
if (!Number.isInteger(rowGroupSize) || rowGroupSize <= 0) {
|
|
142
157
|
throw new Error(`rowGroupSize must be a positive integer (got ${JSON.stringify(rowGroupSize)})`)
|
|
@@ -166,9 +181,13 @@ export async function jsonlToParquet(
|
|
|
166
181
|
// Write the validated line verbatim; DuckDB's `read_json` projects to the explicit `columns`
|
|
167
182
|
// map below (extra keys dropped, absent keys → NULL — matching the Python `row.get(c)`).
|
|
168
183
|
stage.write(line + "\n")
|
|
184
|
+
|
|
169
185
|
rows++
|
|
170
186
|
}
|
|
171
|
-
|
|
187
|
+
|
|
188
|
+
await new Promise<void>((resolve, reject) => {
|
|
189
|
+
stage.end((err?: Error | null) => (err ? reject(err) : resolve()))
|
|
190
|
+
})
|
|
172
191
|
|
|
173
192
|
report?.(`Read ${rows} rows from ${options.input}`)
|
|
174
193
|
|
|
@@ -182,6 +201,7 @@ export async function jsonlToParquet(
|
|
|
182
201
|
// Row order is load-bearing: the overlay-manifest assembler records first/last source_id from
|
|
183
202
|
// shard order. `preserve_insertion_order` (DuckDB default) keeps output order = input order.
|
|
184
203
|
await db.run("SET preserve_insertion_order=true")
|
|
204
|
+
|
|
185
205
|
await db.run(
|
|
186
206
|
`COPY (SELECT ${selectList} FROM read_json('${sqlString(stagePath)}', ` +
|
|
187
207
|
`columns = ${columnsLiteral}, format = 'newline_delimited')) ` +
|