Skip to content

Commit

Permalink
Merge pull request #146 from nrabinowitz/legacy-api
Browse files Browse the repository at this point in the history
This adds a legacy API wrapper, available from h3-js/legacy, which exports the v4 functions using the v3 names. The intent is to help ease migration to the v4 library. In addition to allowing users to put off migrating their code, this provides a path, albeit awkward, to avoid bundling two versions of the library when dependencies have not upgraded to v4, by rewriting dependency import paths at build time to point to the legacy API.
  • Loading branch information
nrabinowitz authored Aug 11, 2022
2 parents 281729f + acc549b commit ea2d5bb
Show file tree
Hide file tree
Showing 11 changed files with 1,977 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
All notable changes to this project will be documented in this file. This library adheres to a versioning policy described in [the README](./README.md#versioning). The public API of this library consists of the functions exported in [h3core.js](./lib/h3core.js).

## [Unreleased]
### Added
- Added legacy API wrapper with Typescript types (#146)

## [4.0.0-rc1] - 2022-07-28
### Added
Expand Down
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);

* [h3](#module_h3)
* [.UNITS](#module_h3.UNITS) : <code>Object</code>
* [.h3IndexToSplitLong(h3Index)](#module_h3.h3IndexToSplitLong) ⇒ <code>Array.&lt;number&gt;</code>
* [.splitLongToH3Index(lower, upper)](#module_h3.splitLongToH3Index) ⇒ <code>H3Index</code>
* [.isValidCell(h3Index)](#module_h3.isValidCell) ⇒ <code>boolean</code>
* [.isPentagon(h3Index)](#module_h3.isPentagon) ⇒ <code>boolean</code>
* [.isResClassIII(h3Index)](#module_h3.isResClassIII) ⇒ <code>boolean</code>
Expand Down Expand Up @@ -169,6 +171,35 @@ Length/Area units
| rads2 | <code>string</code> |


* * *

<a name="module_h3.h3IndexToSplitLong"></a>

### h3.h3IndexToSplitLong(h3Index) ⇒ <code>Array.&lt;number&gt;</code>
Convert an H3 index (64-bit hexidecimal string) into a "split long" - a pair of 32-bit ints

**Returns**: <code>Array.&lt;number&gt;</code> - A two-element array with 32 lower bits and 32 upper bits

| Param | Type | Description |
| --- | --- | --- |
| h3Index | <code>H3IndexInput</code> | H3 index to check |


* * *

<a name="module_h3.splitLongToH3Index"></a>

### h3.splitLongToH3Index(lower, upper) ⇒ <code>H3Index</code>
Get a H3 index string from a split long (pair of 32-bit ints)

**Returns**: <code>H3Index</code> - H3 index

| Param | Type | Description |
| --- | --- | --- |
| lower | <code>number</code> | Lower 32 bits |
| upper | <code>number</code> | Upper 32 bits |


* * *

<a name="module_h3.isValidCell"></a>
Expand Down Expand Up @@ -1073,6 +1104,26 @@ core H3 library and can be found [in the H3 docs](https://h3geo.org/docs/next/li
* * *


## Legacy API

H3 v4 renamed the majority of the functions in the library. To help ease migration from H3 v3 to H3 v4, we offer a legacy API wrapper at `h3-js/legacy`, which exports the v4 functions with the v3 names. Users are welcome to use the legacy API wrapper as a transitional support, but are encouraged to upgrade to the H3 v4 API as soon as possible.

Note that the legacy API is _not_ 100% backwards compatible - it's a thin wrapper on top of the v4 functions, so in cases where behavior has changed, the v4 behavior will be used. In particular, many of the v4 functions will throw errors for invalid input, where v3 functions would return null.

Installation:

```
npm install h3-js
```

Usage:

```
import {geoToH3} from 'h3-js/legacy';
const h3Index = geoToH3(37.3615593, -122.0553238, 7);
```

## Development

The `h3-js` library uses `yarn` as the preferred package manager. To install the dev dependencies, just run:
Expand Down
20 changes: 20 additions & 0 deletions doc-files/README.tmpl.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,26 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);

{{>main}}

## Legacy API

H3 v4 renamed the majority of the functions in the library. To help ease migration from H3 v3 to H3 v4, we offer a legacy API wrapper at `h3-js/legacy`, which exports the v4 functions with the v3 names. Users are welcome to use the legacy API wrapper as a transitional support, but are encouraged to upgrade to the H3 v4 API as soon as possible.

Note that the legacy API is _not_ 100% backwards compatible - it's a thin wrapper on top of the v4 functions, so in cases where behavior has changed, the v4 behavior will be used. In particular, many of the v4 functions will throw errors for invalid input, where v3 functions would return null.

Installation:

```
npm install h3-js
```

Usage:

```
import {geoToH3} from 'h3-js/legacy';
const h3Index = geoToH3(37.3615593, -122.0553238, 7);
```

## Development

The `h3-js` library uses `yarn` as the preferred package manager. To install the dev dependencies, just run:
Expand Down
6 changes: 3 additions & 3 deletions index.js → legacy.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright 2018-2019 Uber Technologies, Inc.
* Copyright 2022 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
Expand All @@ -14,4 +14,4 @@
* limitations under the License.
*/

module.exports = require('./dist/lib/h3core');
import './dist/legacy-types';
17 changes: 17 additions & 0 deletions legacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2022 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module.exports = require('./dist/legacy');
2 changes: 0 additions & 2 deletions lib/h3core.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ const INVALID_HEXIDECIMAL_CHAR = /[^0-9a-fA-F]/;

/**
* Convert an H3 index (64-bit hexidecimal string) into a "split long" - a pair of 32-bit ints
* @private
* @param {H3IndexInput} h3Index H3 index to check
* @return {number[]} A two-element array with 32 lower bits and 32 upper bits
*/
Expand Down Expand Up @@ -193,7 +192,6 @@ function hexFrom32Bit(num) {

/**
* Get a H3 index string from a split long (pair of 32-bit ints)
* @private
* @param {number} lower Lower 32 bits
* @param {number} upper Upper 32 bits
* @return {H3Index} H3 index
Expand Down
62 changes: 62 additions & 0 deletions lib/legacy-mapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2022 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module.exports = {
UNITS: 'UNITS',
h3IndexToSplitLong: 'h3IndexToSplitLong',
splitLongToH3Index: 'splitLongToH3Index',
h3IsValid: 'isValidCell',
h3IsPentagon: 'isPentagon',
h3IsResClassIII: 'isResClassIII',
h3GetBaseCell: 'getBaseCellNumber',
h3GetFaces: 'getIcosahedronFaces',
h3GetResolution: 'getResolution',
geoToH3: 'latLngToCell',
h3ToGeo: 'cellToLatLng',
h3ToGeoBoundary: 'cellToBoundary',
h3ToParent: 'cellToParent',
h3ToChildren: 'cellToChildren',
h3ToCenterChild: 'cellToCenterChild',
kRing: 'gridDisk',
kRingDistances: 'gridDiskDistances',
hexRing: 'gridRingUnsafe',
polyfill: 'polygonToCells',
h3SetToMultiPolygon: 'cellsToMultiPolygon',
compact: 'compactCells',
uncompact: 'uncompactCells',
h3IndexesAreNeighbors: 'areNeighborCells',
getH3UnidirectionalEdge: 'cellsToDirectedEdge',
getOriginH3IndexFromUnidirectionalEdge: 'getDirectedEdgeOrigin',
getDestinationH3IndexFromUnidirectionalEdge: 'getDirectedEdgeDestination',
h3UnidirectionalEdgeIsValid: 'isValidDirectedEdge',
getH3IndexesFromUnidirectionalEdge: 'directedEdgeToCells',
getH3UnidirectionalEdgesFromHexagon: 'originToDirectedEdges',
getH3UnidirectionalEdgeBoundary: 'directedEdgeToBoundary',
h3Distance: 'gridDistance',
h3Line: 'gridPathCells',
experimentalH3ToLocalIj: 'cellToLocalIj',
experimentalLocalIjToH3: 'localIjToCell',
pointDist: 'greatCircleDistance',
cellArea: 'cellArea',
exactEdgeLength: 'exactEdgeLength',
hexArea: 'getHexagonAreaAvg',
edgeLength: 'getHexagonEdgeLengthAvg',
numHexagons: 'getNumCells',
getRes0Indexes: 'getRes0Cells',
getPentagonIndexes: 'getPentagons',
degsToRads: 'degsToRads',
radsToDegs: 'radsToDegs'
};
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@
"scripts": {
"build-update-h3": "bash scripts/update-h3.sh",
"build-emscripten": "yarn build-update-h3 && yarn docker-emscripten",
"build-legacy": "node scripts/build-legacy-api.js",
"build-docs": "jsdoc2md --no-cache --global-index-format grouped --partial doc-files/scope.hbs --helper ./doc-files/insert-version.js --separators --template doc-files/README.tmpl.md lib/h3core.js lib/errors.js > README.md",
"build-tsd": "jsdoc -t node_modules/tsd-jsdoc/dist -d console lib/h3core.js | sed 's/\"h3\"/\"h3-js\"/g' > dist/types.d.ts",
"build-tsd-core": "jsdoc -t node_modules/tsd-jsdoc/dist -d console lib/h3core.js | sed 's/\"h3\"/\"h3-js\"/g' > dist/types.d.ts",
"build-tsd-legacy": "node scripts/build-legacy-types.js",
"build-tsd": "yarn build-tsd-core && yarn build-tsd-legacy",
"bundle-umd": "microbundle --name h3 --format=umd",
"bundle-cjs": "microbundle --format=cjs --no-compress",
"bundle-es": "microbundle --format=es --no-compress",
"bundle-cjs-browser": "microbundle -o dist/browser --format=cjs --no-compress --alias ../out/libh3=$(printf '%q' \"$PWD\")/dist/libh3-browser",
"bundle-es-browser": "microbundle -o dist/browser --format=es --no-compress --alias ../out/libh3=$(printf '%q' \"$PWD\")/dist/libh3-browser",
"dist": "yarn dist-clean && yarn docker-emscripten-browser && yarn bundle-umd && yarn bundle-cjs && yarn bundle-cjs-browser && yarn bundle-es && yarn bundle-es-browser && yarn build-tsd",
"dist": "yarn dist-clean && yarn docker-emscripten-browser && yarn bundle-umd && yarn bundle-cjs && yarn bundle-cjs-browser && yarn bundle-es && yarn bundle-es-browser && yarn build-legacy && yarn build-tsd",
"dist-clean": "rm -rf dist",
"rollup-test": "rollup test/index.js --file dist/test.js --sourcemap --format=cjs --external=tape,fs,path",
"rollup-bindings": "rollup build/print-bindings.js --file dist/print-bindings.js --format cjs",
Expand All @@ -51,9 +54,10 @@
"check-docs": "yarn build-docs && git diff --exit-code",
"check-tsd": "yarn build-tsd && tsc --strict --noEmit dist/types.d.ts",
"lint": "eslint lib* test/*",
"test": "yarn lint && yarn test-fast",
"test": "yarn lint && yarn test-fast && yarn test-legacy",
"test-fast": "yarn test-raw | faucet",
"test-raw": "yarn rollup-test && node dist/test.js",
"test-legacy": "node test/legacy.spec.js | faucet",
"cover": "yarn rollup-test && nyc --clean --reporter=lcov --reporter=text node dist/test.js",
"cover-view": "yarn rollup-test && nyc --clean --reporter=html node dist/test.js && open coverage/index.html",
"benchmark-node": "yarn rollup-benchmark-node && node dist/benchmark.node.js",
Expand Down
36 changes: 36 additions & 0 deletions scripts/build-legacy-api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2022 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @fileoverview
* Create the module for the legacy v3 API and write to dist.
*/

const fs = require('fs');
const path = require('path');
const mapping = require('../lib/legacy-mapping');

const content = `
const h3v4 = require('./h3-js');
module.exports = {
${Object.entries(mapping)
.map(([oldName, newName]) => `${oldName}: h3v4.${newName}`)
.join(',\n')}
};
`;

fs.writeFileSync(path.join(__dirname, '../dist/legacy.js'), content, 'utf-8');
34 changes: 34 additions & 0 deletions scripts/build-legacy-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2022 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"),
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @fileoverview
* Create Typescript types for the legacy v3 API and write to dist. Depends
* on the current v4 types already being generated in dist.
*/

const fs = require('fs');
const path = require('path');
const mapping = require('../lib/legacy-mapping');

let content = fs.readFileSync(path.join(__dirname, '../dist/types.d.ts'), 'utf-8');

for (const [oldName, newName] of Object.entries(mapping)) {
const regex = new RegExp(`\\b${newName}\\b`, 'g');
content = content.replace(regex, oldName);
}

fs.writeFileSync(path.join(__dirname, '../dist/legacy-types.d.ts'), content, 'utf-8');
Loading

0 comments on commit ea2d5bb

Please sign in to comment.