@blockstorage/repertory-js

A Node.js module for interfacing with Repertory's remote mount API

Usage no npm install needed!

<script type="module">
  import blockstorageRepertoryJs from 'https://cdn.skypack.dev/@blockstorage/repertory-js';
</script>

README

About

repertory-js is a Node.js module for interfacing with repertory's remote mount API.

Installing

npm i @blockstorage/repertory-js

Repertory Configuration

A Repertory mount must be active with the EnableRemoteMount setting enabled. RemoteToken should also be set to a strong, random password.

Enabling Sia Remote Mount API on Windows Systems

    repertory.exe -unmount
    repertory.exe -set RemoteMount.EnableRemoteMount true
    repertory.exe -set RemoteMount.RemoteToken "my password"
    
    [Optional - change listening port]
    repertory.exe -set RemoteMount.RemotePort 20202

Enabling Sia Remote Mount API on *NIX Systems

    ./repertory -unmount
    ./repertory -set RemoteMount.EnableRemoteMount true
    ./repertory -set RemoteMount.RemoteToken "my password"
    
    [Optional - change listening port]
    ./repertory -set RemoteMount.RemotePort 20202

Skynet and ScPrime Mounts

  • For Skynet mounts, add -sk argument to all commands listed above.
  • For ScPrime mounts, add -sp argument to all commands listed above.

Module Environment Variables

  • To successfully complete unit tests, a repertory mount supporting remote mount needs to be active. Set the following environment variables prior to running tests:
    • TEST_HOST
    • TEST_PASSWORD
    • TEST_PORT
  • To override the version being sent to repertory, set the following variable:
    • REPERTORY_JS_FORCE_VERSION
      • NOTE: This variable is primarily used for debugging/testing purposes and should normally NOT be set.

Example API Usage

import * as rep from "@blockstorage/repertory-js";
//const rep = require("@blockstorage/repertory-js");


// Repertory host settings
const MY_HOST_OR_IP = 'localhost';
const MY_PORT = 20000;
const MY_TOKEN = 'password';

// Progress callback for uploads / downloads
const progress_cb = (local_path, remote_path, progress, completed) => {
  console.log(local_path, remote_path, progress, completed);
};


//************************************************************************************************//
//                        Step 1. Create a connection pool (recommended)                          //
//************************************************************************************************//

const conn = await rep.create_pool(8, MY_HOST_OR_IP, MY_PORT, MY_TOKEN);
/* Or create a single connection for light operations
  const conn = await rep.connect(MY_HOST_OR_IP, MY_PORT, MY_TOKEN);
*/

/* Disconnect when complete 
  await conn.disconnect();
*/

//************************************************************************************************//
//             Step 2. Create an 'api' instance using the connection pool / connection            //
//************************************************************************************************//

const api = rep.create_api(conn);


//************************************************************************************************//
//                                      Step 3. Use 'api'                                         //
//************************************************************************************************//

//------------------------------------------------------------------------------------------------//
//                          *********** Directory Operations ***********                          //
//------------------------------------------------------------------------------------------------//

// Check if directory exists
const exists = await api.directory.exists('/my_directory');

// List directory contents
await api.directory.list('/', async (remote_path, page_count, get_page) => {
  for (let i = 0; i < page_count; i++) {
    const items = await get_page(i); // Always 'await'
    console.log(items);
  }
});

// Asynchronous directory list
const snap = await api.directory.snapshot('/');
try {
  for (let i = 0; i < snap.page_count; i++) {
    const items = await snap.get_page(i); // Always 'await'
    console.log(items);
  }
} catch (err) {
  console.log(err);
} finally {
  await snap.release();
}

// Create new directory
await api.directory.create('/test');

// Remove existing directory
await api.directory.remove('/test')


//------------------------------------------------------------------------------------------------//
//                            *********** File Operations ***********                             //
//------------------------------------------------------------------------------------------------//

// Check if file exists
const exists = await api.file.exists('/my_file.txt')

// Delete a file
await api.file.delete('/my_file.txt')

// Download a remote file
await api.file.download('/my_file.txt', 'C:\\my_file.txt', progress_cb);

// Download a remote file and overwrite existing local file
await api.file.download('/my_file.txt', 'C:\\my_file.txt', progress_cb, true);

// Resume failed download
await api.file.download('/my_file.txt', 'C:\\my_file.txt', progress_cb, false, true);

// Upload a local file
await api.file.upload('C:\\my_file.txt', '/my_file.txt', progress_cb);

// Upload a local file and overwrite existing remote file
await api.file.upload('C:\\my_file.txt', '/my_file.txt', progress_cb, true);

// Resume failed upload
await api.file.upload('C:\\my_file.txt', '/my_file.txt', progress_cb, false, true);


//------------------------------------------------------------------------------------------------//
//                       *********** Low-Level File Operations ***********                        //
//------------------------------------------------------------------------------------------------//

// Create or open a remote file
{
  const f = await api.file.create_or_open('/my_file.txt');
  await f.close();
}

// Open an existing remote file
{
  const f = await api.file.open('/my_file.txt');
  await f.close();
}

// Write to a file
{
  const f = await api.file.create_or_open('/my_file.txt');

  const b = Buffer.alloc(1);
  b[0] = 1;
  await f.write(0, b); // write '1' byte at file offset '0'

  await f.close();
}

// Read from a file
{
  const f = await api.file.create_or_open('/my_file.txt');
  const b = await f.read(0, 1); // read '1' byte from file offset '0'
  await f.close();
}

// Truncate / resize file
{
  const f = await api.file.create_or_open('/my_file.txt');
  await f.truncate(10);
  await f.close();
}