@hebcal/geo-sqlite 5.9.2 → 5.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +46 -13
  2. package/package.json +8 -9
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- /*! @hebcal/geo-sqlite v5.9.2 */
2
- import Database from 'better-sqlite3';
1
+ /*! @hebcal/geo-sqlite v5.10.0 */
2
+ import { DatabaseSync } from 'node:sqlite';
3
+ import fs$1, { existsSync } from 'node:fs';
3
4
  import QuickLRU from 'quick-lru';
4
5
  import { Location, Locale } from '@hebcal/core';
5
6
  import '@hebcal/cities';
@@ -7,7 +8,6 @@ import { transliterate } from 'transliteration';
7
8
  import events from 'events';
8
9
  import fs from 'fs';
9
10
  import readline from 'readline';
10
- import fs$1 from 'node:fs';
11
11
 
12
12
  var city2geonameid = {
13
13
  "AD-Andorra La Vella":3041563,
@@ -512,7 +512,7 @@ function munge(s) {
512
512
  }
513
513
 
514
514
  // DO NOT EDIT THIS AUTO-GENERATED FILE!
515
- const version = '5.9.2';
515
+ const version = '5.10.0';
516
516
 
517
517
  const GEONAME_SQL = `SELECT
518
518
  g.name as name,
@@ -558,7 +558,7 @@ FROM ZIPCodes_Primary`;
558
558
 
559
559
  const ZIP_COMPLETE_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,TimeZone,DayLightSaving,Population
560
560
  FROM ZIPCodes_Primary
561
- WHERE ZipCode LIKE ?
561
+ WHERE ZipCode >= ? AND ZipCode < ?
562
562
  ORDER BY Population DESC
563
563
  LIMIT 10`;
564
564
 
@@ -641,9 +641,15 @@ class GeoDb {
641
641
  constructor(logger, zipsFilename, geonamesFilename, options) {
642
642
  this.logger = logger;
643
643
  if (logger) logger.info(`GeoDb: opening ${zipsFilename}...`);
644
- this.zipsDb = new Database(zipsFilename, {fileMustExist: true});
644
+ if (!existsSync(zipsFilename)) {
645
+ throw new Error(`GeoDb: ${zipsFilename} does not exist`);
646
+ }
647
+ this.zipsDb = new DatabaseSync(zipsFilename);
645
648
  if (logger) logger.info(`GeoDb: opening ${geonamesFilename}...`);
646
- this.geonamesDb = new Database(geonamesFilename, {fileMustExist: true});
649
+ if (!existsSync(geonamesFilename)) {
650
+ throw new Error(`GeoDb: ${geonamesFilename} does not exist`);
651
+ }
652
+ this.geonamesDb = new DatabaseSync(geonamesFilename);
647
653
  this.zipStmt = this.zipsDb.prepare(ZIPCODE_SQL);
648
654
  const zipsCacheSize = options?.zipsCacheSize || 150;
649
655
  /** @type {Map<string, Location>} */
@@ -879,11 +885,18 @@ class GeoDb {
879
885
  }
880
886
  const firstCharCode = qraw.charCodeAt(0);
881
887
  if (firstCharCode >= 48 && firstCharCode <= 57) {
888
+ // special-case PK query instead of full-table scan
889
+ if (GeoDb.is5DigitZip(qraw)) {
890
+ const loc = this.lookupZip(qraw);
891
+ return loc ? [GeoDb.zipLocToAutocomplete(loc)] : [];
892
+ }
882
893
  if (!this.zipCompStmt) {
883
894
  this.zipCompStmt = this.zipsDb.prepare(ZIP_COMPLETE_SQL);
884
895
  }
885
- const zip5 = qraw.substring(0, 5);
886
- return this.zipCompStmt.all(zip5 + '%').map(GeoDb.zipResultToObj);
896
+ // this is a ZIP code prefix, a string with 1-4 digits
897
+ const zipA = qraw.substring(0, 5);
898
+ const zipB = String(+zipA + 1).padStart(zipA.length, '0');
899
+ return this.zipCompStmt.all(zipA, zipB).map(GeoDb.zipResultToObj);
887
900
  } else {
888
901
  if (!this.geonamesCompStmt) {
889
902
  this.geonamesCompStmt = this.geonamesDb.prepare(GEONAME_COMPLETE_SQL);
@@ -1047,6 +1060,26 @@ class GeoDb {
1047
1060
  static version() {
1048
1061
  return version;
1049
1062
  }
1063
+
1064
+ /**
1065
+ * @param {string} str
1066
+ * @return {boolean}
1067
+ */
1068
+ static is5DigitZip(str) {
1069
+ if (typeof str !== 'string') {
1070
+ return false;
1071
+ }
1072
+ const s = str.trim();
1073
+ if (s.length < 5) {
1074
+ return false;
1075
+ }
1076
+ for (let i = 0; i < 5; i++) {
1077
+ if (s.charCodeAt(i) > 57 || s.charCodeAt(i) < 48) {
1078
+ return false;
1079
+ }
1080
+ }
1081
+ return true;
1082
+ }
1050
1083
  }
1051
1084
 
1052
1085
  /* eslint-disable no-multi-spaces */
@@ -1080,8 +1113,8 @@ async function buildGeonamesSqlite(opts) {
1080
1113
  const ILalternate = opts.ILalternate;
1081
1114
  const logger = opts.logger;
1082
1115
  logger.info(`Opening ${dbFilename}`);
1083
- const db = new Database(dbFilename);
1084
- db.pragma('journal_mode = MEMORY');
1116
+ const db = new DatabaseSync(dbFilename);
1117
+ db.exec('PRAGMA journal_mode = MEMORY');
1085
1118
 
1086
1119
  doSql(logger, db,
1087
1120
  `DROP TABLE IF EXISTS country`,
@@ -1419,7 +1452,7 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
1419
1452
  return;
1420
1453
  }
1421
1454
  }
1422
- stmt.run(a);
1455
+ stmt.run(...a);
1423
1456
  accepted++;
1424
1457
  });
1425
1458
 
@@ -1444,7 +1477,7 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
1444
1477
  */
1445
1478
  function makeZipsSqlite(dbFilename, sqlFile) {
1446
1479
  const sql = fs$1.readFileSync(sqlFile, 'utf8');
1447
- const db = new Database(dbFilename);
1480
+ const db = new DatabaseSync(dbFilename);
1448
1481
  console.log(sql);
1449
1482
  db.exec(sql);
1450
1483
  db.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hebcal/geo-sqlite",
3
- "version": "5.9.2",
3
+ "version": "5.10.0",
4
4
  "author": "Michael J. Radwin (https://github.com/mjradwin)",
5
5
  "keywords": [
6
6
  "hebcal"
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "typings": "geo-sqlite.d.ts",
29
29
  "engines": {
30
- "node": ">= 20.0.0"
30
+ "node": ">= 22.5.0"
31
31
  },
32
32
  "files": [
33
33
  "dist",
@@ -39,8 +39,7 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "@hebcal/cities": "^6.1.0",
42
- "@hebcal/core": "^6.0.8",
43
- "better-sqlite3": "^12.8.0",
42
+ "@hebcal/core": "^6.3.3",
44
43
  "minimist": "^1.2.8",
45
44
  "pino": "^10.3.1",
46
45
  "pino-pretty": "^13.1.3",
@@ -66,13 +65,13 @@
66
65
  "@eslint/js": "^10.0.1",
67
66
  "@rollup/plugin-json": "^6.1.0",
68
67
  "@rollup/plugin-node-resolve": "^16.0.3",
69
- "ava": "^7.0.0",
70
- "eslint": "^10.0.3",
68
+ "ava": "^8.0.0",
69
+ "eslint": "^10.3.0",
71
70
  "eslint-config-google": "^0.14.0",
72
- "eslint-plugin-n": "^17.24.0",
73
- "globals": "^17.4.0",
71
+ "eslint-plugin-n": "^18.0.1",
72
+ "globals": "^17.6.0",
74
73
  "jsdoc": "^4.0.5",
75
74
  "jsdoc-to-markdown": "^9.1.3",
76
- "rollup": "^4.59.0"
75
+ "rollup": "^4.60.3"
77
76
  }
78
77
  }