Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ playwright-report
.envrc
.tool-versions
.env
examples/helia-101/2600-h.htm
100 changes: 100 additions & 0 deletions examples/helia-101/102-cid-profiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { createReadStream } from 'node:fs'
import { globSource, unixfs } from '@helia/unixfs'
import { createHelia } from 'helia'
import { fixedSize } from 'ipfs-unixfs-importer/chunker'
import { balanced } from 'ipfs-unixfs-importer/layout'


//--------------------------------set up

const helia = await createHelia()
const fs = unixfs(helia)

const bigDirectorySource = "https://sourceforge.net/projects/freetype/files/latest/download"

//--------------------------------directory inputs

// using a local copy of https://www.gutenberg.org/files/2600/2600-h/2600-h.htm , curled to this directory but not checked in
Comment thread
bumblefudge marked this conversation as resolved.
const bigHtmlFile = createReadStream('./2600-h.htm')

// generate CID according to Helia defaults (~== kubo v1 profile) from bigHtmlFile:
const cidBigHTML = await fs.addFile(

@2color 2color Mar 14, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify this by having helia download the file for you as I did in

const urlCid = await fs.addFile(urlSource(url))

https://github.com/ipfs-examples/helia-examples/pull/456/files#diff-15db2a7c59c6093dbf74da5c6c0132ad792799c35a93eabe589cf6cd00d1019dR65

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought having a local file would simplify the comparison to kubo, since i don't think the latter has a "from URL" option? this is neat, tho, maybe it makes sense to add it as a 5th example before the local-file version to show that it's the same CID between urlSource(url) and the local file curled from the same URL... i leave it to the tutorials' editor to decide!

{
path: './bigHtmlFile.htm',
//content: bigHtmlFile
}, {
wrapWithDirectory: false
}
)

console.log('bigHtmlFile test-cid-v1 profile: ', cidBigHTML.toString())
const stats = await fs.stat(cidBigHTML)
console.log('Stats:', stats)

// generate CID according to Kubo legacy-cid-v0 profile from bigHtmlFile:
const bigHtmlFile2 = createReadStream('./2600-h.htm')
const cidBigHTML2 = await fs.addFile(
{
path: './bigHtmlFile.htm',
//content: bigHtmlFile2
}, {
cidVersion: 0,
rawLeaves: false,
layout: balanced({
maxChildrenPerNode: 174
}),
chunker: fixedSize({
chunkSize: 262_144
}),
wrapWithDirectory: false
}
)

console.log('bigHtmlFile legacy-cid-v0 profile: ', cidBigHTML2.toString())
const stats2 = await fs.stat(cidBigHTML2)
console.log('Stats:', stats2)

//--------------------------------directory inputs

// big-directory populated with many small files and subdirectories to trigger
// recursive encoding, but not enough to trigger a HAMT-directory

// generate CID according to Helia defaults (~== kubo v1 profile) from a big
// directory via the globSource function (see
// https://ipfs.github.io/helia/functions/_helia_unixfs.index.globSource.html ):

for await (const entry of fs.addAll(globSource(
'./big_directory',
'**/*'
), {
wrapWithDirectory: true
}
)
){
console.log('bigDirectory test-cid-v1 profile: ', entry.cid.toString())
const stats3 = await fs.stat(entry.cid)
console.log('Stats:', stats3)
}

// generate CID according to Kubo legacy-cid-v0 profile from same directory:

for await (const entry of fs.addAll(globSource(
'./big_directory',
'**/*'
), {
cidVersion: 0,
rawLeaves: false,
layout: balanced({
maxChildrenPerNode: 256
}),
chunker: fixedSize({
chunkSize: 262_144
}),
wrapWithDirectory: true
}
)
){
console.log('bigDirectory kubo-cid-v0 profile: ', entry.cid.toString())
const stats4 = await fs.stat(entry.cid)
console.log('Stats:', stats4)
}
11 changes: 11 additions & 0 deletions examples/helia-101/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- [Running Examples](#running-examples)
- [Usage](#usage)
- [101 - Basics](#101---basics)
- [102 - CID Profiles](#102---cid-profiles)
- [201 - Storage](#201---storage)
- [Blockstore](#blockstore)
- [Datastore](#datastore)
Expand Down Expand Up @@ -89,6 +90,16 @@ To run it, use the following command:
```console
> npm run 101-basics
```
That's it! We've created a Helia node, added a file to it, and retrieved that file.

Next we will look at where the bytes that make up the file go.

### 102 - CID Profiles

The way UnixFS takes arbitrary inputs (files, folders, etc) and turns them into [DAGs](https://proto.school/merkle-dags/03) of smaller binary blocks (addressed by CID) involves a lot of tradeoffs and choices, particularly in the shape and structure of the DAG.
If you need multiple different implementations to produce the same CID for a given input, configure CID generation accordingly, matching certain configuration variables to those defined in CID profiles, like those exposed in the `ipfs config profile apply` command in kubo ([docs](https://docs.ipfs.tech/reference/kubo/cli/#ipfs-config-profile-apply)).

When experimenting with these options, it can be helpful to play with the [DAG Build](https://dag.ipfs.tech/) .

### 201 - Storage

Expand Down
5 changes: 5 additions & 0 deletions examples/helia-101/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"license": "MIT",
"scripts": {
"101-basics": "node 101-basics.js",
"102-cid-profiles": "node 102-cid-profiles.js",
"201-storage": "node 201-storage.js",
"301-networking": "node 301-networking.js",
"401-providing": "node 401-providing.js",
Expand All @@ -25,7 +26,11 @@
"datastore-core": "^10.0.2",
"datastore-fs": "^10.0.2",
"helia": "^5.3.0",
"ipfs-unixfs": "^11.2.0",
"ipfs-unixfs-exporter": "^13.6.1",
"ipfs-unixfs-importer": "^15.3.1",
"libp2p": "^2.8.2"
"multiformats": "^13.3.1"
},
"devDependencies": {
"test-ipfs-example": "^1.3.3"
Expand Down