Skip to content

Commit ea2d5bb

Browse files
authored
Merge pull request #146 from nrabinowitz/legacy-api
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.
2 parents 281729f + acc549b commit ea2d5bb

11 files changed

+1977
-8
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
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).
44

55
## [Unreleased]
6+
### Added
7+
- Added legacy API wrapper with Typescript types (#146)
68

79
## [4.0.0-rc1] - 2022-07-28
810
### Added

README.md

+51
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
9999

100100
* [h3](#module_h3)
101101
* [.UNITS](#module_h3.UNITS) : <code>Object</code>
102+
* [.h3IndexToSplitLong(h3Index)](#module_h3.h3IndexToSplitLong) ⇒ <code>Array.&lt;number&gt;</code>
103+
* [.splitLongToH3Index(lower, upper)](#module_h3.splitLongToH3Index) ⇒ <code>H3Index</code>
102104
* [.isValidCell(h3Index)](#module_h3.isValidCell) ⇒ <code>boolean</code>
103105
* [.isPentagon(h3Index)](#module_h3.isPentagon) ⇒ <code>boolean</code>
104106
* [.isResClassIII(h3Index)](#module_h3.isResClassIII) ⇒ <code>boolean</code>
@@ -169,6 +171,35 @@ Length/Area units
169171
| rads2 | <code>string</code> |
170172

171173

174+
* * *
175+
176+
<a name="module_h3.h3IndexToSplitLong"></a>
177+
178+
### h3.h3IndexToSplitLong(h3Index) ⇒ <code>Array.&lt;number&gt;</code>
179+
Convert an H3 index (64-bit hexidecimal string) into a "split long" - a pair of 32-bit ints
180+
181+
**Returns**: <code>Array.&lt;number&gt;</code> - A two-element array with 32 lower bits and 32 upper bits
182+
183+
| Param | Type | Description |
184+
| --- | --- | --- |
185+
| h3Index | <code>H3IndexInput</code> | H3 index to check |
186+
187+
188+
* * *
189+
190+
<a name="module_h3.splitLongToH3Index"></a>
191+
192+
### h3.splitLongToH3Index(lower, upper) ⇒ <code>H3Index</code>
193+
Get a H3 index string from a split long (pair of 32-bit ints)
194+
195+
**Returns**: <code>H3Index</code> - H3 index
196+
197+
| Param | Type | Description |
198+
| --- | --- | --- |
199+
| lower | <code>number</code> | Lower 32 bits |
200+
| upper | <code>number</code> | Upper 32 bits |
201+
202+
172203
* * *
173204

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

10751106

1107+
## Legacy API
1108+
1109+
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.
1110+
1111+
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.
1112+
1113+
Installation:
1114+
1115+
```
1116+
npm install h3-js
1117+
```
1118+
1119+
Usage:
1120+
1121+
```
1122+
import {geoToH3} from 'h3-js/legacy';
1123+
1124+
const h3Index = geoToH3(37.3615593, -122.0553238, 7);
1125+
```
1126+
10761127
## Development
10771128

10781129
The `h3-js` library uses `yarn` as the preferred package manager. To install the dev dependencies, just run:

doc-files/README.tmpl.md

+20
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ const coordinates = h3.cellsToMultiPolygon(hexagons, true);
9595

9696
{{>main}}
9797

98+
## Legacy API
99+
100+
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.
101+
102+
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.
103+
104+
Installation:
105+
106+
```
107+
npm install h3-js
108+
```
109+
110+
Usage:
111+
112+
```
113+
import {geoToH3} from 'h3-js/legacy';
114+
115+
const h3Index = geoToH3(37.3615593, -122.0553238, 7);
116+
```
117+
98118
## Development
99119

100120
The `h3-js` library uses `yarn` as the preferred package manager. To install the dev dependencies, just run:

index.js legacy.d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
2-
* Copyright 2018-2019 Uber Technologies, Inc.
2+
* Copyright 2022 Uber Technologies, Inc.
33
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* Licensed under the Apache License, Version 2.0 (the "License"),
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
@@ -14,4 +14,4 @@
1414
* limitations under the License.
1515
*/
1616

17-
module.exports = require('./dist/lib/h3core');
17+
import './dist/legacy-types';

legacy.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright 2022 Uber Technologies, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"),
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module.exports = require('./dist/legacy');

lib/h3core.js

-2
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ const INVALID_HEXIDECIMAL_CHAR = /[^0-9a-fA-F]/;
151151

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

194193
/**
195194
* Get a H3 index string from a split long (pair of 32-bit ints)
196-
* @private
197195
* @param {number} lower Lower 32 bits
198196
* @param {number} upper Upper 32 bits
199197
* @return {H3Index} H3 index

lib/legacy-mapping.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2022 Uber Technologies, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"),
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module.exports = {
18+
UNITS: 'UNITS',
19+
h3IndexToSplitLong: 'h3IndexToSplitLong',
20+
splitLongToH3Index: 'splitLongToH3Index',
21+
h3IsValid: 'isValidCell',
22+
h3IsPentagon: 'isPentagon',
23+
h3IsResClassIII: 'isResClassIII',
24+
h3GetBaseCell: 'getBaseCellNumber',
25+
h3GetFaces: 'getIcosahedronFaces',
26+
h3GetResolution: 'getResolution',
27+
geoToH3: 'latLngToCell',
28+
h3ToGeo: 'cellToLatLng',
29+
h3ToGeoBoundary: 'cellToBoundary',
30+
h3ToParent: 'cellToParent',
31+
h3ToChildren: 'cellToChildren',
32+
h3ToCenterChild: 'cellToCenterChild',
33+
kRing: 'gridDisk',
34+
kRingDistances: 'gridDiskDistances',
35+
hexRing: 'gridRingUnsafe',
36+
polyfill: 'polygonToCells',
37+
h3SetToMultiPolygon: 'cellsToMultiPolygon',
38+
compact: 'compactCells',
39+
uncompact: 'uncompactCells',
40+
h3IndexesAreNeighbors: 'areNeighborCells',
41+
getH3UnidirectionalEdge: 'cellsToDirectedEdge',
42+
getOriginH3IndexFromUnidirectionalEdge: 'getDirectedEdgeOrigin',
43+
getDestinationH3IndexFromUnidirectionalEdge: 'getDirectedEdgeDestination',
44+
h3UnidirectionalEdgeIsValid: 'isValidDirectedEdge',
45+
getH3IndexesFromUnidirectionalEdge: 'directedEdgeToCells',
46+
getH3UnidirectionalEdgesFromHexagon: 'originToDirectedEdges',
47+
getH3UnidirectionalEdgeBoundary: 'directedEdgeToBoundary',
48+
h3Distance: 'gridDistance',
49+
h3Line: 'gridPathCells',
50+
experimentalH3ToLocalIj: 'cellToLocalIj',
51+
experimentalLocalIjToH3: 'localIjToCell',
52+
pointDist: 'greatCircleDistance',
53+
cellArea: 'cellArea',
54+
exactEdgeLength: 'exactEdgeLength',
55+
hexArea: 'getHexagonAreaAvg',
56+
edgeLength: 'getHexagonEdgeLengthAvg',
57+
numHexagons: 'getNumCells',
58+
getRes0Indexes: 'getRes0Cells',
59+
getPentagonIndexes: 'getPentagons',
60+
degsToRads: 'degsToRads',
61+
radsToDegs: 'radsToDegs'
62+
};

package.json

+7-3
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
"scripts": {
2929
"build-update-h3": "bash scripts/update-h3.sh",
3030
"build-emscripten": "yarn build-update-h3 && yarn docker-emscripten",
31+
"build-legacy": "node scripts/build-legacy-api.js",
3132
"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",
32-
"build-tsd": "jsdoc -t node_modules/tsd-jsdoc/dist -d console lib/h3core.js | sed 's/\"h3\"/\"h3-js\"/g' > dist/types.d.ts",
33+
"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",
34+
"build-tsd-legacy": "node scripts/build-legacy-types.js",
35+
"build-tsd": "yarn build-tsd-core && yarn build-tsd-legacy",
3336
"bundle-umd": "microbundle --name h3 --format=umd",
3437
"bundle-cjs": "microbundle --format=cjs --no-compress",
3538
"bundle-es": "microbundle --format=es --no-compress",
3639
"bundle-cjs-browser": "microbundle -o dist/browser --format=cjs --no-compress --alias ../out/libh3=$(printf '%q' \"$PWD\")/dist/libh3-browser",
3740
"bundle-es-browser": "microbundle -o dist/browser --format=es --no-compress --alias ../out/libh3=$(printf '%q' \"$PWD\")/dist/libh3-browser",
38-
"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",
41+
"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",
3942
"dist-clean": "rm -rf dist",
4043
"rollup-test": "rollup test/index.js --file dist/test.js --sourcemap --format=cjs --external=tape,fs,path",
4144
"rollup-bindings": "rollup build/print-bindings.js --file dist/print-bindings.js --format cjs",
@@ -51,9 +54,10 @@
5154
"check-docs": "yarn build-docs && git diff --exit-code",
5255
"check-tsd": "yarn build-tsd && tsc --strict --noEmit dist/types.d.ts",
5356
"lint": "eslint lib* test/*",
54-
"test": "yarn lint && yarn test-fast",
57+
"test": "yarn lint && yarn test-fast && yarn test-legacy",
5558
"test-fast": "yarn test-raw | faucet",
5659
"test-raw": "yarn rollup-test && node dist/test.js",
60+
"test-legacy": "node test/legacy.spec.js | faucet",
5761
"cover": "yarn rollup-test && nyc --clean --reporter=lcov --reporter=text node dist/test.js",
5862
"cover-view": "yarn rollup-test && nyc --clean --reporter=html node dist/test.js && open coverage/index.html",
5963
"benchmark-node": "yarn rollup-benchmark-node && node dist/benchmark.node.js",

scripts/build-legacy-api.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2022 Uber Technologies, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"),
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* @fileoverview
19+
* Create the module for the legacy v3 API and write to dist.
20+
*/
21+
22+
const fs = require('fs');
23+
const path = require('path');
24+
const mapping = require('../lib/legacy-mapping');
25+
26+
const content = `
27+
const h3v4 = require('./h3-js');
28+
29+
module.exports = {
30+
${Object.entries(mapping)
31+
.map(([oldName, newName]) => `${oldName}: h3v4.${newName}`)
32+
.join(',\n')}
33+
};
34+
`;
35+
36+
fs.writeFileSync(path.join(__dirname, '../dist/legacy.js'), content, 'utf-8');

scripts/build-legacy-types.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2022 Uber Technologies, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"),
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* @fileoverview
19+
* Create Typescript types for the legacy v3 API and write to dist. Depends
20+
* on the current v4 types already being generated in dist.
21+
*/
22+
23+
const fs = require('fs');
24+
const path = require('path');
25+
const mapping = require('../lib/legacy-mapping');
26+
27+
let content = fs.readFileSync(path.join(__dirname, '../dist/types.d.ts'), 'utf-8');
28+
29+
for (const [oldName, newName] of Object.entries(mapping)) {
30+
const regex = new RegExp(`\\b${newName}\\b`, 'g');
31+
content = content.replace(regex, oldName);
32+
}
33+
34+
fs.writeFileSync(path.join(__dirname, '../dist/legacy-types.d.ts'), content, 'utf-8');

0 commit comments

Comments
 (0)