Add comprehensive installation and setup documentation

- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
This commit is contained in:
Dorian
2026-01-27 17:18:21 +00:00
parent a81f655133
commit 0d073fa89e
22658 changed files with 4494151 additions and 6 deletions
File diff suppressed because one or more lines are too long
+57
View File
@@ -0,0 +1,57 @@
import type { InfiniteHash } from './consumable-hash.js';
export interface BucketChild<V> {
key: string;
value: V;
hash: InfiniteHash;
}
interface SA<B> {
length: number;
compactArray(): B[];
get(i: number): B;
set(i: number, value: B): void;
reduce<A>(fn: (acc: A, curr: B, index: number) => A, initial: A): B;
find(fn: (item: B) => boolean): B | undefined;
bitField(): number[];
unset(i: number): void;
}
export interface BucketPosition<T> {
bucket: Bucket<T>;
pos: number;
hash: InfiniteHash;
existingChild?: BucketChild<T>;
}
export interface BucketOptions {
bits: number;
hash(value: Uint8Array | InfiniteHash): InfiniteHash;
}
export declare class Bucket<T> {
_options: BucketOptions;
_popCount: number;
_parent?: Bucket<T>;
_posAtParent: number;
_children: SA<Bucket<T> | BucketChild<T>>;
key: string | null;
constructor(options: BucketOptions, parent?: Bucket<T>, posAtParent?: number);
put(key: string, value: T): Promise<void>;
get(key: string): Promise<T | undefined>;
del(key: string): Promise<void>;
leafCount(): number;
childrenCount(): number;
onlyChild(): Bucket<T> | BucketChild<T>;
eachLeafSeries(): Iterable<BucketChild<T>>;
serialize<M>(map: (value: BucketChild<T>, index: number) => M, reduce: (reduced: Bucket<T> | BucketChild<T>) => M): M;
asyncTransform<R = T>(asyncMap: (value: BucketChild<T>) => Promise<T[]>, asyncReduce: (reduced: any) => Promise<R>): Promise<R>;
toJSON(): Record<string, any>;
prettyPrint(): string;
tableSize(): number;
_findChild(key: string): Promise<BucketChild<T> | undefined>;
_findPlace(key: string | InfiniteHash): Promise<BucketPosition<T>>;
_findNewBucketAndPos(key: string | InfiniteHash): Promise<BucketPosition<T>>;
_putAt(place: BucketPosition<T>, key: string, value: T): void;
_putObjectAt(pos: number, object: Bucket<T> | BucketChild<T>): void;
_delAt(pos: number): void;
_level(): void;
_at(index: number): Bucket<T> | BucketChild<T>;
}
export {};
//# sourceMappingURL=bucket.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"bucket.d.ts","sourceRoot":"","sources":["../../src/bucket.ts"],"names":[],"mappings":"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"}
+202
View File
@@ -0,0 +1,202 @@
// @ts-expect-error no types
import SparseArray from 'sparse-array';
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
export class Bucket {
_options;
_popCount;
_parent;
_posAtParent;
_children;
key;
constructor(options, parent, posAtParent = 0) {
this._options = options;
this._popCount = 0;
this._parent = parent;
this._posAtParent = posAtParent;
this._children = new SparseArray();
this.key = null;
}
async put(key, value) {
const place = await this._findNewBucketAndPos(key);
place.bucket._putAt(place, key, value);
}
async get(key) {
const child = await this._findChild(key);
if (child != null) {
return child.value;
}
}
async del(key) {
const place = await this._findPlace(key);
const child = place.bucket._at(place.pos);
if (child != null && child.key === key) {
place.bucket._delAt(place.pos);
}
}
leafCount() {
const children = this._children.compactArray();
return children.reduce((acc, child) => {
if (child instanceof Bucket) {
return acc + child.leafCount();
}
return acc + 1;
}, 0);
}
childrenCount() {
return this._children.length;
}
onlyChild() {
return this._children.get(0);
}
*eachLeafSeries() {
const children = this._children.compactArray();
for (const child of children) {
if (child instanceof Bucket) {
yield* child.eachLeafSeries();
}
else {
yield child;
}
}
}
serialize(map, reduce) {
const acc = [];
// serialize to a custom non-sparse representation
return reduce(this._children.reduce((acc, child, index) => {
if (child != null) {
if (child instanceof Bucket) {
acc.push(child.serialize(map, reduce));
}
else {
acc.push(map(child, index));
}
}
return acc;
}, acc));
}
async asyncTransform(asyncMap, asyncReduce) {
return asyncTransformBucket(this, asyncMap, asyncReduce);
}
toJSON() {
return this.serialize(mapNode, reduceNodes);
}
prettyPrint() {
return JSON.stringify(this.toJSON(), null, ' ');
}
tableSize() {
return Math.pow(2, this._options.bits);
}
async _findChild(key) {
const result = await this._findPlace(key);
const child = result.bucket._at(result.pos);
if (child instanceof Bucket) {
// should not be possible, this._findPlace should always
// return a location for a child, not a bucket
return undefined;
}
if (child != null && child.key === key) {
return child;
}
}
async _findPlace(key) {
const hashValue = this._options.hash(typeof key === 'string' ? uint8ArrayFromString(key) : key);
const index = await hashValue.take(this._options.bits);
const child = this._children.get(index);
if (child instanceof Bucket) {
return child._findPlace(hashValue);
}
return {
bucket: this,
pos: index,
hash: hashValue,
existingChild: child
};
}
async _findNewBucketAndPos(key) {
const place = await this._findPlace(key);
if ((place.existingChild != null) && place.existingChild.key !== key) {
// conflict
const bucket = new Bucket(this._options, place.bucket, place.pos);
place.bucket._putObjectAt(place.pos, bucket);
// put the previous value
const newPlace = await bucket._findPlace(place.existingChild.hash);
newPlace.bucket._putAt(newPlace, place.existingChild.key, place.existingChild.value);
return bucket._findNewBucketAndPos(place.hash);
}
// no conflict, we found the place
return place;
}
_putAt(place, key, value) {
this._putObjectAt(place.pos, {
key,
value,
hash: place.hash
});
}
_putObjectAt(pos, object) {
if (this._children.get(pos) == null) {
this._popCount++;
}
this._children.set(pos, object);
}
_delAt(pos) {
if (pos === -1) {
throw new Error('Invalid position');
}
if (this._children.get(pos) != null) {
this._popCount--;
}
this._children.unset(pos);
this._level();
}
_level() {
if (this._parent != null && this._popCount <= 1) {
if (this._popCount === 1) {
// remove myself from parent, replacing me with my only child
const onlyChild = this._children.find(exists);
if ((onlyChild != null) && !(onlyChild instanceof Bucket)) {
const hash = onlyChild.hash;
hash.untake(this._options.bits);
const place = {
pos: this._posAtParent,
hash,
bucket: this._parent
};
this._parent._putAt(place, onlyChild.key, onlyChild.value);
}
}
else {
this._parent._delAt(this._posAtParent);
}
}
}
_at(index) {
return this._children.get(index);
}
}
function exists(o) {
return Boolean(o);
}
function mapNode(node, _) {
return node.key;
}
function reduceNodes(nodes) {
return nodes;
}
async function asyncTransformBucket(bucket, asyncMap, asyncReduce) {
const output = [];
for (const child of bucket._children.compactArray()) {
if (child instanceof Bucket) {
await asyncTransformBucket(child, asyncMap, asyncReduce);
}
else {
const mappedChildren = await asyncMap(child);
output.push({
bitField: bucket._children.bitField(),
children: mappedChildren
});
}
}
return asyncReduce(output);
}
//# sourceMappingURL=bucket.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
export declare class ConsumableBuffer {
_value: Uint8Array;
_currentBytePos: number;
_currentBitPos: number;
constructor(value: Uint8Array);
availableBits(): number;
totalBits(): number;
take(bits: number): number;
untake(bits: number): void;
_haveBits(): boolean;
}
//# sourceMappingURL=consumable-buffer.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"consumable-buffer.d.ts","sourceRoot":"","sources":["../../src/consumable-buffer.ts"],"names":[],"mappings":"AAsBA,qBAAa,gBAAgB;IAC3B,MAAM,EAAE,UAAU,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;gBAET,KAAK,EAAE,UAAU;IAM9B,aAAa,IAAK,MAAM;IAIxB,SAAS,IAAK,MAAM;IAIpB,IAAI,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAsB3B,MAAM,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ3B,SAAS,IAAK,OAAO;CAGtB"}
+72
View File
@@ -0,0 +1,72 @@
const START_MASKS = [
0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000
];
const STOP_MASKS = [
0b00000001,
0b00000011,
0b00000111,
0b00001111,
0b00011111,
0b00111111,
0b01111111,
0b11111111
];
export class ConsumableBuffer {
_value;
_currentBytePos;
_currentBitPos;
constructor(value) {
this._value = value;
this._currentBytePos = value.length - 1;
this._currentBitPos = 7;
}
availableBits() {
return this._currentBitPos + 1 + this._currentBytePos * 8;
}
totalBits() {
return this._value.length * 8;
}
take(bits) {
let pendingBits = bits;
let result = 0;
while (pendingBits > 0 && this._haveBits()) {
const byte = this._value[this._currentBytePos];
const availableBits = this._currentBitPos + 1;
const taking = Math.min(availableBits, pendingBits);
const value = byteBitsToInt(byte, availableBits - taking, taking);
result = (result << taking) + value;
pendingBits -= taking;
this._currentBitPos -= taking;
if (this._currentBitPos < 0) {
this._currentBitPos = 7;
this._currentBytePos--;
}
}
return result;
}
untake(bits) {
this._currentBitPos += bits;
while (this._currentBitPos > 7) {
this._currentBitPos -= 8;
this._currentBytePos += 1;
}
}
_haveBits() {
return this._currentBytePos >= 0;
}
}
function byteBitsToInt(byte, start, length) {
const mask = maskFor(start, length);
return (byte & mask) >>> start;
}
function maskFor(start, length) {
return START_MASKS[start] & STOP_MASKS[Math.min(length + start - 1, 7)];
}
//# sourceMappingURL=consumable-buffer.js.map
@@ -0,0 +1 @@
{"version":3,"file":"consumable-buffer.js","sourceRoot":"","sources":["../../src/consumable-buffer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAClB,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;CACX,CAAA;AAED,MAAM,UAAU,GAAG;IACjB,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;IACV,UAAU;CACX,CAAA;AAED,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAY;IAClB,eAAe,CAAQ;IACvB,cAAc,CAAQ;IAEtB,YAAa,KAAiB;QAC5B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QACvC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,cAAc,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC3D,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,CAAE,IAAY;QAChB,IAAI,WAAW,GAAG,IAAI,CAAA;QACtB,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,OAAO,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;YAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,CAAA;YAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAA;YACnD,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,EAAE,MAAM,CAAC,CAAA;YACjE,MAAM,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,CAAA;YAEnC,WAAW,IAAI,MAAM,CAAA;YAErB,IAAI,CAAC,cAAc,IAAI,MAAM,CAAA;YAC7B,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC,cAAc,GAAG,CAAC,CAAA;gBACvB,IAAI,CAAC,eAAe,EAAE,CAAA;YACxB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED,MAAM,CAAE,IAAY;QAClB,IAAI,CAAC,cAAc,IAAI,IAAI,CAAA;QAC3B,OAAO,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,IAAI,CAAC,CAAA;YACxB,IAAI,CAAC,eAAe,IAAI,CAAC,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,eAAe,IAAI,CAAC,CAAA;IAClC,CAAC;CACF;AAED,SAAS,aAAa,CAAE,IAAY,EAAE,KAAa,EAAE,MAAc;IACjE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACnC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,CAAA;AAChC,CAAC;AAED,SAAS,OAAO,CAAE,KAAa,EAAE,MAAc;IAC7C,OAAO,WAAW,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACzE,CAAC"}
+15
View File
@@ -0,0 +1,15 @@
import { ConsumableBuffer } from './consumable-buffer.js';
export declare function wrapHash(hashFn: (value: Uint8Array) => Promise<Uint8Array>): (value: InfiniteHash | Uint8Array) => InfiniteHash;
export declare class InfiniteHash {
_value: Uint8Array;
_hashFn: (value: Uint8Array) => Promise<Uint8Array>;
_depth: number;
_availableBits: number;
_currentBufferIndex: number;
_buffers: ConsumableBuffer[];
constructor(value: Uint8Array, hashFn: (value: Uint8Array) => Promise<Uint8Array>);
take(bits: number): Promise<number>;
untake(bits: number): void;
_produceMoreBits(): Promise<void>;
}
//# sourceMappingURL=consumable-hash.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"consumable-hash.d.ts","sourceRoot":"","sources":["../../src/consumable-hash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAEzD,wBAAgB,QAAQ,CAAE,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,KAAK,YAAY,CAWhI;AAED,qBAAa,YAAY;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACnD,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,QAAQ,EAAE,gBAAgB,EAAE,CAAA;gBAEf,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC;IAa5E,IAAI,CAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB1C,MAAM,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAiBrB,gBAAgB,IAAK,OAAO,CAAC,IAAI,CAAC;CAUzC"}
+75
View File
@@ -0,0 +1,75 @@
import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
import { ConsumableBuffer } from './consumable-buffer.js';
export function wrapHash(hashFn) {
function hashing(value) {
if (value instanceof InfiniteHash) {
// already a hash. return it
return value;
}
else {
return new InfiniteHash(value, hashFn);
}
}
return hashing;
}
export class InfiniteHash {
_value;
_hashFn;
_depth;
_availableBits;
_currentBufferIndex;
_buffers;
constructor(value, hashFn) {
if (!(value instanceof Uint8Array)) {
throw new Error('can only hash Uint8Arrays');
}
this._value = value;
this._hashFn = hashFn;
this._depth = -1;
this._availableBits = 0;
this._currentBufferIndex = 0;
this._buffers = [];
}
async take(bits) {
let pendingBits = bits;
while (this._availableBits < pendingBits) {
await this._produceMoreBits();
}
let result = 0;
while (pendingBits > 0) {
const hash = this._buffers[this._currentBufferIndex];
const available = Math.min(hash.availableBits(), pendingBits);
const took = hash.take(available);
result = (result << available) + took;
pendingBits -= available;
this._availableBits -= available;
if (hash.availableBits() === 0) {
this._currentBufferIndex++;
}
}
return result;
}
untake(bits) {
let pendingBits = bits;
while (pendingBits > 0) {
const hash = this._buffers[this._currentBufferIndex];
const availableForUntake = Math.min(hash.totalBits() - hash.availableBits(), pendingBits);
hash.untake(availableForUntake);
pendingBits -= availableForUntake;
this._availableBits += availableForUntake;
if (this._currentBufferIndex > 0 && hash.totalBits() === hash.availableBits()) {
this._depth--;
this._currentBufferIndex--;
}
}
}
async _produceMoreBits() {
this._depth++;
const value = this._depth > 0 ? uint8ArrayConcat([this._value, Uint8Array.from([this._depth])]) : this._value;
const hashValue = await this._hashFn(value);
const buffer = new ConsumableBuffer(hashValue);
this._buffers.push(buffer);
this._availableBits += buffer.availableBits();
}
}
//# sourceMappingURL=consumable-hash.js.map
@@ -0,0 +1 @@
{"version":3,"file":"consumable-hash.js","sourceRoot":"","sources":["../../src/consumable-hash.ts"],"names":[],"mappings":"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"}
+41
View File
@@ -0,0 +1,41 @@
/**
* @packageDocumentation
*
* A [Hash Mapped Trie](https://en.wikipedia.org/wiki/Hash_array_mapped_trie) implementation for JavaScript.
*
* This is used by [@helia/unixfs](https://www.npmjs.com/package/@helia/unixfs) for it's HAMT-sharded directory implementation.
*
* @example
*
* ```TypeScript
* 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) => {
* return crypto
* .createHash('sha256')
* .update(buf)
* .digest()
* }
*
* const bucket = createHAMT({
* hashFn: hashFn
* })
*
* await bucket.put('key', 'value')
*
* const output = await bucket.get('key')
* // output === 'value'
* ```
*/
import { Bucket } from './bucket.js';
import type { BucketOptions, BucketPosition, BucketChild } from './bucket.js';
interface UserBucketOptions {
hashFn(value: Uint8Array): Promise<Uint8Array>;
bits?: number;
}
export declare function createHAMT<T>(options: UserBucketOptions): Bucket<T>;
export { Bucket };
export type { BucketOptions, BucketPosition, BucketChild };
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE7E,UAAU,iBAAiB;IACzB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAG,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC,CAAC,CAAC,CAWpE;AAED,OAAO,EAAE,MAAM,EAAE,CAAA;AACjB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,CAAA"}
+45
View File
@@ -0,0 +1,45 @@
/**
* @packageDocumentation
*
* A [Hash Mapped Trie](https://en.wikipedia.org/wiki/Hash_array_mapped_trie) implementation for JavaScript.
*
* This is used by [@helia/unixfs](https://www.npmjs.com/package/@helia/unixfs) for it's HAMT-sharded directory implementation.
*
* @example
*
* ```TypeScript
* 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) => {
* return crypto
* .createHash('sha256')
* .update(buf)
* .digest()
* }
*
* const bucket = createHAMT({
* hashFn: hashFn
* })
*
* await bucket.put('key', 'value')
*
* const output = await bucket.get('key')
* // output === 'value'
* ```
*/
import { Bucket } from './bucket.js';
import { wrapHash } from './consumable-hash.js';
export function createHAMT(options) {
if (options == null || options.hashFn == null) {
throw new Error('please define an options.hashFn');
}
const bucketOptions = {
bits: options.bits ?? 8,
hash: wrapHash(options.hashFn)
};
return new Bucket(bucketOptions);
}
export { Bucket };
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAQ/C,MAAM,UAAU,UAAU,CAAK,OAA0B;IACvD,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC;QACvB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;KAC/B,CAAA;IAED,OAAO,IAAI,MAAM,CAAI,aAAa,CAAC,CAAA;AACrC,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,CAAA"}
+8
View File
@@ -0,0 +1,8 @@
{
"Bucket": "https://ipfs.github.io/js-hamt-sharding/classes/Bucket.html",
"BucketChild": "https://ipfs.github.io/js-hamt-sharding/interfaces/BucketChild.html",
"BucketOptions": "https://ipfs.github.io/js-hamt-sharding/interfaces/BucketOptions.html",
"BucketPosition": "https://ipfs.github.io/js-hamt-sharding/interfaces/BucketPosition.html",
"createHAMT": "https://ipfs.github.io/js-hamt-sharding/functions/createHAMT.html",
".:createHAMT": "https://ipfs.github.io/js-hamt-sharding/functions/createHAMT.html"
}