From 86d64ab6003a201ddc22a3358a92761e5ee700bc Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Fri, 3 Dec 2021 12:15:58 +0000 Subject: [PATCH 1/7] refactor: convert to typescript --- package.json | 18 +- src/{bucket.js => bucket.ts} | 223 +++++------------- ...sumable-buffer.js => consumable-buffer.ts} | 36 +-- ...{consumable-hash.js => consumable-hash.ts} | 48 ++-- src/index.js | 31 --- src/index.ts | 25 ++ test/browser.js | 3 - test/browser.ts | 1 + ...spec.js => hamt-consumable-buffer.spec.ts} | 9 +- ...h.spec.js => hamt-consumable-hash.spec.ts} | 24 +- test/{hamt.spec.js => hamt.spec.ts} | 46 +--- test/node.js | 5 - test/node.ts | 3 + tsconfig.json | 4 +- 14 files changed, 160 insertions(+), 316 deletions(-) rename src/{bucket.js => bucket.ts} (55%) rename src/{consumable-buffer.js => consumable-buffer.ts} (76%) rename src/{consumable-hash.js => consumable-hash.ts} (73%) delete mode 100644 src/index.js create mode 100644 src/index.ts delete mode 100644 test/browser.js create mode 100644 test/browser.ts rename test/{hamt-consumable-buffer.spec.js => hamt-consumable-buffer.spec.ts} (93%) rename test/{hamt-consumable-hash.spec.js => hamt-consumable-hash.spec.ts} (76%) rename test/{hamt.spec.js => hamt.spec.ts} (85%) delete mode 100644 test/node.js create mode 100644 test/node.ts diff --git a/package.json b/package.json index 8ef57e9..da999b8 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,18 @@ "version": "2.0.1", "description": "JavaScript implementation of sharding using hash array mapped tries", "leadMaintainer": "Alex Potsides ", - "main": "src/index.js", + "main": "dist/src/index.js", + "type": "module", "scripts": { - "test": "aegir test", + "pretest": "npm run build", + "test": "aegir test -f ./dist/test/*.js", "prepare": "aegir build --no-bundle", "lint": "aegir ts -p check && aegir lint", "release": "aegir release", "release-minor": "aegir release --type minor", "release-major": "aegir release --type major", - "coverage": "aegir coverage" + "coverage": "aegir coverage", + "build": "tsc" }, "repository": { "type": "git", @@ -44,5 +47,12 @@ "contributors": [ "achingbrain " ], - "types": "dist/src/index.d.ts" + "typesVersions": { + "*": { + "src/*": [ + "dist/src/*", + "dist/src/*/index" + ] + } + } } diff --git a/src/bucket.js b/src/bucket.ts similarity index 55% rename from src/bucket.js rename to src/bucket.ts index e1dd421..6950a8a 100644 --- a/src/bucket.js +++ b/src/bucket.ts @@ -1,88 +1,62 @@ -'use strict' - // @ts-ignore -const SparseArray = require('sparse-array') -const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') - -/** - * @typedef {import('./consumable-hash').InfiniteHash} InfiniteHash - * @typedef {import('../').UserBucketOptions} UserBucketOptions - */ - -/** - * @template V - * @typedef {object} BucketChild - * @property {string} key - * @property {V} value - * @property {InfiniteHash} hash - */ - -/** - * @template B - * - * @typedef {object} SA - * @property {number} length - * @property {() => B[]} compactArray - * @property {(i: number) => B} get - * @property {(i: number, value: B) => void} set - * @property { (fn: (acc: A, curr: B, index: number) => A, initial: A) => B} reduce - * @property {(fn: (item: B) => boolean) => B | undefined} find - * @property {() => number[]} bitField - * @property {(i: number) => void} unset - */ - -/** - * @template T - * - * @typedef {object} BucketPosition - * @property {Bucket} bucket - * @property {number} pos - * @property {InfiniteHash} hash - * @property {BucketChild} [existingChild] - */ - -/** - * @typedef {object} BucketOptions - * @property {number} bits - * @property {(value: Uint8Array | InfiniteHash) => InfiniteHash} hash - */ - -/** - * @template T - */ -class Bucket { - /** - * @param {BucketOptions} options - * @param {Bucket} [parent] - * @param {number} [posAtParent=0] - */ - constructor (options, parent, posAtParent = 0) { +import SparseArray from 'sparse-array' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import type { InfiniteHash } from './consumable-hash.js' + +interface BucketChild { + key: string + value: V + hash: InfiniteHash +} + +interface SA { + length: number + compactArray: () => B[] + get: (i: number) => B + set: (i: number, value: B) => void + reduce: (fn: (acc: A, curr: B, index: number) => A, initial: A) => B + find: (fn: (item: B) => boolean) => B | undefined + bitField: () => number[] + unset: (i: number) => void +} + +interface BucketPosition { + bucket: Bucket + pos: number + hash: InfiniteHash + existingChild?: BucketChild +} + +interface BucketOptions { + bits: number + hash: (value: Uint8Array | InfiniteHash) => InfiniteHash +} + +class Bucket { + _options: BucketOptions + _popCount: number + _parent?: Bucket + _posAtParent: number + _children: SA | BucketChild> + + key: string | null + + constructor (options: BucketOptions, parent?: Bucket, posAtParent = 0) { this._options = options this._popCount = 0 this._parent = parent this._posAtParent = posAtParent - - /** @type {SA | BucketChild>} */ this._children = new SparseArray() - - /** @type {string | null} */ this.key = null } - /** - * @param {string} key - * @param {T} value - */ - async put (key, value) { + async put (key: string, value: T) { const place = await this._findNewBucketAndPos(key) await place.bucket._putAt(place, key, value) } - /** - * @param {string} key - */ - async get (key) { + async get (key: string) { const child = await this._findChild(key) if (child) { @@ -90,10 +64,7 @@ class Bucket { } } - /** - * @param {string} key - */ - async del (key) { + async del (key: string) { const place = await this._findPlace(key) const child = place.bucket._at(place.pos) @@ -102,10 +73,7 @@ class Bucket { } } - /** - * @returns {number} - */ - leafCount () { + leafCount (): number { const children = this._children.compactArray() return children.reduce((acc, child) => { @@ -125,33 +93,20 @@ class Bucket { return this._children.get(0) } - /** - * @returns {Iterable>} - */ - * eachLeafSeries () { + * eachLeafSeries (): Iterable> { const children = this._children.compactArray() for (const child of children) { if (child instanceof Bucket) { - yield * child.eachLeafSeries() + yield * Array.from(child.eachLeafSeries()) } else { yield child } } - - // this is necessary because tsc requires a @return annotation as it - // can't derive a return type due to the recursion, and eslint requires - // a return statement when there is a @return annotation - return [] } - /** - * @param {(value: BucketChild, index: number) => T} map - * @param {(reduced: any) => any} reduce - */ - serialize (map, reduce) { - /** @type {T[]} */ - const acc = [] + serialize (map: (value: BucketChild, index: number) => T, reduce: (reduced: any) => any) { + const acc: T[] = [] // serialize to a custom non-sparse representation return reduce(this._children.reduce((acc, child, index) => { if (child) { @@ -165,11 +120,7 @@ class Bucket { }, acc)) } - /** - * @param {(value: BucketChild) => Promise} asyncMap - * @param {(reduced: any) => Promise} asyncReduce - */ - asyncTransform (asyncMap, asyncReduce) { + asyncTransform (asyncMap: (value: BucketChild) => Promise, asyncReduce: (reduced: any) => Promise) { return asyncTransformBucket(this, asyncMap, asyncReduce) } @@ -185,11 +136,7 @@ class Bucket { return Math.pow(2, this._options.bits) } - /** - * @param {string} key - * @returns {Promise | undefined>} - */ - async _findChild (key) { + async _findChild (key: string) { const result = await this._findPlace(key) const child = result.bucket._at(result.pos) @@ -204,11 +151,7 @@ class Bucket { } } - /** - * @param {string | InfiniteHash} key - * @returns {Promise>} - */ - async _findPlace (key) { + async _findPlace (key: string | InfiniteHash): Promise> { const hashValue = this._options.hash(typeof key === 'string' ? uint8ArrayFromString(key) : key) const index = await hashValue.take(this._options.bits) @@ -226,11 +169,7 @@ class Bucket { } } - /** - * @param {string | InfiniteHash} key - * @returns {Promise>} - */ - async _findNewBucketAndPos (key) { + async _findNewBucketAndPos (key: string | InfiniteHash): Promise> { const place = await this._findPlace(key) if (place.existingChild && place.existingChild.key !== key) { @@ -249,12 +188,7 @@ class Bucket { return place } - /** - * @param {BucketPosition} place - * @param {string} key - * @param {T} value - */ - _putAt (place, key, value) { + _putAt (place: BucketPosition, key: string, value: T) { this._putObjectAt(place.pos, { key: key, value: value, @@ -262,21 +196,14 @@ class Bucket { }) } - /** - * @param {number} pos - * @param {Bucket | BucketChild} object - */ - _putObjectAt (pos, object) { + _putObjectAt (pos: number, object: Bucket | BucketChild) { if (!this._children.get(pos)) { this._popCount++ } this._children.set(pos, object) } - /** - * @param {number} pos - */ - _delAt (pos) { + _delAt (pos: number) { if (pos === -1) { throw new Error('Invalid position') } @@ -310,46 +237,24 @@ class Bucket { } } - /** - * @param {number} index - * @returns {BucketChild | Bucket | undefined} - */ - _at (index) { + _at (index:number ) { return this._children.get(index) } } -/** - * @param {any} o - */ -function exists (o) { +function exists (o: any) { return Boolean(o) } -/** - * - * @param {*} node - * @param {number} index - */ -function mapNode (node, index) { +function mapNode (node: any, _: number) { return node.key } -/** - * @param {*} nodes - */ -function reduceNodes (nodes) { +function reduceNodes (nodes: any) { return nodes } -/** - * @template T - * - * @param {Bucket} bucket - * @param {(value: BucketChild) => Promise} asyncMap - * @param {(reduced: any) => Promise} asyncReduce - */ -async function asyncTransformBucket (bucket, asyncMap, asyncReduce) { +async function asyncTransformBucket (bucket: Bucket, asyncMap: (value: BucketChild) => Promise, asyncReduce: (reduced: any) => Promise) { const output = [] for (const child of bucket._children.compactArray()) { @@ -368,4 +273,4 @@ async function asyncTransformBucket (bucket, asyncMap, asyncReduce) { return asyncReduce(output) } -module.exports = Bucket +export default Bucket diff --git a/src/consumable-buffer.js b/src/consumable-buffer.ts similarity index 76% rename from src/consumable-buffer.js rename to src/consumable-buffer.ts index b52566a..734c746 100644 --- a/src/consumable-buffer.js +++ b/src/consumable-buffer.ts @@ -1,5 +1,3 @@ -'use strict' - const START_MASKS = [ 0b11111111, 0b11111110, @@ -22,11 +20,12 @@ const STOP_MASKS = [ 0b11111111 ] -module.exports = class ConsumableBuffer { - /** - * @param {Uint8Array} value - */ - constructor (value) { +export default class ConsumableBuffer { + _value: Uint8Array + _currentBytePos: number + _currentBitPos: number + + constructor (value: Uint8Array) { this._value = value this._currentBytePos = value.length - 1 this._currentBitPos = 7 @@ -40,10 +39,7 @@ module.exports = class ConsumableBuffer { return this._value.length * 8 } - /** - * @param {number} bits - */ - take (bits) { + take (bits: number) { let pendingBits = bits let result = 0 while (pendingBits && this._haveBits()) { @@ -65,10 +61,7 @@ module.exports = class ConsumableBuffer { return result } - /** - * @param {number} bits - */ - untake (bits) { + untake (bits: number) { this._currentBitPos += bits while (this._currentBitPos > 7) { this._currentBitPos -= 8 @@ -81,20 +74,11 @@ module.exports = class ConsumableBuffer { } } -/** - * @param {number} byte - * @param {number} start - * @param {number} length - */ -function byteBitsToInt (byte, start, length) { +function byteBitsToInt (byte: number, start: number, length: number) { const mask = maskFor(start, length) return (byte & mask) >>> start } -/** - * @param {number} start - * @param {number} length - */ -function maskFor (start, length) { +function maskFor (start: number, length: number) { return START_MASKS[start] & STOP_MASKS[Math.min(length + start - 1, 7)] } diff --git a/src/consumable-hash.js b/src/consumable-hash.ts similarity index 73% rename from src/consumable-hash.js rename to src/consumable-hash.ts index f922686..3b00dae 100644 --- a/src/consumable-hash.js +++ b/src/consumable-hash.ts @@ -1,16 +1,8 @@ -'use strict' - -const ConsumableBuffer = require('./consumable-buffer') -const { concat: uint8ArrayConcat } = require('uint8arrays/concat') - -/** - * @param {(value: Uint8Array) => Promise} hashFn - */ -function wrapHash (hashFn) { - /** - * @param {InfiniteHash | Uint8Array} value - */ - function hashing (value) { +import ConsumableBuffer from './consumable-buffer.js' +import { concat as uint8ArrayConcat } from 'uint8arrays/concat' + +function wrapHash (hashFn: (value: Uint8Array) => Promise) { + function hashing (value: InfiniteHash | Uint8Array) { if (value instanceof InfiniteHash) { // already a hash. return it return value @@ -23,12 +15,14 @@ function wrapHash (hashFn) { } class InfiniteHash { - /** - * - * @param {Uint8Array} value - * @param {(value: Uint8Array) => Promise} hashFn - */ - constructor (value, hashFn) { + _value: Uint8Array + _hashFn: (value: Uint8Array) => Promise + _depth: number + _availableBits: number + _currentBufferIndex: number + _buffers: ConsumableBuffer[] + + constructor (value: Uint8Array, hashFn: (value: Uint8Array) => Promise) { if (!(value instanceof Uint8Array)) { throw new Error('can only hash Uint8Arrays') } @@ -38,15 +32,10 @@ class InfiniteHash { this._depth = -1 this._availableBits = 0 this._currentBufferIndex = 0 - - /** @type {ConsumableBuffer[]} */ this._buffers = [] } - /** - * @param {number} bits - */ - async take (bits) { + async take (bits: number) { let pendingBits = bits while (this._availableBits < pendingBits) { @@ -71,10 +60,7 @@ class InfiniteHash { return result } - /** - * @param {number} bits - */ - untake (bits) { + untake (bits: number) { let pendingBits = bits while (pendingBits > 0) { @@ -103,5 +89,5 @@ class InfiniteHash { } } -module.exports = wrapHash -module.exports.InfiniteHash = InfiniteHash +export default wrapHash +export { InfiniteHash } diff --git a/src/index.js b/src/index.js deleted file mode 100644 index eac625d..0000000 --- a/src/index.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -const Bucket = require('./bucket') -const wrapHash = require('./consumable-hash') - -/** - * @typedef {object} UserBucketOptions - * @property {(value: Uint8Array) => Promise} hashFn - * @property {number} [bits=8] - */ - -/** - * @param {UserBucketOptions} options - */ -function createHAMT (options) { - if (!options || !options.hashFn) { - throw new Error('please define an options.hashFn') - } - - const bucketOptions = { - bits: options.bits || 8, - hash: wrapHash(options.hashFn) - } - - return new Bucket(bucketOptions) -} - -module.exports = { - createHAMT, - Bucket -} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..470d599 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,25 @@ +import Bucket from './bucket.js' +import wrapHash from './consumable-hash.js' + +interface UserBucketOptions { + hashFn: (value: Uint8Array) => Promise + bits?: number +} + +function createHAMT (options: UserBucketOptions) { + if (!options || !options.hashFn) { + throw new Error('please define an options.hashFn') + } + + const bucketOptions = { + bits: options.bits || 8, + hash: wrapHash(options.hashFn) + } + + return new Bucket(bucketOptions) +} + +export { + createHAMT, + Bucket +} diff --git a/test/browser.js b/test/browser.js deleted file mode 100644 index 42331e1..0000000 --- a/test/browser.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict' - -require('./node') diff --git a/test/browser.ts b/test/browser.ts new file mode 100644 index 0000000..4640a0e --- /dev/null +++ b/test/browser.ts @@ -0,0 +1 @@ +import './node.js' diff --git a/test/hamt-consumable-buffer.spec.js b/test/hamt-consumable-buffer.spec.ts similarity index 93% rename from test/hamt-consumable-buffer.spec.js rename to test/hamt-consumable-buffer.spec.ts index fe7b2bc..ac81976 100644 --- a/test/hamt-consumable-buffer.spec.js +++ b/test/hamt-consumable-buffer.spec.ts @@ -1,13 +1,10 @@ /* eslint-env mocha */ -'use strict' +import { expect } from 'aegir/utils/chai.js' -const { expect } = require('aegir/utils/chai') - -const ConsumableBuffer = require('../src/consumable-buffer') +import ConsumableBuffer from '../src/consumable-buffer.js' describe('HAMT: consumable buffer', () => { - /** @type {ConsumableBuffer} */ - let buf + let buf: ConsumableBuffer it('can create an empty one', () => { buf = new ConsumableBuffer(Uint8Array.from([])) diff --git a/test/hamt-consumable-hash.spec.js b/test/hamt-consumable-hash.spec.ts similarity index 76% rename from test/hamt-consumable-hash.spec.js rename to test/hamt-consumable-hash.spec.ts index 2671bb4..53eafae 100644 --- a/test/hamt-consumable-hash.spec.js +++ b/test/hamt-consumable-hash.spec.ts @@ -1,20 +1,13 @@ /* eslint-env mocha */ -'use strict' +import { expect } from 'aegir/utils/chai.js' +import multihashing from 'multihashing-async' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' -const { expect } = require('aegir/utils/chai') -const multihashing = require('multihashing-async') -const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') - -const wrapHash = require('../src/consumable-hash') - -/** - * @typedef {import('../src/consumable-hash').InfiniteHash} InfiniteHash - */ +import wrapHash, { InfiniteHash } from '../src/consumable-hash.js' describe('HAMT: consumable hash', () => { const val = uint8ArrayFromString('some value') - /** @type {(value: Uint8Array | InfiniteHash) => InfiniteHash} */ - let hash + let hash: (value: Uint8Array | InfiniteHash) => InfiniteHash beforeEach(() => { hash = wrapHash(hashFn) @@ -26,7 +19,7 @@ describe('HAMT: consumable hash', () => { hash(1) throw new Error('Should have refused to hash value') - } catch (err) { + } catch (err: any) { expect(err.message).to.include('can only hash Uint8Arrays') } }) @@ -86,10 +79,7 @@ describe('HAMT: consumable hash', () => { }) }) -/** - * @param {string | Uint8Array} value - */ -async function hashFn (value) { +async function hashFn (value: string | Uint8Array) { const multihash = await multihashing(value instanceof Uint8Array ? value : uint8ArrayFromString(value), 'sha2-256') // remove the multihash identifier diff --git a/test/hamt.spec.js b/test/hamt.spec.ts similarity index 85% rename from test/hamt.spec.js rename to test/hamt.spec.ts index 7828c15..12a3b14 100644 --- a/test/hamt.spec.js +++ b/test/hamt.spec.ts @@ -1,22 +1,12 @@ /* eslint-env mocha */ -'use strict' +import { expect } from 'aegir/utils/chai.js' +import multihashing from 'multihashing-async' +import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' +import length from 'it-length' -const { expect } = require('aegir/utils/chai') -const multihashing = require('multihashing-async') -const { fromString: uint8ArrayFromString } = require('uint8arrays/from-string') -const length = require('it-length') +import { createHAMT, Bucket } from '../src/index.js' -const { createHAMT } = require('..') - -/** - * @template T - * @typedef {import('../src').Bucket} Bucket - */ - -/** - * @param {string | Uint8Array} value - */ -const hashFn = async function (value) { +const hashFn = async function (value: string | Uint8Array) { const multihash = await multihashing(value instanceof Uint8Array ? value : uint8ArrayFromString(value), 'sha2-256') // remove the multihash identifier @@ -29,8 +19,7 @@ const options = { describe('HAMT', () => { describe('basic', () => { - /** @type {Bucket} */ - let bucket + let bucket: Bucket beforeEach(() => { bucket = createHAMT(options) @@ -42,7 +31,7 @@ describe('HAMT', () => { createHAMT() throw new Error('Should have required a hash function') - } catch (err) { + } catch (err: any) { expect(err.message).to.include('please define an options.hashFn') } }) @@ -53,7 +42,7 @@ describe('HAMT', () => { createHAMT({}) throw new Error('Should have required a hash function') - } catch (err) { + } catch (err: any) { expect(err.message).to.include('please define an options.hashFn') } }) @@ -149,8 +138,7 @@ describe('HAMT', () => { }) describe('many keys', () => { - /** @type {Bucket} */ - let bucket + let bucket: Bucket beforeEach(() => { bucket = createHAMT(options) @@ -200,8 +188,7 @@ describe('HAMT', () => { }) describe('exhausting hash', () => { - /** @type {Bucket} */ - let bucket + let bucket: Bucket beforeEach(() => { bucket = createHAMT({ @@ -214,21 +201,14 @@ describe('HAMT', () => { await insertKeys(400, bucket) }) - /** - * @param {string | Uint8Array} value - */ - async function smallHashFn (value) { + async function smallHashFn (value: string | Uint8Array) { const hash = await hashFn(value) return hash.slice(0, 2) // just return the 2 first bytes of the hash } }) }) -/** - * @param {number} count - * @param {Bucket} bucket - */ -async function insertKeys (count, bucket) { +async function insertKeys (count: number, bucket: Bucket) { const keys = Array.from({ length: count }, (_, i) => i.toString()) for (const key of keys) { diff --git a/test/node.js b/test/node.js deleted file mode 100644 index 2114512..0000000 --- a/test/node.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict' - -require('./hamt.spec') -require('./hamt-consumable-buffer.spec') -require('./hamt-consumable-hash.spec') diff --git a/test/node.ts b/test/node.ts new file mode 100644 index 0000000..bdceee7 --- /dev/null +++ b/test/node.ts @@ -0,0 +1,3 @@ +import './hamt.spec.js' +import './hamt-consumable-buffer.spec.js' +import './hamt-consumable-hash.spec.js' diff --git a/tsconfig.json b/tsconfig.json index 108d285..f296f99 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "emitDeclarationOnly": false, + "module": "ES2020" }, "include": [ "src", From 455e46caf33c1678fa8451558614f48c08eacef7 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 14:53:22 +0000 Subject: [PATCH 2/7] fix: prepare script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da999b8..ce0bf5c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "scripts": { "pretest": "npm run build", "test": "aegir test -f ./dist/test/*.js", - "prepare": "aegir build --no-bundle", + "prepare": "npm run build", "lint": "aegir ts -p check && aegir lint", "release": "aegir release", "release-minor": "aegir release --type minor", From 49089d76981c7ad80140f2d55d435ee9f09cbf5d Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 15:02:08 +0000 Subject: [PATCH 3/7] refactor: no default exports --- src/bucket.ts | 4 +--- src/consumable-buffer.ts | 2 +- src/consumable-hash.ts | 9 +++------ src/index.ts | 11 ++++------- test/hamt-consumable-buffer.spec.ts | 2 +- test/hamt-consumable-hash.spec.ts | 2 +- 6 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/bucket.ts b/src/bucket.ts index 6950a8a..f70f9ab 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -32,7 +32,7 @@ interface BucketOptions { hash: (value: Uint8Array | InfiniteHash) => InfiniteHash } -class Bucket { +export class Bucket { _options: BucketOptions _popCount: number _parent?: Bucket @@ -272,5 +272,3 @@ async function asyncTransformBucket (bucket: Bucket, asyncMap: (value: Buc return asyncReduce(output) } - -export default Bucket diff --git a/src/consumable-buffer.ts b/src/consumable-buffer.ts index 734c746..deb2a0a 100644 --- a/src/consumable-buffer.ts +++ b/src/consumable-buffer.ts @@ -20,7 +20,7 @@ const STOP_MASKS = [ 0b11111111 ] -export default class ConsumableBuffer { +export class ConsumableBuffer { _value: Uint8Array _currentBytePos: number _currentBitPos: number diff --git a/src/consumable-hash.ts b/src/consumable-hash.ts index 3b00dae..5cfc36a 100644 --- a/src/consumable-hash.ts +++ b/src/consumable-hash.ts @@ -1,7 +1,7 @@ -import ConsumableBuffer from './consumable-buffer.js' +import { ConsumableBuffer } from './consumable-buffer.js' import { concat as uint8ArrayConcat } from 'uint8arrays/concat' -function wrapHash (hashFn: (value: Uint8Array) => Promise) { +export function wrapHash (hashFn: (value: Uint8Array) => Promise) { function hashing (value: InfiniteHash | Uint8Array) { if (value instanceof InfiniteHash) { // already a hash. return it @@ -14,7 +14,7 @@ function wrapHash (hashFn: (value: Uint8Array) => Promise) { return hashing } -class InfiniteHash { +export class InfiniteHash { _value: Uint8Array _hashFn: (value: Uint8Array) => Promise _depth: number @@ -88,6 +88,3 @@ class InfiniteHash { this._availableBits += buffer.availableBits() } } - -export default wrapHash -export { InfiniteHash } diff --git a/src/index.ts b/src/index.ts index 470d599..dde1d90 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,12 @@ -import Bucket from './bucket.js' -import wrapHash from './consumable-hash.js' +import { Bucket } from './bucket.js' +import { wrapHash } from './consumable-hash.js' interface UserBucketOptions { hashFn: (value: Uint8Array) => Promise bits?: number } -function createHAMT (options: UserBucketOptions) { +export function createHAMT (options: UserBucketOptions) { if (!options || !options.hashFn) { throw new Error('please define an options.hashFn') } @@ -19,7 +19,4 @@ function createHAMT (options: UserBucketOptions) { return new Bucket(bucketOptions) } -export { - createHAMT, - Bucket -} +export { Bucket } diff --git a/test/hamt-consumable-buffer.spec.ts b/test/hamt-consumable-buffer.spec.ts index ac81976..8a85bf8 100644 --- a/test/hamt-consumable-buffer.spec.ts +++ b/test/hamt-consumable-buffer.spec.ts @@ -1,7 +1,7 @@ /* eslint-env mocha */ import { expect } from 'aegir/utils/chai.js' -import ConsumableBuffer from '../src/consumable-buffer.js' +import { ConsumableBuffer } from '../src/consumable-buffer.js' describe('HAMT: consumable buffer', () => { let buf: ConsumableBuffer diff --git a/test/hamt-consumable-hash.spec.ts b/test/hamt-consumable-hash.spec.ts index 53eafae..d12ae30 100644 --- a/test/hamt-consumable-hash.spec.ts +++ b/test/hamt-consumable-hash.spec.ts @@ -3,7 +3,7 @@ import { expect } from 'aegir/utils/chai.js' import multihashing from 'multihashing-async' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' -import wrapHash, { InfiniteHash } from '../src/consumable-hash.js' +import { wrapHash, InfiniteHash } from '../src/consumable-hash.js' describe('HAMT: consumable hash', () => { const val = uint8ArrayFromString('some value') From 004d7801c5a9bd59f88ca3441eab0ef8fbcbe929 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 15:02:46 +0000 Subject: [PATCH 4/7] fix: do not buffer iterable --- src/bucket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bucket.ts b/src/bucket.ts index f70f9ab..7832463 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -98,7 +98,7 @@ export class Bucket { for (const child of children) { if (child instanceof Bucket) { - yield * Array.from(child.eachLeafSeries()) + yield * child.eachLeafSeries() } else { yield child } From 1a619c1f64aeacefb6a27226915fe0abf24ecf4c Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 15:03:57 +0000 Subject: [PATCH 5/7] fix: formatting --- src/bucket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bucket.ts b/src/bucket.ts index 7832463..2179b24 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -237,7 +237,7 @@ export class Bucket { } } - _at (index:number ) { + _at (index: number) { return this._children.get(index) } } From 0dfa6d92a9a9241e39dbb155a0cabfac561479db Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 15:06:06 +0000 Subject: [PATCH 6/7] feat: add files property to filter tests from npm bundle --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index ce0bf5c..3039ce6 100644 --- a/package.json +++ b/package.json @@ -54,5 +54,8 @@ "dist/src/*/index" ] } - } + }, + "files": [ + "dist/src" + ] } From 5296a22192c6492851da9448894bcc62037e34ab Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Thu, 9 Dec 2021 15:17:12 +0000 Subject: [PATCH 7/7] docs: update docs to use ESM --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 68cc58d..245bdce 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ ### Example ```javascript -const { createHAMT } = require('hamt-sharding') -const crypto = require('crypto-promise') +import { createHAMT } from 'hamt-sharding' +import crypto from 'crypto-promise' // decide how to hash buffers made from keys, can return a Promise const hashFn = async (buf) => { @@ -76,13 +76,13 @@ const output = await bucket.get('key') ## API ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' ``` ### `bucket.put(key, value)` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) await bucket.put('key', 'value') @@ -91,7 +91,7 @@ await bucket.put('key', 'value') ### `bucket.get(key)` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) await bucket.put('key', 'value') @@ -102,7 +102,7 @@ console.info(await bucket.get('key')) // 'value' ### `bucket.del(key)` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) await bucket.put('key', 'value') @@ -114,7 +114,7 @@ console.info(await bucket.get('key')) // undefined ### `bucket.leafCount()` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) console.info(bucket.leafCount()) // 0 @@ -127,7 +127,7 @@ console.info(bucket.leafCount()) // 1 ### `bucket.childrenCount()` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) console.info(bucket.childrenCount()) // 0 @@ -141,7 +141,7 @@ console.info(bucket.childrenCount()) // 234 -- dependent on hashing algorithm ### `bucket.eachLeafSeries()` ```javascript -const { createHAMT } = require('hamt-sharding') +import { createHAMT } from 'hamt-sharding' const bucket = createHAMT({...}) await bucket.put('key', 'value')