|
1 | 1 | /* eslint-disable no-console */
|
| 2 | +// @ts-check |
2 | 3 |
|
3 | 4 | import { createHeliaHTTP } from '@helia/http'
|
4 |
| -import { unixfs } from '@helia/unixfs' |
| 5 | +import { unixfs, urlSource } from '@helia/unixfs' |
| 6 | +import { pipeline } from 'stream/promises' |
| 7 | +import * as nodefs from 'fs' |
| 8 | +import { devNull } from 'node:os' |
5 | 9 |
|
6 | 10 | // create a Helia node
|
7 | 11 | const helia = await createHeliaHTTP()
|
8 | 12 |
|
9 |
| -// create a filesystem on top of Helia, in this case it's UnixFS |
| 13 | +// UnixFS allows you to encode files and directories such that they are addressed by CIDs and can be retrieved by other nodes on the network |
10 | 14 | const fs = unixfs(helia)
|
11 | 15 |
|
12 |
| -// add a file and wrap in a directory |
| 16 | +// addFile always returns a directory CID, retaining the filename derived from the `path` argument |
13 | 17 | const readmeCid = await fs.addFile({
|
14 |
| - path: './README.md' |
15 |
| -}, { |
16 |
| - wrapWithDirectory: true |
| 18 | + content: nodefs.createReadStream('./README.md'), |
| 19 | + path: './README.md', |
17 | 20 | })
|
18 | 21 |
|
19 |
| -console.log('Added README.md file:', readmeCid.toString()) |
| 22 | +// stat returns a UnixFSStats object, which contains information about the file or directory |
| 23 | +const readmeStats = await fs.stat(readmeCid) |
| 24 | +console.log('README.md stats:', readmeStats) |
20 | 25 |
|
21 | 26 | // we will use this TextEncoder to turn strings into Uint8Arrays
|
22 | 27 | const encoder = new TextEncoder()
|
23 | 28 |
|
24 |
| -// add the bytes to your node and receive a unique content identifier |
| 29 | +// add the bytes and receive a raw block CID for the content because it's small enough to fit into a single block |
25 | 30 | const cid = await fs.addBytes(encoder.encode('Hello World 101'), {
|
26 | 31 | onProgress: (evt) => {
|
27 | 32 | console.info('add event', evt.type, evt.detail)
|
28 |
| - } |
| 33 | + }, |
29 | 34 | })
|
30 |
| - |
31 | 35 | console.log('Added file:', cid.toString())
|
32 | 36 |
|
33 | 37 | // this decoder will turn Uint8Arrays into strings
|
34 | 38 | const decoder = new TextDecoder()
|
35 | 39 | let text = ''
|
36 | 40 |
|
| 41 | +// Read the file into memory and print it to the console |
37 | 42 | for await (const chunk of fs.cat(cid, {
|
38 | 43 | onProgress: (evt) => {
|
39 | 44 | console.info('cat event', evt.type, evt.detail)
|
40 |
| - } |
| 45 | + }, |
41 | 46 | })) {
|
42 | 47 | text += decoder.decode(chunk, {
|
43 |
| - stream: true |
| 48 | + stream: true, |
44 | 49 | })
|
45 | 50 | }
|
46 |
| - |
47 | 51 | console.log('Added file contents:', text)
|
| 52 | + |
| 53 | +// Create an empty directory |
| 54 | +const directoryCid = await fs.addDirectory({ |
| 55 | + path: 'my-dir', |
| 56 | +}) |
| 57 | + |
| 58 | +// Add a file to the directory |
| 59 | +const updatedCid = await fs.cp(cid, directoryCid, 'hello.txt') |
| 60 | +console.log('Directory with added file:', updatedCid) |
| 61 | + |
| 62 | +// Add a file to Helia from a URL |
| 63 | +// This will download, chunk the file into smaller chunks and return a directory containing the file CID with links to the raw blocks of the file |
| 64 | +const url = 'https://www.gutenberg.org/files/2600/2600-h/2600-h.htm' |
| 65 | +const urlCid = await fs.addFile(urlSource(url)) |
| 66 | + |
| 67 | +const urlCidStats = await fs.stat(urlCid) |
| 68 | +console.log('File from URL: stats:', urlCidStats) |
| 69 | + |
| 70 | +// Helia UnixFS returns an async iterable, allowing integration with other streams |
| 71 | +// Here we use the pipeline function to pipe the stream to devNull to avoid writing to the file system |
| 72 | +try { |
| 73 | + await pipeline( |
| 74 | + fs.cat(urlCid, { |
| 75 | + path: '/2600-h.htm', |
| 76 | + }), |
| 77 | + nodefs.createWriteStream(devNull), |
| 78 | + // createWriteStream('./war_and_peace.html'), // uncomment this to write to the file system |
| 79 | + ) |
| 80 | +} catch (err) { |
| 81 | + console.error('Pipeline failed', err) |
| 82 | +} |
0 commit comments