Skip to content

Instantly share code, notes, and snippets.

@alanshaw
Created March 7, 2023 15:26
Show Gist options
  • Save alanshaw/e4bf69a3c4067992101a5b2801410b30 to your computer and use it in GitHub Desktop.
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
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