Select Git revision
webconnect.mjs

Volker Schukai authored
webconnect.mjs 5.29 KiB
/**
* Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*
* SPDX-License-Identifier: AGPL-3.0
*/
import { internalSymbol, instanceSymbol } from "../../../constants.mjs";
import { isString, isObject } from "../../../types/is.mjs";
import { WebConnect as NetWebConnect } from "../../../net/webconnect.mjs";
import { Message } from "../../../net/webconnect/message.mjs";
import { Server } from "../server.mjs";
export { WebConnect };
/**
* @private
* @type {symbol}
*
* hint: this name is used in the tests. if you want to change it, please change it in the tests as well.
*/
const webConnectSymbol = Symbol("connection");
/**
* The RestAPI is a class that enables a REST API server.
*
* @externalExample ../../../../example/data/datasource/server/webconnect.mjs
* @license AGPLv3
* @since 3.1.0
* @copyright schukai GmbH
* @summary The LocalStorage class encapsulates the access to data objects.
*/
class WebConnect extends Server {
/**
*
* @param {Object} [options] options contains definitions for the datasource.
*/
constructor(options) {
super();
if (isString(options)) {
options = { url: options };
}
if (!isObject(options)) options = {};
this.setOptions(options);
this[webConnectSymbol] = new NetWebConnect({
url: this.getOption("url"),
connection: {
timeout: this.getOption("connection.timeout"),
reconnect: {
timeout: this.getOption("connection.reconnect.timeout"),
attempts: this.getOption("connection.reconnect.attempts"),
enabled: this.getOption("connection.reconnect.enabled"),
},
},
});
}
/**
*
* @return {Promise}
*/
connect() {
return this[webConnectSymbol].connect();
}
/**
* @return {boolean}
*/
isConnected() {
return this[webConnectSymbol].isConnected();
}
/**
* This method is called by the `instanceof` operator.
* @return {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/data/datasource/server/webconnect");
}
/**
* @property {string} url=undefined Defines the resource that you wish to fetch.
* @property {Object} connection
* @property {Object} connection.timeout=5000 Defines the timeout for the connection.
* @property {Number} connection.reconnect.timeout The timeout in milliseconds for the reconnect.
* @property {Number} connection.reconnect.attempts The maximum number of reconnects.
* @property {Bool} connection.reconnect.enabled If the reconnect is enabled.
* @property {Object} write={} Options
* @property {Object} write.mapping the mapping is applied before writing.
* @property {String} write.mapping.transformer Transformer to select the appropriate entries
* @property {Monster.Data.Datasource~exampleCallback[]} write.mapping.callback with the help of the callback, the structures can be adjusted before writing.
* @property {Object} write.sheathing
* @property {Object} write.sheathing.object Object to be wrapped
* @property {string} write.sheathing.path Path to the data
* @property {Object} read={} Options
* @property {String} read.path Path to data
* @property {Object} read.mapping the mapping is applied after reading.
* @property {String} read.mapping.transformer Transformer to select the appropriate entries
* @property {Monster.Data.Datasource~exampleCallback[]} read.mapping.callback with the help of the callback, the structures can be adjusted after reading.
*/
get defaults() {
return Object.assign({}, super.defaults, {
url: undefined,
write: {
mapping: {
transformer: undefined,
callbacks: {},
},
sheathing: {
object: undefined,
path: undefined,
},
},
read: {
mapping: {
transformer: undefined,
callbacks: {},
},
path: undefined,
},
connection: {
timeout: 5000,
reconnect: {
timeout: 1000,
attempts: 1,
enabled: false,
},
},
});
}
/**
* This method closes the connection.
*
* @return {Promise}
*/
close() {
return this[webConnectSymbol].close();
}
/**
* @return {Promise}
*/
read() {
return new Promise((resolve, reject) => {
while (this[webConnectSymbol].dataReceived() === true) {
let obj = this[webConnectSymbol].poll();
if (!isObject(obj)) {
reject(new Error("The received data is not an object."));
return;
}
if (!(obj instanceof Message)) {
reject(new Error("The received data is not a Message."));
return;
}
obj = obj.getData();
obj = this.transformServerPayload.call(this, obj);
this.set(obj);
}
resolve(this.get());
});
}
/**
* @return {Promise}
*/
write() {
const obj = this.prepareServerPayload(this.get());
return this[webConnectSymbol].send(obj);
}
/**
* @return {RestAPI}
*/
getClone() {
return new WebConnect(this[internalSymbol].getRealSubject()["options"]);
}
}