mirror of
https://github.com/falk-werner/webfuse-provider
synced 2026-03-02 04:09:18 +00:00
extracted JavaScript provider API
This commit is contained in:
15
example/daemon/www/js/wsfs/bad_state.js
Normal file
15
example/daemon/www/js/wsfs/bad_state.js
Normal file
@@ -0,0 +1,15 @@
|
||||
export class BadState extends Error {
|
||||
static get BAD() { return 1; }
|
||||
|
||||
static get NOT_IMPLEMENTED() { return 2; }
|
||||
static get TIMEOUT() { return 3; }
|
||||
static get FORMAT() { return 4; }
|
||||
|
||||
static get NO_ENTRY() { return 101; }
|
||||
static get NO_ACCESS() { return 102; }
|
||||
|
||||
constructor(code) {
|
||||
super("Bad State");
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
156
example/daemon/www/js/wsfs/client.js
Normal file
156
example/daemon/www/js/wsfs/client.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import { BadState } from "./bad_state.js";
|
||||
|
||||
export class Client {
|
||||
static get _PROTOCOL() { return "fs"; }
|
||||
|
||||
constructor(provider) {
|
||||
this._provider = provider;
|
||||
this._ws = null;
|
||||
this.isConnected = false;
|
||||
}
|
||||
|
||||
connectTo(url) {
|
||||
this.disconnect();
|
||||
|
||||
this._ws = new WebSocket(url, Client._PROTOCOL);
|
||||
this._ws.onopen = () => {
|
||||
this.isConnected = true;
|
||||
this._provider.connected();
|
||||
};
|
||||
this._ws.onclose = () => {
|
||||
this.isConnected = false;
|
||||
this._provider.disconnected();
|
||||
};
|
||||
this._ws.onmessage = (message) => {
|
||||
this._onmessage(message);
|
||||
};
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this._ws) {
|
||||
this._ws.close();
|
||||
}
|
||||
}
|
||||
|
||||
_onmessage(message) {
|
||||
try {
|
||||
const request = JSON.parse(message.data);
|
||||
const method = request.method;
|
||||
const id = request.id;
|
||||
const params = request.params;
|
||||
|
||||
if ("string" !== typeof(method)) {
|
||||
throw new Error("parse error: missing field: \"method\"");
|
||||
}
|
||||
|
||||
if (!params) {
|
||||
throw new Error("parse error: missing field: \"params\"");
|
||||
}
|
||||
|
||||
if ("number" === typeof(request.id)) {
|
||||
this._invoke(method, params, id);
|
||||
}
|
||||
else {
|
||||
this._notify(method, params);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// swallow
|
||||
}
|
||||
}
|
||||
|
||||
_invoke(method, params, id) {
|
||||
this._invokeAsync(method, params).then((result) => {
|
||||
const response = { result, id };
|
||||
this._ws.send(JSON.stringify(response));
|
||||
}).
|
||||
catch((ex) => {
|
||||
const code = ex.code || BadState.BAD;
|
||||
const response = {error: {code}, id};
|
||||
this._ws.send(JSON.stringify(response));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async _invokeAsync(method, params) {
|
||||
switch(method)
|
||||
{
|
||||
case "lookup":
|
||||
return this._lookup(params);
|
||||
case "getattr":
|
||||
return this._getattr(params);
|
||||
case "readdir":
|
||||
return this._readdir(params);
|
||||
case "open":
|
||||
return this._open(params);
|
||||
case "read":
|
||||
return this._read(params);
|
||||
default:
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
|
||||
_notify(method, params) {
|
||||
switch(method) {
|
||||
case 'close':
|
||||
this._close(params);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid method: "${method}"`);
|
||||
}
|
||||
}
|
||||
|
||||
async _lookup(params) {
|
||||
const parent = params[0];
|
||||
const name = params[1];
|
||||
|
||||
return this._provider.lookup(parent, name);
|
||||
}
|
||||
|
||||
async _getattr(params) {
|
||||
const inode = params[0];
|
||||
|
||||
return this._provider.getattr(inode);
|
||||
}
|
||||
|
||||
async _readdir(params) {
|
||||
const inode = params[0];
|
||||
|
||||
return this._provider.readdir(inode);
|
||||
}
|
||||
|
||||
async _open(params) {
|
||||
const inode = params[0];
|
||||
const mode = params[1];
|
||||
|
||||
return this._provider.open(inode, mode);
|
||||
}
|
||||
|
||||
_close(params) {
|
||||
const inode = params[0];
|
||||
const handle = params[1];
|
||||
const mode = params[2];
|
||||
|
||||
this._provider.close(inode, handle, mode);
|
||||
}
|
||||
|
||||
async _read(params) {
|
||||
const inode = params[0];
|
||||
const handle = params[1];
|
||||
const offset = params[2];
|
||||
const length = params[3];
|
||||
|
||||
const data = await this._provider.read(inode, handle, offset, length);
|
||||
|
||||
if ("string" === typeof(data)) {
|
||||
return {
|
||||
data: btoa(data),
|
||||
format: "base64",
|
||||
count: data.length
|
||||
};
|
||||
}
|
||||
else {
|
||||
throw new BadState(BadState.BAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
example/daemon/www/js/wsfs/file_mode.js
Normal file
10
example/daemon/www/js/wsfs/file_mode.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export class FileMode {
|
||||
static get ACCESS_MODE() { return 0x003; }
|
||||
static get READONLY() { return 0x000; }
|
||||
static get WRITEONLY() { return 0x001; }
|
||||
static get READWRITE() { return 0x002; }
|
||||
static get CREATE() { return 0x040; }
|
||||
static get EXCLUSIVE() { return 0x080; }
|
||||
static get TRUNKATE() { return 0x200; }
|
||||
static get APPEND() { return 0x400; }
|
||||
}
|
||||
38
example/daemon/www/js/wsfs/provider.js
Normal file
38
example/daemon/www/js/wsfs/provider.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
|
||||
|
||||
import { BadState } from "./bad_state.js";
|
||||
|
||||
export class Provider {
|
||||
|
||||
connected() {
|
||||
// empty
|
||||
}
|
||||
|
||||
disconnected() {
|
||||
// empty
|
||||
}
|
||||
|
||||
async lookup(_parent, _name) {
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
async getattr(_inode) {
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
async readdir(_inode) {
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
async open(_inode, _mode) {
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
close(_inode, _handle, _mode) {
|
||||
// empty
|
||||
}
|
||||
|
||||
async read(_inode, _handle, _offset, _length) {
|
||||
throw new BadState(BadState.NOT_IMPLEMENTED);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user