Created
March 7, 2023 15:26
-
-
Save alanshaw/e4bf69a3c4067992101a5b2801410b30 to your computer and use it in GitHub Desktop.
Create a fixture for `@perma/map` from a CAR file containing a HAMT sharded directory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { CarIndexedReader } from '@ipld/car' | |
import * as pb from '@ipld/dag-pb' | |
import { UnixFS } from 'ipfs-unixfs' | |
// usage: node create-perma-map-fixture sharded-dir.car | |
/** @typedef {{ bitfield: number[], links: Array<Link|Element>, prefix?: string }} Link */ | |
/** @typedef {{ key: string, value: string, prefix: string }} Element */ | |
async function main () { | |
const file = process.argv[2] | |
if (!file) throw new Error('missing CAR file path') | |
const reader = await CarIndexedReader.fromFile(file) | |
const roots = await reader.getRoots() | |
if (!roots.length || roots.length > 1) throw new Error('invalid number of roots in CAR') | |
const fixture = await buildFixture(reader, roots[0]) | |
console.log(JSON.stringify(fixture, null, 2)) | |
} | |
/** | |
* @param {import('@ipld/car/api').BlockReader} reader | |
* @param {import('multiformats').CID} link | |
* @param {string} [prefix] | |
*/ | |
async function buildFixture (reader, link, prefix) { | |
const block = await reader.get(link) | |
if (!block) throw new Error(`missing block: ${link}`) | |
const node = pb.decode(block.bytes) | |
if (!node.Data) throw new Error('missing node Data') | |
/** @type {Array<Link|Element>} */ | |
const links = [] | |
for (const l of node.Links) { | |
if (!l.Name) throw new Error('link with no name') | |
const prefix = l.Name.slice(0, 2) | |
const key = l.Name.slice(2) | |
if (key) { | |
links.push({ prefix, key, value: `value(${key})` }) | |
continue | |
} | |
links.push(await buildFixture(reader, l.Hash, prefix)) | |
} | |
const data = UnixFS.unmarshal(node.Data) | |
if (data.type !== 'hamt-sharded-directory') throw new Error('expected hamt-sharded-directory type') | |
if (data.data == null) throw new Error('missing bitfield') | |
const bitfield = Array.from(data.data) | |
return { prefix, bitfield, links } | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment