The internal implementation for DBrowserX-'s DatArchive
APIs.
Works with Dat 2.0.
All async methods work with callbacks and promises. If no callback is provided, a promise will be returned.
Any time a dwebfs archive
is expected, a dbrowser-sfs instance can be provided, unless otherwise stated.
var dwebfs = require('dwebfs')
var ScopedFS = require('dbrowser-sfs')
var archive = dwebfs('./my-dwebfs')
var scopedfs = new ScopedFS('./my-dbrowser-sfs')
await pda.readFile(archive, '/hello.txt') // read the published hello.txt
await pda.readFile(scopedfs, '/hello.txt') // read the local hello.txt
** NOTE: this library is written natively for node 12 and above. **
- Lookup
- Read
-
Write
- writeFile(archive, name, data[, opts, cb])
- mkdir(archive, name[, cb])
- symlink(archive, target, linkname[, cb])
- copy(srcArchive, srcName, dstArchive, dstName[, cb])
- rename(srcArchive, srcName, dstName[, cb])
- updateMetadata(archive, path, metadata[, cb])
- deleteMetadata(archive, path, keys[, cb])
- createWriteStream(archive, name[, cb])
- Delete
- Mounts
- Activity Streams
- Exporters
- Manifest
- Diff
const pda = require('dbrowser-dweb-api')
-
archive
Hyperdrive archive (object). -
name
Entry name (string). -
opts.lstat
Get symlink information if target is a symlink (boolean). - Returns a Hyperdrive Stat entry (object).
- Throws NotFoundError
// by name:
var st = await pda.stat(archive, '/index.json')
st.isDirectory()
st.isFile()
console.log(st) /* =>
Stat {
dev: 0,
nlink: 1,
rdev: 0,
blksize: 0,
ino: 0,
mode: 16877,
uid: 0,
gid: 0,
size: 0,
offset: 0,
blocks: 0,
atime: 2017-04-10T18:59:00.147Z,
mtime: 2017-04-10T18:59:00.147Z,
ctime: 2017-04-10T18:59:00.147Z,
linkname: undefined } */
-
archive
Hyperdrive archive (object). -
name
Entry path (string). -
opts
. Options (object|string). If a string, will act asopts.encoding
. -
opts.encoding
Desired output encoding (string). May be 'binary', 'utf8', 'hex', 'base64', or 'json'. Default 'utf8'. - Returns the content of the file in the requested encoding.
- Throws NotFoundError.
var manifestStr = await pda.readFile(archive, '/index.json')
var manifestObj = await pda.readFile(archive, '/index.json', 'json')
var imageBase64 = await pda.readFile(archive, '/favicon.png', 'base64')
-
archive
Hyperdrive archive (object). -
path
Target directory path (string). -
opts.recursive
Read all subfolders and their files as well if true. Note: does not recurse into mounts. -
opts.includeStats
Output an object which includes the file name, stats object, and parent mount information. - Returns an array of file and folder names.
var listing = await pda.readdir(archive, '/assets')
console.log(listing) // => ['profile.png', 'styles.css']
var listing = await pda.readdir(archive, '/', { recursive: true })
console.log(listing) /* => [
'index.html',
'assets',
'assets/profile.png',
'assets/styles.css'
]*/
var listing = await pda.readdir(archive, '/', { includeStats: true })
console.log(listing) /* => [
{
name: 'profile.png',
stats: { ... },
mount: { ... }
},
...
]*/
-
archive
Hyperdrive archive (object). -
path
Target directory path (string). - Returns a number (size in bytes).
This method will recurse on folders.
var size = await pda.readSize(archive, '/assets')
console.log(size) // => 123
-
archive
Hyperdrive archive (object). -
name
Entry path (string). -
opts
. Options (object|string). If a string, will act asopts.encoding
. -
opts.start
Starting offset (number). Default 0. -
opts.end
. Ending offset inclusive (number). Default undefined. -
opts.length
. How many bytes to read (number). Default undefined. - Returns a readable stream.
- Throws NotFoundError.
pda.createReadStream(archive, '/favicon.png')
pda.createReadStream(archive, '/favicon.png', {
start: 1,
end: 3
})
-
archive
Hyperdrive archive (object). -
name
Entry path (string). -
data
Data to write (string|Buffer). -
opts
. Options (object|string). If a string, will act asopts.encoding
. -
opts.encoding
Desired file encoding (string). May be 'binary', 'utf8', 'hex', 'base64', or 'json'. Default 'utf8' ifdata
is a string, 'binary' ifdata
is a Buffer. - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError, InvalidEncodingError.
await pda.writeFile(archive, '/hello.txt', 'world', 'utf8')
await pda.writeFile(archive, '/thing.json', {hello: 'world'}, 'json')
await pda.writeFile(archive, '/profile.png', fs.readFileSync('/tmp/dog.png'))
-
archive
Hyperdrive archive (object). -
name
Directory path (string). - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError, InvalidEncodingError.
await pda.mkdir(archive, '/stuff')
-
archive
Hyperdrive archive (object). -
target
Path to symlink to (string). -
linkname
Path to create the symlink (string). - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError, InvalidEncodingError.
await pda.symlink(archive, '/hello.txt', '/goodbye.txt')
-
srcArchive
Source Hyperdrive archive (object). -
srcName
Path to file or directory to copy (string). -
dstArchive
Destination Hyperdrive archive (object). -
dstName
Where to copy the file or folder to (string). - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError, InvalidEncodingError.
// copy file:
await pda.copy(archive, '/foo.txt', archive, '/foo.txt.back')
// copy folder:
await pda.copy(archive, '/stuff', otherArchive, '/stuff')
-
srcArchive
Source Hyperdrive archive (object). -
srcName
Path to file or directory to rename (string). -
dstArchive
Destination Hyperdrive archive (object). -
dstName
What the file or folder should be named (string). - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError, InvalidEncodingError.
This is equivalent to moving a file/folder.
// move file:
await pda.rename(archive, '/foo.txt', archive, '/foo.md')
// move folder:
await pda.rename(archive, '/stuff', otherArchive, '/stuff')
-
archive
Hyperdrive archive (object). -
path
Entry path (string). -
metadata
Metadata values to set (object).
Updates the file/folder metadata. Does not overwrite all values; any existing metadata keys which are not specified in the metadata
param are preserved.
await pda.updateMetadata(archive, '/hello.txt', {foo: 'bar'})
The default encoding for metadata attributes is utf8. Attributes which start with bin:
are encoded in binary.
await pda.updateMetadata(archive, '/hello.txt', {'bin:foo': Buffer.from([1,2,3,4]})
(await pda.stat(archive, '/hello.txt')).metadata['bin:foo'] //=> Buffer([1,2,3,4])
-
archive
Hyperdrive archive (object). -
path
Entry path (string). -
keys
Metadata keys to delete (string | string[]).
await pda.deleteMetadata(archive, '/hello.txt', ['foo'])
-
archive
Hyperdrive archive (object). -
name
Entry path (string). - Throws ArchiveNotWritableError, InvalidPathError, EntryAlreadyExistsError.
await pda.createWriteStream(archive, '/hello.txt')
-
archive
Hyperdrive archive (object). -
name
Entry path (string). - Throws ArchiveNotWritableError, NotFoundError, NotAFileError
await pda.unlink(archive, '/hello.txt')
-
archive
Hyperdrive archive (object). -
name
Entry path (string). -
opts.recursive
Delete all subfolders and files if the directory is not empty. - Throws ArchiveNotWritableError, NotFoundError, NotAFolderError, DestDirectoryNotEmpty
await pda.rmdir(archive, '/stuff', {recursive: true})
-
archive
Hyperdrive archive (object). -
name
Entry path (string). -
opts
. Options (object|string). If a string or buffer, will act asopts.key
. -
opts.key
Key of archive to mount. May be a hex string or Buffer. - Throws ArchiveNotWritableError, InvalidPathError
await pda.mount(archive, '/foo', archive2.key)
-
archive
Hyperdrive archive (object). -
name
Entry path (string). - Throws ArchiveNotWritableError, InvalidPathError, NotFoundError
await pda.unmount(archive, '/foo')
-
archive
Hyperdrive archive (object). -
path
Prefix path. If falsy, will watch all files. - Returns a Readable stream.
Watches the given path for file events, which it emits as an emit-stream. Supported events:
-
['changed',{path}]
- The contents of the file has changed.path
is the path-string of the file.
var es = pda.watch(archive, 'foo.txt')
es.on('data', ([event, args]) => {
if (event === 'changed') {
console.log(args.path, 'has changed')
}
})
// alternatively, via emit-stream:
var emitStream = require('emit-stream')
var events = emitStream(pda.watch(archive))
events.on('changed', args => {
console.log(args.path, 'has changed')
})
-
archive
Hyperdrive archive (object). Can not be a dbrowser-sfs object. - Returns a Readable stream.
Watches the archive for network events, which it emits as an emit-stream. Supported events:
-
['network-changed',{connections}]
- The number of connections has changed.connections
is a number. -
['download',{feed,block,bytes}]
- A block has been downloaded.feed
will either be "metadata" or "content".block
is the index of data downloaded.bytes
is the number of bytes in the block. -
['upload',{feed,block,bytes}]
- A block has been uploaded.feed
will either be "metadata" or "content".block
is the index of data downloaded.bytes
is the number of bytes in the block. -
['sync',{feed}]
- All known blocks have been downloaded.feed
will either be "metadata" or "content".
var es = pda.createNetworkActivityStream(archive)
es.on('data', ([event, args]) => {
if (event === 'network-changed') {
console.log('Connected to %d peers', args.connections)
} else if (event === 'download') {
console.log('Just downloaded %d bytes (block %d) of the %s feed', args.bytes, args.block, args.feed)
} else if (event === 'upload') {
console.log('Just uploaded %d bytes (block %d) of the %s feed', args.bytes, args.block, args.feed)
} else if (event === 'sync') {
console.log('Finished downloading', args.feed)
}
})
// alternatively, via emit-stream:
var emitStream = require('emit-stream')
var events = emitStream(es)
events.on('network-changed', args => {
console.log('Connected to %d peers', args.connections)
})
events.on('download', args => {
console.log('Just downloaded %d bytes (block %d) of the %s feed', args.bytes, args.block, args.feed)
})
events.on('upload', args => {
console.log('Just uploaded %d bytes (block %d) of the %s feed', args.bytes, args.block, args.feed)
})
events.on('sync', args => {
console.log('Finished downloading', args.feed)
})
-
opts.srcPath
Source path in the filesystem (string). Required. -
opts.dstArchive
Destination archive (object). Required. -
opts.dstPath
Destination path within the archive. Optional, defaults to '/'. -
opts.ignore
Files not to copy (array of strings). Optional. Uses anymatch. -
opts.inplaceImport
Should import source directory in-place? (boolean). If true and importing a directory, this will cause the directory's content to be copied directy into thedstPath
. If false, will cause the source-directory to become a child of thedstPath
. -
opts.dryRun
Don't actually make changes, just list what changes will occur. Optional, defaults tofalse
. -
opts.progress
Function called with thestats
object on each file updated. - Returns stats on the export.
Copies a file-tree into an archive.
var stats = await pda.exportFilesystemToArchive({
srcPath: '/tmp/mystuff',
dstArchive: archive,
inplaceImport: true
})
console.log(stats) /* => {
addedFiles: ['fuzz.txt', 'foo/bar.txt'],
updatedFiles: ['something.txt'],
removedFiles: [],
addedFolders: ['foo'],
removedFolders: [],
skipCount: 3, // files skipped due to the target already existing
fileCount: 3,
totalSize: 400 // bytes
}*/
-
opts.srcArchive
Source archive (object). Required. -
opts.dstPath
Destination path in the filesystem (string). Required. -
opts.srcPath
Source path within the archive. Optional, defaults to '/'. -
opts.ignore
Files not to copy (array of strings). Optional. Uses anymatch. -
opts.overwriteExisting
Proceed if the destination isn't empty (boolean). Default false. -
opts.skipUndownloadedFiles
Ignore files that haven't been downloaded yet (boolean). Default false. If false, will wait for source files to download. - Returns stats on the export.
Copies an archive into the filesystem.
NOTE
- Unlike exportFilesystemToArchive, this will not compare the target for equality before copying. If
overwriteExisting
is true, it will simply copy all files again.
var stats = await pda.exportArchiveToFilesystem({
srcArchive: archive,
dstPath: '/tmp/mystuff',
skipUndownloadedFiles: true
})
console.log(stats) /* => {
addedFiles: ['fuzz.txt', 'foo/bar.txt'],
updatedFiles: ['something.txt'],
fileCount: 3,
totalSize: 400 // bytes
}*/
-
opts.srcArchive
Source archive (object). Required. -
opts.dstArchive
Destination archive (object). Required. -
opts.srcPath
Source path within the source archive (string). Optional, defaults to '/'. -
opts.dstPath
Destination path within the destination archive (string). Optional, defaults to '/'. -
opts.ignore
Files not to copy (array of strings). Optional. Uses anymatch. -
opts.skipUndownloadedFiles
Ignore files that haven't been downloaded yet (boolean). Default false. If false, will wait for source files to download.
Copies an archive into another archive.
NOTE
- Unlike exportFilesystemToArchive, this will not compare the target for equality before copying. It copies files indescriminately.
var stats = await pda.exportArchiveToArchive({
srcArchive: archiveA,
dstArchive: archiveB,
skipUndownloadedFiles: true
})
console.log(stats) /* => {
addedFiles: ['fuzz.txt', 'foo/bar.txt'],
updatedFiles: ['something.txt'],
fileCount: 3,
totalSize: 400 // bytes
}*/
-
archive
Hyperdrive archive (object).
A sugar to get the manifest object.
var manifestObj = await pda.readManifest(archive)
-
archive
Hyperdrive archive (object). -
manifest
Manifest values (object).
A sugar to write the manifest object.
await pda.writeManifest(archive, { title: 'My dat!' })
-
archive
Hyperdrive archive (object). -
manifest
Manifest values (object).
A sugar to modify the manifest object.
await pda.writeManifest(archive, { title: 'My dat!', description: 'the desc' })
await pda.writeManifest(archive, { title: 'My new title!' }) // preserves description
-
opts
Manifest options (object).
Helper to generate a manifest object. Opts in detail:
{
url: String, the dat's url
title: String
description: String
type: String
author: String | Object{url: String}
links: Object
web_root: String
fallback_page: String
}
See: https://github.com/datprotocol/index.json
-
archive
Archive (object). Required. -
other
Other version to diff against (number|object). Required. -
prefix
Path prefix to filter down to (string). Optional. - Returns diff data.
Get a list of differences between an archive at two points in its history
await pda.diff(archive, 2)
await pda.diff(archive, await archive.checkout(2))
await pda.diff(archive, 2, '/subfolder')
Output looks like:
[
{type: 'put', name: 'hello.txt', value: {stat: {...}}},
{type: 'mount', name: 'mounted-folder', value: {mount: {...}}},
{type: 'del', name: 'hello.txt'}
]
-
fn
Function. Required.
Sets a handler for when the daemon fails authentication. This can occur sometimes because the daemon has reset recently, forcing the auth token to change.