From 038c1caf14a7b01d2a0cb3b1d8117225789ff170 Mon Sep 17 00:00:00 2001 From: Tyler Stewart Date: Tue, 4 Aug 2020 08:54:53 -0600 Subject: [PATCH] feat: expose array-like methods for searching data Instead of limiting an end-user to a string search, enable `predicate` functions to `find` and `filter` values. BREAKING CHANGE: exposed api changed from string search to predicate methods --- package.json | 6 +++++- src/generate.js | 7 +++++-- src/index.d.ts | 8 ++++++-- src/index.js | 36 +++++++++++++++--------------------- src/util.js | 9 --------- 5 files changed, 31 insertions(+), 35 deletions(-) delete mode 100644 src/util.js diff --git a/package.json b/package.json index c343837..6d108f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "canadian-city-timezones", - "version": "1.0.0", + "version": "2.0.0", "description": "Searchable timezones for all Canadian cities, towns, townships, villages, hamlets, and municipalities.", "main": "src/index.js", "types": "src/index.d.ts", @@ -19,6 +19,10 @@ "timezones" ], "author": "trs", + "repository": { + "type": "git", + "url": "https://github.com/autovance/canadian-city-timezones" + }, "license": "MIT", "devDependencies": { "csv-parser": "^2.3.3", diff --git a/src/generate.js b/src/generate.js index 9c301b0..28613d6 100644 --- a/src/generate.js +++ b/src/generate.js @@ -8,7 +8,6 @@ const fetch = require('node-fetch'); const csv = require('csv-parser'); const geoTz = require('geo-tz'); const removeAccents = require('remove-accents'); -const {removeSpecialCharacters} = require('./util'); const mkdirAsync = promisify(mkdir); const pipelineAsync = promisify(pipeline); @@ -27,11 +26,15 @@ const VALID_CSD_TYPES = [ 'Village' ]; +const VALID_CHARACTERS_REGEX = /[^a-zA-Z0-9 ]/ig; + +const removeSpecialCharacters = (value = '') => value.replace(VALID_CHARACTERS_REGEX, '').toLocaleLowerCase(); + const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function * getCityData() { const req = await fetch(CAN_CITY_LIST); - // Download file first as the csv parser would prematurely end being piped it directly + // Download file first as the csv parser would prematurely end being piped in directly await pipelineAsync( req.body, createWriteStream('gc.csv') diff --git a/src/index.d.ts b/src/index.d.ts index 5eac3d1..6b30a44 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -4,6 +4,10 @@ declare interface TimezoneResult { timezone: string; } -declare function find(query: string): Promise; +declare type Predicate = (data: TimezoneResult) => boolean; -declare function findAll(query: string): Promise; +declare function values(): AsyncGenerator; + +declare function find(predicate: Predicate): Promise; + +declare function findAll(predicate: Predicate): AsyncGenerator; diff --git a/src/index.js b/src/index.js index 35701ca..864dc72 100644 --- a/src/index.js +++ b/src/index.js @@ -27,43 +27,37 @@ async function * getDataIterator() { } } -const isPartialMatchFactory = (query) => { - const searchItems = query.split(' ').map((item) => removeSpecialCharacters(item)); - - return (data) => { - const values = [ - data.name, - data.province - ]; - - return searchItems.every((item) => values.join().includes(item)); - } +async function* values() { + yield* getDataIterator(); } -async function find(query) { - const isPartialMatch = isPartialMatchFactory(query); +async function find(predicate) { + if (typeof predicate !== 'function') { + throw new TypeError(`${String(predicate)} is not a function`); + } for await (const data of getDataIterator()) { - if (isPartialMatch(data)) { + if (predicate(data)) { return data; } } return null; } -async function findAll(query) { - const isPartialMatch = isPartialMatchFactory(query); +async function* filter(predicate) { + if (typeof predicate !== 'function') { + throw new TypeError(`${String(predicate)} is not a function`); + } - const results = []; for await (const data of getDataIterator()) { - if (isPartialMatch(data)) { - results.push(data); + if (predicate(data)) { + yield data; } } - return results; } module.exports = { + values, find, - findAll + filter }; diff --git a/src/util.js b/src/util.js deleted file mode 100644 index c118d7c..0000000 --- a/src/util.js +++ /dev/null @@ -1,9 +0,0 @@ -const VALID_CHARACTERS_REGEX = /[^a-zA-Z0-9 ]/ig; - -function removeSpecialCharacters(value = '') { - return value.replace(VALID_CHARACTERS_REGEX, '').toLocaleLowerCase(); -} - -module.exports = { - removeSpecialCharacters -};