mirror of
https://github.com/fluencelabs/dweb-transports
synced 2025-04-24 22:32:16 +00:00
commit
003efedb4d
@ -25,7 +25,7 @@ to your package.json file in the dependencies section.
|
||||
### Installation and usage in the Browser
|
||||
* Install npm & node
|
||||
* Clone this repo and cd to it.
|
||||
* `npm bundle` will create dist/dweb_transports_bundle.js
|
||||
* `npm run build` will create dist/dweb_transports_bundle.js
|
||||
* Add `<SCRIPT type="text/javascript" src="dweb_transports_bundle.js"></SCRIPT>` to your `<HEAD>`
|
||||
|
||||
Then code like this should work.
|
||||
|
259
TransportWOLK.js
Normal file
259
TransportWOLK.js
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
This Transport layers uses Wolk NoSQL + Cloudstore.
|
||||
*/
|
||||
const Url = require('url');
|
||||
const WOLK = require('wolkjs').WOLK; //TODO: change to just WOLK once we understand everything
|
||||
const stringify = require('canonical-json');
|
||||
const debug = require('debug')('dweb-transports:wolk');
|
||||
|
||||
// Other Dweb modules
|
||||
const errors = require('./Errors'); // Standard Dweb Errors
|
||||
const Transport = require('./Transport.js'); // Base class for TransportXyz
|
||||
const Transports = require('./Transports'); // Manage all Transports that are loaded
|
||||
const utils = require('./utils'); // Utility functions
|
||||
|
||||
let defaultoptions = {
|
||||
wolk_addr: "http://cloud.wolk.com:81", //"http://c1.wolk.com:80",
|
||||
};
|
||||
|
||||
class TransportWOLK extends Transport {
|
||||
/* Wolk specific transport */
|
||||
constructor(options) {
|
||||
super(options);
|
||||
this.options = options; // Dictionary of options
|
||||
this.wolk = undefined;
|
||||
this.name = "WOLK"; // For console log etc
|
||||
//TODO: Change name to WOLK once we understand everything
|
||||
this.supportURLs = ['wolk'];
|
||||
this.supportFunctions = [ 'fetch', 'store', 'connection', 'get', 'set', 'createReadStream' ];
|
||||
|
||||
this.status = Transport.STATUS_LOADED;
|
||||
}
|
||||
|
||||
connection(url) {
|
||||
console.log("WOLK connection call")
|
||||
var wolknode = new WOLK();
|
||||
//TODO: cloudstore connection needed
|
||||
return wolknode
|
||||
}
|
||||
|
||||
//stuff that happens b/f using ntwk bandwidth (config/connect/stuff)
|
||||
static setup0(options) {
|
||||
let combinedoptions = Transport.mergeoptions(defaultoptions, options.wolk);
|
||||
debug("setup options=%o", combinedoptions);
|
||||
let t = new TransportWOLK(combinedoptions);
|
||||
t.wolk = new WOLK();
|
||||
//var successinit = await Promise.all(t.wolk.init())
|
||||
t.wolk.setProvider(t.options.wolk_addr);
|
||||
Transports.addtransport(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
//make the connection
|
||||
async p_setup1(cb) {
|
||||
await this.wolk.init()
|
||||
.then( async () => {
|
||||
if( this.wolk.ecdsaKey == undefined || this.wolk.ecdsaKey == null ) {
|
||||
var wolkName = "user" + Math.floor((Math.random() * 1000) + 1);
|
||||
console.log("WOLK: createAccount because ecsaKey null")
|
||||
await this.wolk.createAccount(wolkName, (err, hash) => {
|
||||
if(err) { throw new Error("Error Creating Account: " + err); }
|
||||
console.log("[WOLK] Account Created: [" + wolkName + "] hash: " + hash + " KEY: " + this.wolk.ecdsaKey)
|
||||
})
|
||||
}
|
||||
});
|
||||
try {
|
||||
this.status = Transport.STATUS_STARTING; // Should display, but probably not refreshed in most case
|
||||
if (cb) cb(this);
|
||||
await this.p_status();
|
||||
} catch(err) {
|
||||
console.error(this.name, "failed to start" ,err);
|
||||
this.status = Transport.STATUS_FAILED;
|
||||
}
|
||||
if (cb) cb(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
async p_status() {
|
||||
/* Return an integer for the status of a transport see Transport */
|
||||
return this.wolk.getLatestBlockNumber()
|
||||
.then( (bn) => {
|
||||
if (bn >= 0) {
|
||||
console.log("[WOLK] STATUS: connected? [1] = BN: " + bn)
|
||||
this.status = Transport.STATUS_CONNECTED;
|
||||
} else {
|
||||
console.log("[WOLK] STATUS: connected? [0] = BN: " + bn)
|
||||
this.status = Transport.STATUS_FAILED;
|
||||
}
|
||||
return this.status;
|
||||
})
|
||||
.catch( (err) => { console.log("Error getting bn: " + err); })
|
||||
}
|
||||
|
||||
// ===== DATA ======
|
||||
async p_rawstore(chunk) {
|
||||
/*
|
||||
Store a blob of data onto the decentralised transport.
|
||||
Returns a promise that resolves to the url of the data
|
||||
|
||||
:param string|Buffer data: Data to store - no assumptions made to size or content
|
||||
:resolve string: url of data stored
|
||||
*/
|
||||
|
||||
console.assert(chunk, "TransportWOLK.p_rawstore: requires chunkdata");
|
||||
/* TODO:
|
||||
const rawRes = this.wolk.setChunk(chunk);
|
||||
if (rawRes.err) {
|
||||
throw new errors.TransportError("Error encountered storing chunk: " + rawRes.err);
|
||||
}
|
||||
return "wolk://wolk/" + rawRes.h;
|
||||
*/
|
||||
}
|
||||
|
||||
parseWolkUrl(url) {
|
||||
var url = Url.parse(url);
|
||||
if(url.protocol != "wolk:") {
|
||||
throw new errors.TransportError("WOLK Error encountered retrieving val: url (" + url.href + ") is not a valid WOLK url | protocol = " + url.protocol);
|
||||
}
|
||||
let wolkowner = url.host
|
||||
var urlParts = url.path.split("/");
|
||||
let wolkbucket = urlParts[1];
|
||||
let wolkpath = url.path.substring(wolkbucket.length + 2);
|
||||
var wolkurltype = "key"
|
||||
if( wolkowner == "wolk" && wolkbucket == "chunk" ) {
|
||||
wolkurltype = "chunk"
|
||||
}
|
||||
let wolkquery = url.query
|
||||
return { owner: wolkowner, bucket: wolkbucket, path: wolkpath, urltype: wolkurltype, query: wolkquery }
|
||||
}
|
||||
|
||||
async p_rawfetch(url) {
|
||||
var wolkurl = this.parseWolkUrl(url)
|
||||
/*
|
||||
console.log("WOLK p_rawfetch url: " + JSON.stringify(wolkurl));
|
||||
console.log("WOLK owner: " + wolkurl.owner);
|
||||
console.log("WOLK bucket: " + wolkurl.bucket);
|
||||
console.log("WOLK key: " + wolkurl.path);
|
||||
console.log("WOLK query: " + wolkurl.query);
|
||||
console.log("WOLK urltype: " + wolkurl.urltype);
|
||||
*/
|
||||
|
||||
var responseData = ""
|
||||
if( wolkurl.urltype == "key" ) {
|
||||
console.log("[WOLK] Checking Wolk NoSQL for: " + url)
|
||||
return this.wolk.getKey(wolkurl.owner, wolkurl.bucket, wolkurl.path, "latest")
|
||||
.then(function(responseData) {
|
||||
//TODO: error checking
|
||||
console.log("WOLK Response: " + JSON.stringify(responseData));
|
||||
return responseData;
|
||||
})
|
||||
.catch( (err) => {
|
||||
throw new Error("ERROR: p_rawfetch - " + err);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//=======KEY VALUE TABLES ========
|
||||
async p_newdatabase(pubkey) {
|
||||
|
||||
}
|
||||
|
||||
async p_newtable(pubkey, table) {
|
||||
|
||||
}
|
||||
|
||||
async p_set(url, keyvalues, value) {
|
||||
/*
|
||||
Set key values
|
||||
keyvalues: string (key) in which case value should be set there OR object in which case value is ignored
|
||||
*/
|
||||
var wolkurl = this.parseWolkUrl(url)
|
||||
/*
|
||||
console.log("WOLK p_set url: " + JSON.stringify(wolkurl));
|
||||
console.log("WOLK owner: " + wolkurl.owner);
|
||||
console.log("WOLK bucket: " + wolkurl.bucket);
|
||||
console.log("WOLK key: " + wolkurl.path);
|
||||
console.log("WOLK query: " + wolkurl.query);
|
||||
console.log("WOLK urltype: " + wolkurl.urltype);
|
||||
*/
|
||||
if (typeof keyvalues === "string") {
|
||||
return this.wolk.setKey(wolkurl.owner, wolkurl.bucket, keyvalues, stringify(value))
|
||||
.then( (hash) => {
|
||||
return hash;
|
||||
})
|
||||
.catch( (err) => {
|
||||
throw new Error("TransportWOLK - Error setting key value pair: " + err)
|
||||
});
|
||||
} else {
|
||||
// Store all key-value pairs without destroying any other key/value pairs previously set
|
||||
//TODO: Why not support Arrays?
|
||||
console.assert(!Array.isArray(keyvalues), "TransportWOLK - shouldnt be passsing an array as the keyvalues");
|
||||
//TODO: better understand dictionary objects
|
||||
/*
|
||||
table.put(
|
||||
Object.keys(keyvalues).reduce(
|
||||
function(previous, key) {
|
||||
previous[key] = stringify(keyvalues[key]);
|
||||
return previous;
|
||||
},
|
||||
{}
|
||||
)
|
||||
)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
async p_get(url, keys) {
|
||||
var wolkurl = this.parseWolkUrl(url)
|
||||
|
||||
console.log("WOLK: getting url: " + JSON.stringify(wolkurl));
|
||||
/*
|
||||
console.log("WOLK owner: " + wolkurl.owner);
|
||||
console.log("WOLK bucket: " + wolkurl.bucket);
|
||||
console.log("WOLK key: " + wolkurl.path);
|
||||
console.log("WOLK query: " + wolkurl.query);
|
||||
console.log("WOLK urltype: " + wolkurl.urltype);
|
||||
*/
|
||||
if (Array.isArray(keys)) {
|
||||
throw new errors.ToBeImplementedError("p_get(url, [keys]) isn't supported - because of ambiguity better to explicitly loop on set of keys");
|
||||
/*
|
||||
return keys.reduce(function(previous, key) {
|
||||
let val = table.get(key);
|
||||
previous[key] = typeof val === "string" ? JSON.parse(val) : val; // Handle undefined
|
||||
return previous;
|
||||
}, {});
|
||||
*/
|
||||
} else {
|
||||
return this.wolk.getKey(wolkurl.owner, wolkurl.bucket, keys, "latest")
|
||||
.then( (value) => { return value; })
|
||||
.catch( (err) => {
|
||||
throw new errors.TransportError("Error encountered getting keyvalues: " + err);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async p_delete(url, keys) {
|
||||
var wolkurl = this.parseWolkUrl(url)
|
||||
|
||||
if ( typeof keys === "string") {
|
||||
return this.wolk.deleteKey(wolkurl.owner, wolkurl.bucket, keys)
|
||||
.then( (res) => { return res; })
|
||||
.catch( (err) => { throw new errors.TransportError("Error deleting key(s): " + err)})
|
||||
} else {
|
||||
keys.map( (key) => {
|
||||
this.wolk.deleteKey(wolkurl.owner, wolkurl.bucket, key)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async p_keys(url) {
|
||||
var wolkurl = this.parseWolkUrl(url)
|
||||
return this.listCollection(wolkurl.owner, wolkurl.bucket, {})
|
||||
}
|
||||
|
||||
async p_getall(url) {
|
||||
//TODO: difference between this and p_keys
|
||||
}
|
||||
}
|
||||
Transports._transportclasses["WOLK"] = TransportWOLK;
|
||||
exports = module.exports = TransportWOLK;
|
@ -82,6 +82,12 @@ class Transports {
|
||||
// Find an http transport if it exists, so for example YJS can use it.
|
||||
return Transports._connected().find((t) => t.name === "HTTP")
|
||||
}
|
||||
|
||||
static wolk() {
|
||||
// Find a Wolk transport if it exists, so for example YJS can use it.
|
||||
return Transports._connected().find((t) => t.name === "WOLK")
|
||||
}
|
||||
|
||||
static ipfs() {
|
||||
// Find an ipfs transport if it exists, so for example YJS can use it.
|
||||
return Transports._connected().find((t) => t.name === "IPFS")
|
||||
@ -653,7 +659,7 @@ class Transports {
|
||||
let tabbrevs = options.transports; // Array of transport abbreviations
|
||||
this._optionspaused = (options.paused || []).map(n => n.toUpperCase()); // Array of transports paused - defaults to none, upper cased
|
||||
if (!(tabbrevs && tabbrevs.length)) { tabbrevs = options.defaulttransports || [] }
|
||||
if (! tabbrevs.length) { tabbrevs = ["HTTP", "YJS", "IPFS", "WEBTORRENT", "GUN"]; } // SEE-OTHER-ADDTRANSPORT
|
||||
if (! tabbrevs.length) { tabbrevs = ["HTTP", "YJS", "IPFS", "WEBTORRENT", "GUN", "WOLK"]; } // SEE-OTHER-ADDTRANSPORT
|
||||
tabbrevs = tabbrevs.map(n => n.toUpperCase());
|
||||
let transports = this.setup0(tabbrevs, options);
|
||||
["statuscb", "mirror"].forEach(k => { if (options[k]) this[k] = options[k];} )
|
||||
@ -662,13 +668,13 @@ class Transports {
|
||||
while (statuselement.lastChild) {statuselement.removeChild(statuselement.lastChild); } // Remove any exist status
|
||||
statuselement.appendChild(
|
||||
utils.createElement("UL", {}, transports.map(t => {
|
||||
let el = utils.createElement("LI",
|
||||
let el = utils.createElement("LI",
|
||||
{onclick: "this.source.togglePaused(DwebTransports.refreshstatus);", source: t, name: t.name}, //TODO-SW figure out how t osend this back
|
||||
t.name);
|
||||
t.statuselement = el; // Save status element on transport
|
||||
return el;
|
||||
}
|
||||
)));
|
||||
t.statuselement = el; // Save status element on transport
|
||||
return el;
|
||||
}))
|
||||
);
|
||||
}
|
||||
await this.p_setup1(this.refreshstatus);
|
||||
await this.p_setup2(this.refreshstatus);
|
||||
@ -710,8 +716,8 @@ class Transports {
|
||||
*/
|
||||
if (typeof url !== "string") url = Url.parse(url).href;
|
||||
// In patterns below http or https; and :/ or :// are treated the same
|
||||
const gateways = ["dweb.me", "ipfs.io"]; // Kniwn gateways, may dynamically load this at some point
|
||||
const protocols = ["ipfs","gun","magnet","yjs","arc", "contenthash", "http", "https"];
|
||||
const gateways = ["dweb.me", "ipfs.io"]; // Known gateways, may dynamically load this at some point
|
||||
const protocols = ["ipfs","gun","magnet","yjs","wolk","arc", "contenthash", "http", "https"];
|
||||
const protocolsWantingDomains = ["arc", "http", "https"];
|
||||
const gatewaypatts = [ // Must be before patts because gateway names often start with a valid proto
|
||||
/^http[s]?:[/]+([^/]+)[/](\w+)[/](.*)/i, // https://(gateway)/proto/(internal) + gateway in list (IPFS gateways. dweb.me)
|
||||
|
1
index.js
1
index.js
@ -6,6 +6,7 @@ require("./TransportHTTP.js"); // Can access via window.DwebTransports._transp
|
||||
require("./TransportIPFS.js");
|
||||
require("./TransportYJS.js");
|
||||
require("./TransportWEBTORRENT.js");
|
||||
require("./TransportWOLK.js");
|
||||
require("./TransportGUN.js");
|
||||
if (typeof window !== "undefined") { window.DwebTransports = DwebTransports; }
|
||||
exports = module.exports = DwebTransports;
|
||||
|
@ -1,4 +1,6 @@
|
||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
const webpack = require('webpack'); //to access built-in plugins
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
'dweb-transports': './index.js',
|
||||
@ -20,9 +22,16 @@ module.exports = {
|
||||
console: false
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new webpack.EnvironmentPlugin({
|
||||
WOLK_ENV: 'idb',
|
||||
})
|
||||
],
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
zlib: 'browserify-zlib-next'
|
||||
zlib: 'browserify-zlib-next',
|
||||
zlib: 'zlib'
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
@ -39,4 +48,4 @@ module.exports = {
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user