Coder Social home page Coder Social logo

rangermauve / hyper-sdk Goto Github PK

View Code? Open in Web Editor NEW
292.0 24.0 45.0 249 KB

Make your own hyper apps!

Home Page: https://www.youtube.com/watch?v=HyHk4aImd_I&list=PL7sG5SCUNyeYx8wnfMOUpsh7rM_g0w_cu&index=20

License: MIT License

JavaScript 100.00%
p2p hypercore-protocol hypercore dweb

hyper-sdk's Introduction

hyper-sdk

A Software Development Kit for the hypercore-protocol

Why use this?

Hypercore-protocol and it's ecosystem consists of a bunch of low level building blocks for working with data in distributed applications. Although this modularity makes it easy to mix and match pieces, it adds complexity when it comes to actually building something.

The Hyper SDK combines the lower level pieces of the Hyper stack into high level APIs that you can use across platforms so that you can focus on your application rather than the gritty details of how it works.

Goals

  • High level API
  • Cross-platform with same codebase
    • โœ” Node
    • โœ” Electron
    • ๐Ÿ—๏ธ Web (PRs welcome)

Installation

Make sure you've set up Node.js.

npm install --save hyper-sdk
# or yarn
import * as SDK from "hyper-sdk"

API

SDK.create()

const sdk = await SDK.create({
  // Specify the "storage" you want
  // Regular strings will be passed to `random-access-application` to store in your user directory
  // On web this will use `random-access-web` to choose the best storage based on the browser
  // You can specify an absolute or relative path `./example/` to choose where to store data
  // You can specify `false` to not persist data at all and do everything in-memory
  storage: 'hyper-sdk',

  // This controls whether the SDK will automatically start swarming when loading a core via `get`
  // Set this to false if you want to have more fine control over peer discovery
  autoJoin: true,

  // Specify options to pass to the Corestore constructor
  // The storage will get derived from the `storage` parameter
  // https://github.com/hypercore-protocol/corestore/
  corestoreOpts: {},

  // Specify options to pass to the hyperswarm constructor
  // The keypair will get derived automatically from the corestore
  // https://github.com/hyperswarm/hyperswarm
  swarmOpts: {},
})

sdk.publicKey

The public key used for identifying this peer in the hyperswarm network.

This is a 32 byte buffer which can be use in conjunction with sdk.joinPeer() to connect two peers directly together.

sdk.connections

The list of active connections to other peers, taken from hyperswarm.

sdk.peers

The list of active peers.

Each peer has a publicKey, and list of topics

You can find more docs in the hyperswarm repo.

sdk.cores

List of active Hypercores.

sdk.on('peer-add', peerInfo) / sdk.on('peer-remove', peerInfo)

You can listen on when a peer gets connected or disconnected with this event.

You can find more docs in the hyperswarm repo.

sdk.on('peer-add', (peerInfo) => {
  console.log('Connected to', peerInfo.publicKey, 'on', peerInfo.topics)
})
sdk.on('peer-add', (peerInfo) => {
  console.log('Disconnected from')
})

sdk.get()

You can initialize a Hypercore instance by passing in a key, a name to derive a key from, or a URL containing either a key or a DNS name.

You can also pass additional options for whether the hypercore should be replicated as sparse or not.

Unlike corestore, you may not initialize a hypercore from a null key since everything must be derivable or loadable.

Unless autoJoin is set to false, the peer discovery will be automatically started for the core.

// Derive a key from a "name"
const core = await sdk.get('example name')

// Resolve DNS to a hypercore
const core = await sdk.get('hyper://example.mauve.moe')

// Buffer key, 32 bytes of 0's
const core = await sdk.get(b4a.alloc(32, 0))

// Hex key, equivalent to 32 bytes of zeros
const core = await sdk.get('hyper://0000000000000000000000000000000000000000000000000000000000000000')

// z32 encoded, equivalent to 32 bytes of zeros
const core = await sdk.get('hyper://yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy')

// Disable sparse mode in order to download everything from peers
const core = await sdk.get('example', {sparse: false})

// Don't auto-join the swarm for the core on init
const core = await sdk.get('example', {autoJoin: false})

sdk.getDrive()

You can initialize a Hyperdrive instance by passing in the same arguments as in sdk.get().

In addition to the usual hyperdrive properties, there's a new url property to get the hyper:// URL for the drive to used elsewhere.

Note that the drives's metadata DB's discovery key will be used for replicating if autoJoin is true.

Hyperdrive is mostly useful for storing and loading files since it splits the metadata representing the file systema and the blob storage into separate cores.

const drive = await sdk.getDrive('hyper://blob.mauve.moe')
for(const path of drive.readdir('/')) {
  const stat = drive.stat(path)
}

sdk.getBee()

You can initialize a Hyperbee instance by passing the same arguments as in sdk.get().

In addition to the usual hyperbee properties, there's a new url property to get the hyper:// URL for the bee to used elsewhere.

Additionally, you should pass in a keyEncoding and a valueEncoding in order to control the encoding for data that's being written.

Hyperbee is best used when you want to create database indexes.

For an out of the box database with a proper query language, check out HyperbeeDeeBee.

const db = await sdk.getBee('example db')

const db = await sdk.getBee('example db', {keyEncoding: 'utf8', valueEncoding: 'json')
await db.put('hello', 'world')

for(const entry of db.createReadStream()) {
  console.log(entry)
}

sdk.resolveDNSToKey()

You can manually resolve DNS addresses to hypercore keys on domains using the DNS Link spec with this method.

However, it's not mandatory to use DNS since sdk.get() will automatically detect and perform resolutions of DNS for hyper:// URLs.

const key = await sdk.resolveDNSToKey('example.mauve.moe')

sdk.namespace()

Get back a namespaced Corestore instance which can be passed to things like Hyperdrive.

Note that cores initialized with a namespaced corestore will not be auto-joined and you will need to call sdk.join(core.discoveryKey) on said cores.

import Hypderdrive from "hyperdrive"

const drive = new Hyperdrive(sdk.namespace('example'))

// Wait for the drive to initiailize
await drive.ready()

// Manually trigger peer lookup for this drive
sdk.join(drive.publicKey)

sdk.join() / sdk.leave()

You can manually trigger peer discovery of hypercores as well as stop peer discovery. This can be done by using the discoveryKey of a hypercore, or any 32 byte buffer.

As well, you can use string names for topics in order to discover peers based on a human readable string. When using string topics, they are converted to 32 byte buffers using the Hypercore Crypto namespace algorithm.

const core = await sdk.get('example', {autoJoin: false})

// Start finding peers without advertising
sdk.join(core.discoveryKey, {server: false})

// Listen on a human readable topic
sdk.join("cool cat videos")

sdk.leave(core.discoveryKey)
sdk.leave("cool cat videos")

sdk.joinPeer() / sdk.leavePeer()

const sdk1 = await SDK.create({persist: false})
const sdk2 = await SDK.create({persist: false})

sdk1.joinPeer(sdk2.publicKey)

sdk.close()

This will gracefully close connections, remove advertisements from the DHT, and close any open file handles.

Make sure you invoke this to keep the network fast and to avoid data corruption!

hyper-sdk's People

Contributors

4c656554 avatar aramzs avatar douganderson444 avatar frando avatar gr0kchain avatar hdegroote avatar jackyzha0 avatar jamestheawesomedude avatar lejeunerenard avatar lukks avatar martinheidegger avatar mkroehnert avatar ninabreznik avatar nornagon avatar okdistribute avatar prm3theus avatar rangermauve avatar serapath avatar urgentest avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hyper-sdk's Issues

`peer-add` event not firing for archives

Here is a reproducible code:


const SDK = require('dat-sdk')
const { Hypercore, Hyperdrive, resolveName, deleteStorage, destroy } = SDK();
  
const archive = Hyperdrive(null, {
  persist: false,
  createIfMissing: true,
});
  
archive.on('peer-add', (peer) => {
  console.log("[Owner]: peer added: ", peer); // <-- NOT GETTING INVOKED !!
});

archive.on('ready', () => {
  const url = `dat://${archive.key.toString('hex')}`;
  console.log(`Here's your URL: ${url}`, "discovery key: ", archive.discoveryKey.toString('hex'), " version: ", archive.version);
  setInterval(updateFile, 1000); // keep updating frequently	
  updateFile(() => runClient(archive)); // do an update once on start (before client connects, to avoid 404), then start client
});

function updateFile(cb) {
  const str = `world-${(new Date()).toLocaleTimeString()}`;
  archive.writeFile('/example.txt', str, () => {
    console.log('[Owner]: Written example file!', str);
    if(cb) cb();
  });
}

/*-------------------------*/
/******* client ************/
/*-------------------------*/	
function runClient(archive) {
  var remoteArchive = Hyperdrive(archive.key.toString('hex'), {
    persist: false,
    createIfMissing: false
  });
  remoteArchive.on('peer-add', (peer) => {
    console.log("  [client] peer added: ", peer);
  });
  reallyReady(remoteArchive, () => {
    remoteArchive.readdir('/', console.log)
  })
  function reallyReady(archive, cb) {
    if (archive.metadata.peers.length) {
      archive.metadata.update({ ifAvailable: true }, cb)
    } else {
      archive.metadata.once('peer-add', () => { 
        archive.metadata.update({ ifAvailable: true }, cb)
      })
    }
  }
  remoteArchive.readFile('/example.txt', 'utf8', (err, data) => {
    if (err) throw err
    console.log(`  [client]: content of example.txt: ${data}`);

    remoteArchive.on('update', () => {
      console.log("  [client]:  remoteArchive updated: ", archive.version);
    });
  })	
}

What this does:

  • creates a new archive and keeps updating a file inside it. Also creates a test client
  • the client is able to receive update notifications from the owner for the file whenever it changes

What is not working:

  • the peer-add event is not getting fired on owner or client

Sample output:

Here's your URL: dat://72e0c3d4c61778020876a8ced49cfa683c63cc3a235c1b7d6aae75d8492fd504 discovery key:  05b9e8f264f076260c22a664adeaf2663b2c43c39800877cb36006d48e6f8dd7  version:  0
[Owner]: Written example file! world-7:36:20 AM
  [client]: content of example.txt: world-7:36:20 AM
  [client]:  remoteArchive updated:  2
[Owner]: Written example file! world-7:36:21 AM
  [client]:  remoteArchive updated:  3
[Owner]: Written example file! world-7:36:22 AM
  [client]:  remoteArchive updated:  4
[Owner]: Written example file! world-7:36:23 AM
  [client]:  remoteArchive updated:  5
[Owner]: Written example file! world-7:36:24 AM
  [client]:  remoteArchive updated:  6
[Owner]: Written example file! world-7:36:25 AM
  [client]:  remoteArchive updated:  7
[Owner]: Written example file! world-7:36:26 AM
  [client]:  remoteArchive updated:  8
[Owner]: Written example file! world-7:36:27 AM
  [client]:  remoteArchive updated:  9

how to load DatArchive in writable state ?

const archive = await DatArchive.load(datURL, {
        secretKey,
        persist: false
})
console.log((await archive.readdir('/')).length)
await archive.writeFile('/index.html', '<h1>Hello World!</h1>')
  • if secretKey===null then on my dat it prints number 3 and writeFile fails with error Cannot write to this archive ; Not the owner
  • if I do the same, with secretKey set to value returned by dat keys export it prints number 0 and write doesnt fail, but it doesn't get created in original repository

is this bug or how should I provide secretKey to be able to write to the repository ?

Cross Origin Request Blocked

What I Wanted
DatArchive.load and read file per https://github.com/datproject/sdk#apiexamples-promise

What I Did

index.js:

// Auto-detects sane defaults based on your environment
// Uses Beaker's APIs if they are if they are available
// DatArchive is the same as Beaker
// https://beakerbrowser.com/docs/apis/dat
const { DatArchive } = require("dat-sdk/auto");

(async function() {
  const archive = await DatArchive.load("dat://dat.foundation");

  const someData = await archive.readFile("/dat.json", "utf8");

  console.log("Dat foundation dat.json:", someData);
})();

browserify -d index.js > test-bundle.js

index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="/test-bundle.js" defer></script>
  </head>
  <body>
    <div></div>
  </body>
</html>

What I Got

Firefox console output:
TypeError: NetworkError when attempting to fetch resource.
Firefox canโ€™t establish a connection to the server at ws://localhost:3472/. stream.js:64
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://gateway.mauve.moe/undation/.well-known/dat. (Reason: CORS header โ€˜Access-Control-Allow-Originโ€™ missing).

TypeError: NetworkError when attempting to fetch resource.

bundle.run links and web browser example in the README are broken

The README gives the following example for getting started with Dat in the browser:

<script src="https://bundle.run/dat-sdk@1"></script>
<script src="https://bundle.run/dat-sdk@1/promise.js"></script>
<script src="https://bundle.run/dat-sdk@1/auto.js"></script>
<script>
  const SDK = window.datSDK
  // Look at the examples from here
</script>

Unfortunately those script links are broken. Are there updated sources or an updated "Hello World" browser example you would recommend?

Uncaught TypeError: Cannot read property 'join' of undefined

I'm doing
const url = 'dat://c610858d82e4c9bc9585bb26fedb260c080ed24c6a05bcf3da9ad73a6917ac82/'
const archive = Hyperdrive(url)

using version
"dat-sdk": "^0.1.0"

getting the following error:

index.js:931 Uncaught TypeError: Cannot read property 'join' of undefined
    at Storage.metadata [as create] (index.js:931)
    at Storage.openKey (storage.js:224)
    at Storage.openKey (storage.js:223)
    at Feed._open (index.js:326)
    at open (index.js:138)
    at run (index.js:19)
    at Feed.thunk [as _ready] (index.js:13)
    at new Feed (index.js:117)
    at Feed (index.js:37)
    at new Hyperdrive (index.js:43)
metadata @ index.js:931
Storage.openKey @ storage.js:224
Storage.openKey @ storage.js:223
Feed._open @ index.js:326
open @ index.js:138
run @ index.js:19
thunk @ index.js:13
Feed @ index.js:117
Feed @ index.js:37
Hyperdrive @ index.js:43
Hyperdrive @ index.js:26
Hyperdrive @ index.js:80
334../moloch-demo.sol @ contracts.js:7
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
338.bel @ makeCollectionArea.js:3
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
341../svg.json @ paginationButtons.js:3
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
342.bel @ search.js:5
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
333.bel @ index.js:5
o @ _prelude.js:1
r @ _prelude.js:1
(anonymous) @ _prelude.js:1
stream.js:64 WebSocket connection to 'ws://localhost:3472/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
WebSocketStream @ stream.js:64
DiscoverySwarmStreamWebsocket @ index.js:161
DiscoverySwarmWeb @ index.js:50
module.exports @ index.js:196
Hyperdiscovery @ index.js:51
module.exports @ index.js:11
SDK @ index.js:24
334../moloch-demo.sol @ contracts.js:2
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
338.bel @ makeCollectionArea.js:3
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
341../svg.json @ paginationButtons.js:3
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
342.bel @ search.js:5
o @ _prelude.js:1
(anonymous) @ _prelude.js:1
333.bel @ index.js:5
o @ _prelude.js:1
r @ _prelude.js:1
(anonymous) @ _prelude.js:1
events.js:164 Uncaught Error: Unhandled "error" event. ([object Event])
    at Duplexify.emit (events.js:164)
    at Duplexify._destroy (index.js:191)
    at index.js:182
    at Item.run (browser.js:153)
    at drainQueue (browser.js:123)

Spring release plan

Like spring cleaning but spring releasing!

@RangerMauve, want to make a plan around how to reduce the 'TODO' items in the README and start calling this module 'v1.0'/done, and hopefully deprecate other modules that it replaces (i.e., dat-js/dat-node)? Happy to jump on a call sometime!

archive.readFile doesn't call the callback

When I call archive.readFile with the path where the file is empty, callback doesn't get triggered.

Screenshot_2019-08-11_00-54-44

If I call the same with path where file is not empty, it works fine and when I call it with wrong path, I get an error.

Hypercore Secret Key option

My platform starts up a new container for each build and I keep loosing write permissions.

In the dat-sdk, is it possible to:

I was thinking of something like:

const myArchive = await DatArchive.create({
  title: 'My Archive'
})

const archive = await DatArchive.load(myArchive.url, {secretKey: myArchive.secretKey})

That way, I can set secretKey as an env variable, and maintain write permissions between containers.

Integrate with hyperswarm-daemon

  • Corestore API
  • Wrap RPC client API in Callback API
  • Auto-spawn the daemon
  • Have web use existing implementation
  • Update Cabal with new Daemon-based code
  • Release

Dat 2 Support

  • Add corestore for replication
  • Hyperdrive 10 API with promise wrapper
  • Hypercore API with promise wrapper
  • Use hyperswarm-web for web
  • Use sodium-javascript-plus to use new hypercore on web
  • Add destroy method to hyperdrive (pending on PR)
  • Add way to control discoveryKey / lookup / announce swarm opts.
  • Docs
  • Release

This is currently blocked on hypercore having support for browsers / API stabilization of corestore and hyperdrive

Beaker Integration

  • Wrap DatArchive with hyperdrive
  • Wrap resolveName API with Beaker APIs
  • Test that hypercore still works using web storage / proxying
  • Make sure tests work in Node / Web / Beaker
  • Release

Meta: ES Modules for documentation / distributed artifacts

TL;DR Please consider distributing the DAT SDK as an ES Module, and prefer documentation that demonstrates how to use it as an ES Module.

The frontier of the JavaScript library-building community is moving towards expressing distributed libraries as ES Modules. Tools like Rollup.js and Node.jsยน are creating cowpaths for a package ecosystem where modules can be more easily/consistently imported in multiple environments by adopting the standard JavaScript module syntax.

On the one hand, I'm sure that a full-conversion to ES Modules would be a lot of work, and is likely not feasible given the sheer number of dependencies involved. On the other hand, it seems like it would be feasible to distribute an artifact that uses ES Modules so that others can consume the SDK that way, and to reflect that mode of usage in documentation.

In the long run, preferring ES Module-based packages will make it easier for dependent projects to apply optimizations such as sharing dependency packages with the SDK, tree shaking and code splitting. These optimizations may be possible today, but in order to apply them effectively we would need a comparatively intimate knowledge of the DAT SDK's dependency graph and all the errata to correctly bundle it.

The DAT SDK is a massive body of JavaScript. The more of it that can be consumed in a standard, consistent module format, the easier it will be to accept the byte cost it brings as a dependency.

Thank you for your consideration, and I look forward to hearing your thoughts on this issue.

ยน Node v12.17.0 "--experimental-modules flag is no longer necessary to use ECMAScript modules (ESM)"

archive.watch() picks up changes irregularly

Hey, I'm working on a web implementation of the sdk(promise) that imports an existing dat archive, reads its contents, renders some of its files, and orders them reverse-chronologically, in a 'blog' style. I am just an amateur trying to 'do It myself', so i hope my issue is a simple one.

goal: having multiple 'blogs' served from different devices to a web-client that awaits changes and updates live.

I tried to implement archive.watch() exactly as it is documented in the README. It partly works. Deleting existing files is always picked up, and creating files in terminal within the directory with touch is also always picked up. But it doesn't seem to pick up files being manually pasted into the folder or changes made to files with any program (although the dat-cli is logging those changes). To add to this, when i used archive.download(), (it downloads the archive and) the 'changed' event is fired for all the changes that were previously not picked up.

I saw that this is a recurring issue with fs.watch() as well, and there are some workarounds (chokidar?). Dat-node also has a great .on('put') and .on('del'), but it's not meant for web :(

Where exactly is the problem? Would there be a simple solution for this?

(btw thanks for all the great work!)

Webpack dat-dns not found

When using the dat-sdk as described in the README with Webpack/Vue it does have an issue loading dat-dns:

const SDKPromise = require('dat-sdk/promise')

Error message:

* dns in ./node_modules/node-dat-archive/node_modules/dat-dns/index.js

The sample, see App.vue for the problematic import:
datbox.zip

Different Extensions per Hyperdrive/Hypercore

It would probably result in unexpected behavior if different Hyperdrives/Hypercores used different extensions:

const sdk = new SDK()
sdk.Hypercore({extensions: ['a']})
sdk.Hypercore(..., {extensions: ['b']})

as the first hyper* would add the extension a to the swarm but the second hypercore would have a & b (even though only a was specified). And while the first one would expect it only had a connecting to it, in the protocol it would broadcast both the availability of a and b.

For the time being I think the quickest solution to this would be that extensions are added as option to the swarm and explicitly forbidden as option to a core/drive.

'Error: Could not bind'

Expected Behaviour:

Using the dat-sdk in two different instances of node should allow for cross-process swarming

Actual behaviour:

Requiring the dat-sdk while it is open in another node instance produces a traceback, and replication does not occur between processes

Environment:

Ubuntu on Windows Subsystem for Linux, node v10.16.0

Traceback:

> const {Hypercore} = require('dat-sdk')();
undefined
> Thrown:
{ Error: Could not bind
    at UTP.bind (/mnt/c/Users/Delta/Documents/hyperchat/node_modules/discovery-swarm/node_modules/utp-native/index.js:178:18)
    at UTP.listen (/mnt/c/Users/Delta/Documents/hyperchat/node_modules/discovery-swarm/node_modules/utp-native/index.js:190:32)
    at Server.ontcplisten (/mnt/c/Users/Delta/Documents/hyperchat/node_modules/discovery-swarm/index.js:510:15)
    at Server.emit (events.js:198:13)
    at Server.EventEmitter.emit (domain.js:466:23)
    at emitListeningNT (net.js:1313:10)
    at process._tickCallback (internal/process/next_tick.js:63:19)
  domainEmitter:
   Hyperdiscovery {
     domain:
      Domain {
        domain: null,
        _events: [Object],
        _eventsCount: 3,
        _maxListeners: undefined,
        members: [],
        [Symbol(kWeak)]: WeakReference {} },
     _events: [Object: null prototype] {},
     _eventsCount: 0,
     _maxListeners: undefined,
     _opts: { extensions: [] },
     id:
      <Buffer 9e f9 c7 ea 7f a1 1a ff d1 7c 0e c3 45 95 06 44 15 e5 d0 e8 8c f8 32 8a bf 56 e4 38 d6 e3 98 8a>,
     _port: 3282,
     _portAlts: [ 3000, 3002, 3004, 2001, 2003, 2005 ],
     _swarm:
      Swarm {
        domain: [Domain],
        _events: [Object],
        _eventsCount: 13,
        _maxListeners: undefined,
        maxConnections: 0,
        totalConnections: 0,
        connections: [],
        id:
         <Buffer 9e f9 c7 ea 7f a1 1a ff d1 7c 0e c3 45 95 06 44 15 e5 d0 e8 8c f8 32 8a bf 56 e4 38 d6 e3 98 8a>,
        destroyed: false,
        _stream: [Function: bound _createReplicationStream],
        _options: [Object],
        _whitelist: [],
        _discovery: null,
        _tcp: [Server],
        _utp: [UTP],
        _tcpConnections: [EventEmitter],
        _adding: [],
        _listening: true,
        _peersIds: {},
        _peersSeen: {},
        _peersQueued: [] },
     _replicatingFeeds: Map {} },
  domain:
   Domain {
     domain: null,
     _events:
      [Object: null prototype] {
        removeListener: [Function: updateExceptionCapture],
        newListener: [Function: updateExceptionCapture],
        error: [Function: debugDomainError] },
     _eventsCount: 3,
     _maxListeners: undefined,
     members: [],
     [Symbol(kWeak)]: WeakReference {} },
  domainThrown: false }

Storage not persisting on Chrome and Firefox

Apparently there's an error: DOMException: "The operation failed because the requested database object could not be found. For example, an object store did not exist but was being opened."

Gonna figure this out on Monday.

Error: Hyperdrive is not a constructor

Hey,

I am trying to run the example code from the readme and get this error. There was also a closing single quote typo (did a PR for that), but now it throws this error.

Any idea what this could be?

Screenshot_2019-07-17_00-20-08

archive.getSecretKey returns undefined

To repro:

const myArchive = await DatArchive.create({
  title: 'My Archive',
  persist: false,
})
console.log(await myArchive.getSecretKey())
// => undefined

require('dat-sdk/auto') fails to run due to missing directory

I pulled the Promises example code from the README and ran it on a fresh machine (macOS) and encountered this error:

/Users/nornagon/Source/autowiki/node_modules/node-localstorage/LocalStorage.js:187
            throw e;
            ^

Error: ENOENT: no such file or directory, mkdir '/Users/nornagon/Library/Application Support/dat-nodejs/localStorage'
    at Object.mkdirSync (fs.js:856:3)
    at LocalStorage._init (/Users/nornagon/Source/autowiki/node_modules/node-localstorage/LocalStorage.js:183:14)
    at new LocalStorage (/Users/nornagon/Source/autowiki/node_modules/node-localstorage/LocalStorage.js:124:12)
    at module.exports (/Users/nornagon/Source/autowiki/node_modules/dat-sdk/localstorage.js:13:10)
    at SDK (/Users/nornagon/Source/autowiki/node_modules/dat-sdk/promise.js:36:24)
    at Object.<anonymous> (/Users/nornagon/Source/autowiki/node_modules/dat-sdk/auto.js:9:40)
    at Module._compile (internal/modules/cjs/loader.js:1151:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14) {
  errno: -2,
  syscall: 'mkdir',
  code: 'ENOENT',
  path: '/Users/nornagon/Library/Application Support/dat-nodejs/localStorage'
}

It looks like simply requiring dat-sdk/auto is enough to trigger this error:

const {DatArchive} = require('dat-sdk/auto')

When using await there is no option to persist

When using this construction await DatArchive.create({ there doesn't seem to be anyway to pass the option to tell the archive to be persistent? It will continue to rotate the dat uri on every machine reboot?

Is there a way to have it emulate https://github.com/datproject/dat-node in having an archive uri that is persistent? I assume it means passing the key as dat-node did at https://github.com/datproject/dat-node/blob/master/index.js#L93 ? and I could def manually create a file somewhere to store it, but I don't see a way to use the await construction to pass that option to hyperdrive?

Document the differences between the sdk and dat-node

I recently tried to use the dat-sdk as i would have used dat-node and noticed that both the data storage structure and the synchronization has changed entirely. It would be good if there was documentation about it.

Hypercore constructor not respecting key argument

Expected behaviour:

Passing in the key attribute of a generated hypercore to the contructor should produce another hypercore with the same key

Actual behaviour:

A new random key-pair is generated

Environment:

Ubuntu on Windows Subsystem for Linux, node v10.16.0

Steps to reproduce:

> const {Hypercore} = require('dat-sdk')();
undefined
> remote = Hypercore('23e2ea2ce9e4ecf32df8b0cb8bbf951ce95f828a0ae2a56c76f051697b590a21');
Hypercore(
  key: null
  discoveryKey: null
  opened: false
  sparse: false
  writable: false
  length: 0
  byteLength: 0
  peers: 0
)
> remote.key
<Buffer 76 7e 79 b2 22 92 56 b2 64 b3 88 88 2c 5f 4a 7b b6 f0 70 67 be 06 fa 81 aa 27 a2 08 47 cb e9 41>

SLEEP dir usage

Hello y'all, this is a question about hyperdrive, the sdk and the .dat folder that we use to find after using the dat CLI create or share commands.
From my understanding the .dat folder contains SLEEP related files. The current sdk behavior is to create a .dat file containing the public key only. Is this desired behavior? I mean maybe the SLEEP format is not longer used anymore. Or maybe there is a module to handle SLEEP dir creation. I'm playing with dat-storage with no luck yet.

My use case involves something similar to dat-node but using latest hyperdrive mainly.

Thanks in advance for any info ๐Ÿ‘‹

(Dat2) Replicate in-memory hypercores

Hiya, I was testing out the dat2-take-two branch. Looking good!

Hypercores created with the { persist: false } option cannot be replicated at the moment. As they are created outside of the Corestore they are not injected into replication streams, as corestore-swarm-networking doesn't know about them.

I'm not sure what the best fix is for this. Maybe doing a PR to corestore that would add support for a persist opt there? So that it could create hypercores with a random-access-memory storage but otherwise treat them exactly the same, so that they're part of the normal replication workflow. @andrewosh? Alternatively we'd need a way to dynamically inject hypercores into corestore-swarm-networking, that seems difficult though with its reliance on corestore's stream injection handling. A third option would be not to use corestore-swarm-networking and roll our own replication manager in the SDK, but then that would have to be maintained.

issues with bundling for web

I am happy to try the new version of the sdk. When bundling for web, I ran into some issues. This is all very new to me, so I am not sure where things went wrong.

  1. Compiling with build:
git clone [email protected]:datproject/sdk.git
cd sdk
npm install
npm run build

With dat-sdk-bundle.js linked in my html page, my browser logs this error:

dat-sdk-bundle.js:64222 Uncaught Error: No native build was found for platform=browser arch=javascript runtime=node abi=undefined uv= libc=glibc
    at Function.load.path (dat-sdk-bundle.js:64222)
    at load (dat-sdk-bundle.js:64187)
    at Object.<anonymous> (dat-sdk-bundle.js:64160)
    at Object.427.node-gyp-build (dat-sdk-bundle.js:64164)
    at o (dat-sdk-bundle.js:1)
    at dat-sdk-bundle.js:1
    at Object.<anonymous> (dat-sdk-bundle.js:51584)
    at Object.317../cipher-state (dat-sdk-bundle.js:52085)
    at o (dat-sdk-bundle.js:1)
    at dat-sdk-bundle.js:1
  1. With Browserify:
npm install --save-dev browserify
npm install --save dat-sdk@next
browserify index.js > bundle.js

Npm could not find modules 'babelify' and '@babel/core', so after installing them manually and bundling again, I got back a bundle.js and could link it my webpage. My browser logs the same error as above.

  1. With Webpack:

In my working directory, I installed the sdk, webpack, and webpack-cli with npm install --save dat-sdk webpack webpack-cli, and used the same webpack.config.js as the one in the documentation. This attempt did not make it to the browser, with the ./node_modules/.bin/webpack command logging this error for every instance of util in the sdk:

ERROR in ./node_modules/browserify-sign/node_modules/readable-stream/lib/_stream_readable.js
Module not found: Error: Can't resolve 'util' in '/Users/km/Desktop/HOMESERVER/tryouts/hyperdrive-test-5-webpack/node_modules/browserify-sign/node_modules/readable-stream/lib'
 @ ./node_modules/browserify-sign/node_modules/readable-stream/lib/_stream_readable.js 60:16-31
 @ ./node_modules/browserify-sign/node_modules/readable-stream/readable-browser.js
 @ ./node_modules/browserify-sign/browser/index.js
 @ ./node_modules/crypto-browserify/index.js
 @ ./node_modules/corestore-swarm-networking/index.js
 @ ./node_modules/dat-sdk/index.js
 @ ./index.js

Although ./node_modules/util/util.js does exist. I don't know why this is happening.

(npm v6.14.5, node v12.18.1, and Google Chrome v83 on macOS 10.15.5)

How to Replicate in SDK?

dat-js and dat-node just kinda replicated out of the box. Without any createServer or fancy stream stuff.

Now that we're back to straight up archive = new Hyperdrive do we have to do the whole archive.replicate() business?

A) Is this implemented in SDK yet? and;
B) If so, could we get a little paste love with an example? I see the archive.url but I'm struggling to get it to replicate onto another machine.

@RangerMauve

Not updating archive?

Hey guys,

I have some problems with adding files to an archive. I use chokidar to watch a folder as follows:

const watcher = chokidar.watch(filePath, {
    ignored: /(^|[\/\\])\../, // ignore dotfiles
    persistent: true,
    ignoreInitial: true,
});

watcher.on('add', async (addedPath: string) => {
    fs.readFile(filePath, async (err, data) => {
        await archive.writeFile(path.basename(addedPath), data);
        console.log('Wrote ${path.basename(addedPath)}, ${addedPath} to the archive');
        console.log(`Current archive contents: ${await archive.readdir('/')}`);
    });
});

Which works as expected: It adds the file to the archive and lists it in archive.readdir('/').

However, when using the following code to watch for updates, it does not register any updates:

const { Hyperdrive } = sdk;
const archive = Hyperdrive(key, {
    sparse: false,
    sparseMetadata: false,
});
// This registers the initial content of the archive correctly
let files = await archive.readdir('/');
// Just updates do not work
archive.on('update', async () => {
      console.log('archive updated');
});

This is wrapped in a async click listener in a react electron app.

Am I missing something? Is it the async method?

Web-daemon

Figure out how to share hyperdrives between tabs / origins by having a daemon that runs inside the web browser and stores all hyperdrives / uses RPC to for access by tabs

Chrome Security Prompt: Store Files on this Device ?

Running this below example code from the ReadMe is prompting security alert as shown below. Since this example code apparently does not much, this prompt is very alarming.

image

  const discoveryCoreKey = 'dat://bee80ff3a4ee5e727dc44197cb9d25bf8f19d50b0f3ad2984cfe5b7d14e75de7'
  const discoveryCore = new Hypercore(discoveryCoreKey, {
    extensions: ['discovery']
  });    

Question:

How to specify that dat SDK should use IDB / localForage or its equivalent instead of FileSystemAPI?

How to close DatArchive

How may I run this code so that the node process ends?

I run it with node dat.js, and the process hangs.

dat.js

const { DatArchive } = require('dat-sdk/auto')
const read = async () => {
  const archive = await DatArchive.load('dat://dat.foundation')

  const someData = await archive.readFile('/dat.json', 'utf8')

  console.log(someData)
}

read()

Thank you!

Cannot browserify dat-sdk

index.js is simply const SDK = require('dat-sdk')

In my terminal:

browserify index.js > bundle.js
Error: Cannot find module 'babelify' from '/Users/my_user/Documents/GitHub/project/node_modules/dat-sdk'

So I tried npm install babelify then, again, browserify index.js > bundle.js
My terminal:

Error: Cannot find module '@babel/core'

DatArchive Persistence and Write Permissions

I ran this code in the Firefox:


const archive = await DatArchive.create({
      title:"Test",
    });

console.debug(archive);

Then I copied the URL from the console, and changed my code to:

const archive = await DatArchive.load("dat://f8c1bd14267d5783a06ed7ca9d255a6ca957b4be853ec415f77cda2ce4dda7ed");
await new Promise(resolve => setTimeout(resolve, 4000));
await archive.writeFile('/test.json', 'Hello World!');

and I get:

Error: Cannot write to this archive ; Not the owner

Here's a link to glitch:

https://glitch.com/edit/#!/ralphie-line

ws to port 3472 issue

It is not clear why the code is trying to connect to port 3472.

Testing a sample code below:

    const myCore = Hypercore(null, {
      valueEncoding: 'json',
      persist: false,
      storage: null  // storage: RAI
    })
    myCore.append(JSON.stringify({
      name: 'Alice'
    }), () => { 
      const discoveryCoreKey = 'dat://bee80ff3a4ee5e727dc44197cb9d25bf8f19d50b0f3ad2984cfe5b7d14e75de7'
      const discoveryCore = new Hypercore(discoveryCoreKey, {
        persist: false,
        extensions: ['discovery']
      })

      // When you find a new peer, tell them about your core
      discoveryCore.on('peer-add', (peer) => {
        console.log('Got a peer!')
        peer.extension('discovery', myCore.key)
      })
      discoveryCore.on('extension', (type, message) => {
        console.log('Got extension message', type, message)
        if (type !== 'discovery') return
        discoveryCore.close()

        const otherCore = new Hypercore(message, {
          valueEncoding: 'json',
          persist: false
        })
        otherCore.get(0, console.log)
      })
    });

In the browser, getting the below error:

WebSocket connection to 'ws://localhost:3472/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

image

as well as this error:
image

Electron build failing

It looks like the SDK now officially supports Electron, but when I attempt to build the package I get the following errors. Is this the correct way to include the sdk into Electron, or are we supposed to build a browser bundle?

Electron React Boilerplate

โœ– Rebuild Failed

An unhandled error occurred inside electron-rebuild
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | darwin | x64
gyp info find Python using Python version 2.7.5 found at "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python"
gyp info spawn /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
gyp info spawn args [
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/.electron-gyp/7.1.13/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/Users/carolbaskins/.electron-gyp/7.1.13',
gyp info spawn args   '-Dnode_gyp_dir=/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=/Users/carolbaskins/.electron-gyp/7.1.13/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
  CC(target) Release/obj.target/sodium/binding.o
../binding.c:70:20: warning: implicit declaration of function 'napi_detach_arraybuffer' is invalid in C99 [-Wimplicit-function-declaration]
  SN_STATUS_THROWS(napi_detach_arraybuffer(env, array_buf), "failed to detach array buffer");
                   ^
1 warning generated.
  SOLINK_MODULE(target) Release/sodium.node
clang: error: no such file or directory: '../lib/libsodium-x64.dylib'
make: *** [Release/sodium.node] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:203:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Darwin 19.4.0
gyp ERR! command "/Users/carolbaskins/.nvm/versions/node/v12.8.1/bin/node" "/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/.bin/node-gyp" "rebuild" "--target=7.1.13" "--arch=x64" "--dist-url=https://www.electronjs.org/headers" "--build-from-source"
gyp ERR! cwd /Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native
gyp ERR! node -v v12.8.1
gyp ERR! node-gyp -v v6.1.0
gyp ERR! not ok 

Failed with exit code: 1

Error: gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | darwin | x64
gyp info find Python using Python version 2.7.5 found at "/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python"
gyp info spawn /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
gyp info spawn args [
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/Users/carolbaskins/.electron-gyp/7.1.13/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/Users/carolbaskins/.electron-gyp/7.1.13',
gyp info spawn args   '-Dnode_gyp_dir=/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=/Users/carolbaskins/.electron-gyp/7.1.13/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
  CC(target) Release/obj.target/sodium/binding.o
../binding.c:70:20: warning: implicit declaration of function 'napi_detach_arraybuffer' is invalid in C99 [-Wimplicit-function-declaration]
  SN_STATUS_THROWS(napi_detach_arraybuffer(env, array_buf), "failed to detach array buffer");
                   ^
1 warning generated.
  SOLINK_MODULE(target) Release/sodium.node
clang: error: no such file or directory: '../lib/libsodium-x64.dylib'
make: *** [Release/sodium.node] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/node-gyp/lib/build.js:194:23)
gyp ERR! stack     at ChildProcess.emit (events.js:203:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12)
gyp ERR! System Darwin 19.4.0
gyp ERR! command "/Users/carolbaskins/.nvm/versions/node/v12.8.1/bin/node" "/Users/carolbaskins/Documents/electron-mail-client/node_modules/electron-rebuild/node_modules/.bin/node-gyp" "rebuild" "--target=7.1.13" "--arch=x64" "--dist-url=https://www.electronjs.org/headers" "--build-from-source"
gyp ERR! cwd /Users/carolbaskins/Documents/electron-mail-client/app/node_modules/sodium-native
gyp ERR! node -v v12.8.1
gyp ERR! node-gyp -v v6.1.0
gyp ERR! not ok 

Failed with exit code: 1
    at SafeSubscriber._error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/spawn-rx/lib/src/index.js:267:84)
    at SafeSubscriber.__tryOrUnsub (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:205:16)
    at SafeSubscriber.error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:156:26)
    at Subscriber._error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:92:26)
    at Subscriber.error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:72:18)
    at MapSubscriber.Subscriber._error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:92:26)
    at MapSubscriber.Subscriber.error (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:72:18)
    at SafeSubscriber._next (/Users/carolbaskins/Documents/electron-mail-client/node_modules/spawn-rx/lib/src/index.js:242:65)
    at SafeSubscriber.__tryOrUnsub (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:205:16)
    at SafeSubscriber.next (/Users/carolbaskins/Documents/electron-mail-client/node_modules/rxjs/internal/Subscriber.js:143:22)
child_process.js:660
    throw err;
    ^

Error: Command failed: ../node_modules/.bin/electron-rebuild --parallel --force --types prod,dev,optional --module-dir .
    at checkExecSyncError (child_process.js:621:11)
    at execSync (child_process.js:657:15)
    at Object.<anonymous> (/Users/carolbaskins/Documents/electron-mail-client/internals/scripts/ElectronRebuild.js:18:3)
    at Module._compile (internal/modules/cjs/loader.js:868:30)
    at Module._compile (/Users/carolbaskins/Documents/electron-mail-client/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:879:10)
    at Object.newLoader [as .js] (/Users/carolbaskins/Documents/electron-mail-client/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:731:32)
    at Function.Module._load (internal/modules/cjs/loader.js:644:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:931:10) {
  status: 255,
  signal: null,
  output: [ null, null, null ],
  pid: 52280,
  stdout: null,
  stderr: null
}

Upgrade signalbub to wss:// ?

When I try to use the SDK to do
const { Hypercore } = SDK()
over HTTPS on esnextbin, I get this error:

was loaded over HTTPS, but attempted to connect to the insecure 
WebSocket endpoint 'ws://signalhubws.mauve.moe/discovery-swarm-web'. 
This request has been blocked; this endpoint must be available over WSS.

Should ws://signalhubws.mauve.moe/discovery-swarm-web be sent over wss?

ready() promises do not resolve in a mobile context when using browserified dat-sdk

The following html works in a desktop browser, but does not on the mobile browsers I tried (Safari, Brave).

The drive.ready() does not resolve, it appears.

<!DOCTYPE html><html>
<head>
  <script src="lib/dat-sdk-bundle.js"></script>
 <meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>

<script>

let hypersdk
let drive
let core

// Runs through initialisation of hyper core and hyperdrive, puts status messages in html doc.
;(async function(){

  await new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve));
  document.getElementById('setup').innerHTML += 'dom loaded<br>'
  hypersdk = await window.datSDK();
  document.getElementById('setup').innerHTML += 'hypersdk loaded<br>'


  drive = await hypersdk.Hyperdrive('drive')
  document.getElementById('drive').innerHTML += 'drive created<br>' //+String(drive.ready()) Note adding this shows that mobile browser recognises ready() as promise obj
  await drive.ready()
  document.getElementById('drive').innerHTML += 'drive ready<br>'
  document.getElementById('drive').innerHTML += 'drive key = ' + drive.key.toString('hex') +'<br>'


  core = await hypersdk.Hypercore('core')
  document.getElementById('core').innerHTML += 'core created<br>' +String(core.ready())
  await core.ready()
  document.getElementById('core').innerHTML += 'core ready<br>'
  document.getElementById('core').innerHTML += 'core key = ' + core.key.toString('hex') +'<br>'

})();


</script>
<!-- main container div -->
<div id="main" style="width:100%;height:auto;display:grid;grid-template: auto auto auto/ auto;background-color:red;">
      <div id="setup" style="width:100%;height:auto;grid-area: 1 / 1 / 2 / 2;;background-color:lavender;">
        INIT:<br>
      </div>
      <div id="drive" style="width:100%;height:auto;grid-area: 2 / 1 / 3 / 2;transition: all 0.5s;background-color:lightgreen;">
        DRIVE:<br>
      </div>
      <div id="core" style="width:100%;height:auto;grid-area: 3 / 1 / 4 / 2;transition: all 0.5s;background-color:yellow;">
        CORE:<br>
      </div>
</div>

</body></html>

Thanks for creating this great library!

Why does the sdk create `uls_scratch` directory?

I am a bit confused. I am trying to create a new dat with via the promise syntax and it is creating a directory uls_scratch within my current working directory, but apparently not creating a folder for storing the dat data.

const { DatArchive, destroy } = require("dat-sdk/auto");

async function main() {
  const archive = await DatArchive.create({ title: "My Archive" });
  await archive.writeFile("/example.txt", "Hello World!");
  destroy();
}
main();

What is this directory and why is it not cleaned up? Where is the actually data getting stored?
Or does this use RAM?

Browser test failing (Storage / RAW)

When I build the test and open in the browser, it fails. This is what i get:

test-bundle.js:66097 Uncaught (in promise) Error: Not opened
    at Request._openAndNotClosed (test-bundle.js:66097)
    at Request._run (test-bundle.js:66120)
    at RandomAccess.run (test-bundle.js:66025)
    at RandomAccess.write (test-bundle.js:65979)
    at Request._callback (test-bundle.js:22236)
    at Request.callback (test-bundle.js:66091)
    at nextTickCallback (test-bundle.js:66185)
    at Item.run (test-bundle.js:63440)
    at drainQueue (test-bundle.js:63404)

I haven't been able to persist: true in the browser for a while. For some reason the random-access-storage isn't opening? I'm not sure how to troubleshoot this. ๐Ÿ˜ž

Browser: Chrome 85 on Windows
sdk v 2.8.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.