Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • oss/libraries/javascript/monster
1 result
Select Git revision
Loading items
Show changes
Commits on Source (5)
Showing
with 247 additions and 325 deletions
<a name="v3.6.0"></a>
## [v3.6.0] - 2023-01-26
### Add Features
- add rome and do linting
### Changes
- code format rome
<a name="v3.5.0"></a> <a name="v3.5.0"></a>
## [v3.5.0] - 2023-01-23 ## [v3.5.0] - 2023-01-23
### Add Features ### Add Features
...@@ -203,6 +212,7 @@ ...@@ -203,6 +212,7 @@
<a name="1.8.0"></a> <a name="1.8.0"></a>
## 1.8.0 - 2021-08-15 ## 1.8.0 - 2021-08-15
[v3.6.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.5.0...v3.6.0
[v3.5.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.2...v3.5.0 [v3.5.0]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.2...v3.5.0
[v3.4.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.1...v3.4.2 [v3.4.2]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.1...v3.4.2
[v3.4.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.0...v3.4.1 [v3.4.1]: https://gitlab.schukai.com/oss/libraries/javascript/monster/compare/v3.4.0...v3.4.1
......
{ {
"name": "@schukai/monster", "name": "@schukai/monster",
"version": "3.4.2", "version": "3.5.0",
"description": "Monster is a simple library for creating fast, robust and lightweight websites.", "description": "Monster is a simple library for creating fast, robust and lightweight websites.",
"keywords": [ "keywords": [
"framework", "framework",
......
...@@ -8,11 +8,7 @@ ...@@ -8,11 +8,7 @@
* @author schukai GmbH * @author schukai GmbH
*/ */
export { export { internalSymbol, internalStateSymbol, instanceSymbol };
internalSymbol,
internalStateSymbol,
instanceSymbol
}
/** /**
* @private * @private
...@@ -21,7 +17,7 @@ export { ...@@ -21,7 +17,7 @@ export {
* @license AGPLv3 * @license AGPLv3
* @since 1.24.0 * @since 1.24.0
*/ */
const internalSymbol = Symbol.for('@schukai/monster/internal'); const internalSymbol = Symbol.for("@schukai/monster/internal");
/** /**
* @private * @private
...@@ -30,11 +26,10 @@ const internalSymbol = Symbol.for('@schukai/monster/internal'); ...@@ -30,11 +26,10 @@ const internalSymbol = Symbol.for('@schukai/monster/internal');
* @license AGPLv3 * @license AGPLv3
* @since 1.25.0 * @since 1.25.0
*/ */
const internalStateSymbol = Symbol.for('@schukai/monster/state'); const internalStateSymbol = Symbol.for("@schukai/monster/state");
/** /**
* @private * @private
* @type {symbol} * @type {symbol}
*/ */
const instanceSymbol = Symbol.for('@schukai/monster/instance'); const instanceSymbol = Symbol.for("@schukai/monster/instance");
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
*/ */
import {Base} from '../types/base.mjs'; import { Base } from "../types/base.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {AbstractConstraint} export { AbstractConstraint };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -26,7 +26,6 @@ export {AbstractConstraint} ...@@ -26,7 +26,6 @@ export {AbstractConstraint}
* @summary The abstract constraint * @summary The abstract constraint
*/ */
class AbstractConstraint extends Base { class AbstractConstraint extends Base {
/** /**
* *
*/ */
...@@ -52,5 +51,4 @@ class AbstractConstraint extends Base { ...@@ -52,5 +51,4 @@ class AbstractConstraint extends Base {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/abstract-constraint"); return Symbol.for("@schukai/monster/constraints/abstract-constraint");
} }
} }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
*/ */
import { AbstractConstraint } from "./abstract.mjs"; import { AbstractConstraint } from "./abstract.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {AbstractOperator} export { AbstractOperator };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -24,7 +24,6 @@ export {AbstractOperator} ...@@ -24,7 +24,6 @@ export {AbstractOperator}
* @summary The abstract operator constraint * @summary The abstract operator constraint
*/ */
class AbstractOperator extends AbstractConstraint { class AbstractOperator extends AbstractConstraint {
/** /**
* *
* @param {AbstractConstraint} operantA * @param {AbstractConstraint} operantA
...@@ -34,13 +33,12 @@ class AbstractOperator extends AbstractConstraint { ...@@ -34,13 +33,12 @@ class AbstractOperator extends AbstractConstraint {
constructor(operantA, operantB) { constructor(operantA, operantB) {
super(); super();
if (!(operantA instanceof AbstractConstraint) || !(operantB instanceof AbstractConstraint)) { if (!(operantA instanceof AbstractConstraint && operantB instanceof AbstractConstraint)) {
throw new TypeError("parameters must be from type AbstractConstraint") throw new TypeError("parameters must be from type AbstractConstraint");
} }
this.operantA = operantA; this.operantA = operantA;
this.operantB = operantB; this.operantB = operantB;
} }
/** /**
...@@ -51,8 +49,4 @@ class AbstractOperator extends AbstractConstraint { ...@@ -51,8 +49,4 @@ class AbstractOperator extends AbstractConstraint {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/abstract-operator"); return Symbol.for("@schukai/monster/constraints/abstract-operator");
} }
} }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
*/ */
import { AbstractOperator } from "./abstractoperator.mjs"; import { AbstractOperator } from "./abstractoperator.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {AndOperator} export { AndOperator };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -24,7 +24,6 @@ export {AndOperator} ...@@ -24,7 +24,6 @@ export {AndOperator}
* @summary A and operator constraint * @summary A and operator constraint
*/ */
class AndOperator extends AbstractOperator { class AndOperator extends AbstractOperator {
/** /**
* this method return a promise containing the result of the check. * this method return a promise containing the result of the check.
* *
...@@ -43,6 +42,4 @@ class AndOperator extends AbstractOperator { ...@@ -43,6 +42,4 @@ class AndOperator extends AbstractOperator {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/and-operator"); return Symbol.for("@schukai/monster/constraints/and-operator");
} }
} }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
*/ */
import { AbstractConstraint } from "./abstract.mjs"; import { AbstractConstraint } from "./abstract.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {Invalid} export { Invalid };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -24,7 +24,6 @@ export {Invalid} ...@@ -24,7 +24,6 @@ export {Invalid}
* @summary A constraint that always invalid * @summary A constraint that always invalid
*/ */
class Invalid extends AbstractConstraint { class Invalid extends AbstractConstraint {
/** /**
* this method return a rejected promise * this method return a rejected promise
* *
...@@ -43,6 +42,4 @@ class Invalid extends AbstractConstraint { ...@@ -43,6 +42,4 @@ class Invalid extends AbstractConstraint {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/invalid"); return Symbol.for("@schukai/monster/constraints/invalid");
} }
} }
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
import { isArray } from "../types/is.mjs"; import { isArray } from "../types/is.mjs";
import { AbstractConstraint } from "./abstract.mjs"; import { AbstractConstraint } from "./abstract.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {IsArray} export { IsArray };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -23,7 +23,6 @@ export {IsArray} ...@@ -23,7 +23,6 @@ export {IsArray}
* @summary A constraint to check if a value is an array * @summary A constraint to check if a value is an array
*/ */
class IsArray extends AbstractConstraint { class IsArray extends AbstractConstraint {
/** /**
* this method return a promise containing the result of the check. * this method return a promise containing the result of the check.
* *
...@@ -46,6 +45,4 @@ class IsArray extends AbstractConstraint { ...@@ -46,6 +45,4 @@ class IsArray extends AbstractConstraint {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraint/is-array"); return Symbol.for("@schukai/monster/constraint/is-array");
} }
} }
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
import { isObject } from "../types/is.mjs"; import { isObject } from "../types/is.mjs";
import { AbstractConstraint } from "./abstract.mjs"; import { AbstractConstraint } from "./abstract.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {IsObject} export { IsObject };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -23,7 +23,6 @@ export {IsObject} ...@@ -23,7 +23,6 @@ export {IsObject}
* @summary A constraint to check if a value is an object * @summary A constraint to check if a value is an object
*/ */
class IsObject extends AbstractConstraint { class IsObject extends AbstractConstraint {
/** /**
* this method return a promise containing the result of the check. * this method return a promise containing the result of the check.
* *
...@@ -46,6 +45,4 @@ class IsObject extends AbstractConstraint { ...@@ -46,6 +45,4 @@ class IsObject extends AbstractConstraint {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraint/is-object"); return Symbol.for("@schukai/monster/constraint/is-object");
} }
} }
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
* SPDX-License-Identifier: AGPL-3.0 * SPDX-License-Identifier: AGPL-3.0
*/ */
/** /**
* Constraints are used to define conditions that must be met by the value of a variable so that the value can be transferred to the system. * Constraints are used to define conditions that must be met by the value of a variable so that the value can be transferred to the system.
* *
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
*/ */
import { AbstractOperator } from "./abstractoperator.mjs"; import { AbstractOperator } from "./abstractoperator.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {OrOperator} export { OrOperator };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -24,7 +24,6 @@ export {OrOperator} ...@@ -24,7 +24,6 @@ export {OrOperator}
* @summary A or operator * @summary A or operator
*/ */
class OrOperator extends AbstractOperator { class OrOperator extends AbstractOperator {
/** /**
* this method return a promise containing the result of the check. * this method return a promise containing the result of the check.
* *
...@@ -35,12 +34,15 @@ class OrOperator extends AbstractOperator { ...@@ -35,12 +34,15 @@ class OrOperator extends AbstractOperator {
var self = this; var self = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
let a, b; let a;
let b;
self.operantA.isValid(value) self.operantA
.isValid(value)
.then(function () { .then(function () {
resolve(); resolve();
}).catch(function () { })
.catch(function () {
a = false; a = false;
/** b has already been evaluated and was not true */ /** b has already been evaluated and was not true */
if (b === false) { if (b === false) {
...@@ -48,10 +50,12 @@ class OrOperator extends AbstractOperator { ...@@ -48,10 +50,12 @@ class OrOperator extends AbstractOperator {
} }
}); });
self.operantB.isValid(value) self.operantB
.isValid(value)
.then(function () { .then(function () {
resolve(); resolve();
}).catch(function () { })
.catch(function () {
b = false; b = false;
/** b has already been evaluated and was not true */ /** b has already been evaluated and was not true */
if (a === false) { if (a === false) {
...@@ -69,7 +73,4 @@ class OrOperator extends AbstractOperator { ...@@ -69,7 +73,4 @@ class OrOperator extends AbstractOperator {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/or-operator"); return Symbol.for("@schukai/monster/constraints/or-operator");
} }
} }
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
*/ */
import { AbstractConstraint } from "./abstract.mjs"; import { AbstractConstraint } from "./abstract.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
export {Valid} export { Valid };
/** /**
* Constraints are used to define conditions that must be met by the value of a variable. * Constraints are used to define conditions that must be met by the value of a variable.
...@@ -24,7 +24,6 @@ export {Valid} ...@@ -24,7 +24,6 @@ export {Valid}
* @summary A constraint that always valid * @summary A constraint that always valid
*/ */
class Valid extends AbstractConstraint { class Valid extends AbstractConstraint {
/** /**
* this method return a promise containing the result of the check. * this method return a promise containing the result of the check.
* *
...@@ -43,6 +42,4 @@ class Valid extends AbstractConstraint { ...@@ -43,6 +42,4 @@ class Valid extends AbstractConstraint {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/constraints/valid"); return Symbol.for("@schukai/monster/constraints/valid");
} }
} }
...@@ -10,14 +10,13 @@ import {validateString} from "../types/validate.mjs"; ...@@ -10,14 +10,13 @@ import {validateString} from "../types/validate.mjs";
import { clone } from "../util/clone.mjs"; import { clone } from "../util/clone.mjs";
import { DELIMITER, Pathfinder, WILDCARD } from "./pathfinder.mjs"; import { DELIMITER, Pathfinder, WILDCARD } from "./pathfinder.mjs";
export {buildMap, PARENT, assembleParts} export { buildMap, PARENT, assembleParts };
/** /**
* @type {string} * @type {string}
* @memberOf Monster.Data * @memberOf Monster.Data
*/ */
const PARENT = '^'; const PARENT = "^";
/** /**
* With the help of the function `buildMap()`, maps can be easily created from data objects. * With the help of the function `buildMap()`, maps can be easily created from data objects.
...@@ -47,10 +46,8 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) { ...@@ -47,10 +46,8 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
v = build(v, valueTemplate); v = build(v, valueTemplate);
this.set(k, v); this.set(k, v);
}); });
} }
/** /**
* @private * @private
* @param {*} subject * @param {*} subject
...@@ -61,20 +58,19 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) { ...@@ -61,20 +58,19 @@ function buildMap(subject, selector, valueTemplate, keyTemplate, filter) {
* @throws {TypeError} selector is neither a string nor a function * @throws {TypeError} selector is neither a string nor a function
*/ */
function assembleParts(subject, selector, filter, callback) { function assembleParts(subject, selector, filter, callback) {
const result = new Map(); const result = new Map();
let map; let map;
if (isFunction(selector)) { if (isFunction(selector)) {
map = selector(subject) map = selector(subject);
if (!(map instanceof Map)) { if (!(map instanceof Map)) {
throw new TypeError('the selector callback must return a map'); throw new TypeError("the selector callback must return a map");
} }
} else if (isString(selector)) { } else if (isString(selector)) {
map = new Map; map = new Map();
buildFlatMap.call(map, subject, selector); buildFlatMap.call(map, subject, selector);
} else { } else {
throw new TypeError('selector is neither a string nor a function') throw new TypeError("selector is neither a string nor a function");
} }
if (!(map instanceof Map)) { if (!(map instanceof Map)) {
...@@ -87,7 +83,6 @@ function assembleParts(subject, selector, filter, callback) { ...@@ -87,7 +83,6 @@ function assembleParts(subject, selector, filter, callback) {
} }
callback.call(result, v, k, m); callback.call(result, v, k, m);
}); });
return result; return result;
...@@ -102,23 +97,21 @@ function assembleParts(subject, selector, filter, callback) { ...@@ -102,23 +97,21 @@ function assembleParts(subject, selector, filter, callback) {
* @return {*} * @return {*}
*/ */
function buildFlatMap(subject, selector, key, parentMap) { function buildFlatMap(subject, selector, key, parentMap) {
const result = this; const result = this;
const currentMap = new Map; const currentMap = new Map();
const resultLength = result.size; const resultLength = result.size;
if (key === undefined) key = []; if (key === undefined) key = [];
let parts = selector.split(DELIMITER); let parts = selector.split(DELIMITER);
let current = "", currentPath = []; let current = "";
let currentPath = [];
do { do {
current = parts.shift(); current = parts.shift();
currentPath.push(current); currentPath.push(current);
if (current === WILDCARD) { if (current === WILDCARD) {
let finder = new Pathfinder(subject); let finder = new Pathfinder(subject);
let map; let map;
...@@ -130,12 +123,11 @@ function buildFlatMap(subject, selector, key, parentMap) { ...@@ -130,12 +123,11 @@ function buildFlatMap(subject, selector, key, parentMap) {
} }
for (const [k, o] of map) { for (const [k, o] of map) {
let copyKey = clone(key); let copyKey = clone(key);
currentPath.map((a) => { currentPath.map((a) => {
copyKey.push((a === WILDCARD) ? k : a) copyKey.push(a === WILDCARD ? k : a);
}) });
let kk = copyKey.join(DELIMITER); let kk = copyKey.join(DELIMITER);
let sub = buildFlatMap.call(result, o, parts.join(DELIMITER), copyKey, o); let sub = buildFlatMap.call(result, o, parts.join(DELIMITER), copyKey, o);
...@@ -146,10 +138,7 @@ function buildFlatMap(subject, selector, key, parentMap) { ...@@ -146,10 +138,7 @@ function buildFlatMap(subject, selector, key, parentMap) {
currentMap.set(kk, sub); currentMap.set(kk, sub);
} }
} }
} while (parts.length > 0); } while (parts.length > 0);
// no set in child run // no set in child run
...@@ -160,10 +149,8 @@ function buildFlatMap(subject, selector, key, parentMap) { ...@@ -160,10 +149,8 @@ function buildFlatMap(subject, selector, key, parentMap) {
} }
return subject; return subject;
} }
/** /**
* With the help of this filter callback, values can be filtered out. Only if the filter function returns true, the value is taken for the map. * With the help of this filter callback, values can be filtered out. Only if the filter function returns true, the value is taken for the map.
* *
...@@ -318,7 +305,7 @@ function build(subject, definition, defaultValue) { ...@@ -318,7 +305,7 @@ function build(subject, definition, defaultValue) {
if (definition === undefined) return defaultValue ? defaultValue : subject; if (definition === undefined) return defaultValue ? defaultValue : subject;
validateString(definition); validateString(definition);
const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm const regexp = /(?<placeholder>\${(?<path>[a-z\^A-Z.\-_0-9]*)})/gm;
const array = [...definition.matchAll(regexp)]; const array = [...definition.matchAll(regexp)];
let finder = new Pathfinder(subject); let finder = new Pathfinder(subject);
...@@ -328,20 +315,17 @@ function build(subject, definition, defaultValue) { ...@@ -328,20 +315,17 @@ function build(subject, definition, defaultValue) {
} }
array.forEach((a) => { array.forEach((a) => {
let groups = a?.['groups']; let groups = a?.["groups"];
let placeholder = groups?.['placeholder'] let placeholder = groups?.["placeholder"];
if (placeholder === undefined) return; if (placeholder === undefined) return;
let path = groups?.['path'] let path = groups?.["path"];
let v = finder.getVia(path); let v = finder.getVia(path);
if (v === undefined) v = defaultValue; if (v === undefined) v = defaultValue;
definition = definition.replaceAll(placeholder, v); definition = definition.replaceAll(placeholder, v);
});
})
return definition; return definition;
} }
...@@ -11,19 +11,19 @@ import {NodeList} from "../types/nodelist.mjs"; ...@@ -11,19 +11,19 @@ import {NodeList} from "../types/nodelist.mjs";
import { assembleParts } from "./buildmap.mjs"; import { assembleParts } from "./buildmap.mjs";
import { extend } from "./extend.mjs"; import { extend } from "./extend.mjs";
export {buildTree} export { buildTree };
/** /**
* @private * @private
* @type {symbol} * @type {symbol}
*/ */
const parentSymbol = Symbol('parent'); const parentSymbol = Symbol("parent");
/** /**
* @private * @private
* @type {symbol} * @type {symbol}
*/ */
const rootSymbol = Symbol('root'); const rootSymbol = Symbol("root");
/** /**
* @typedef {Object} buildTreeOptions * @typedef {Object} buildTreeOptions
...@@ -49,17 +49,20 @@ const rootSymbol = Symbol('root'); ...@@ -49,17 +49,20 @@ const rootSymbol = Symbol('root');
* @since 1.26.0 * @since 1.26.0
*/ */
function buildTree(subject, selector, idKey, parentIDKey, options) { function buildTree(subject, selector, idKey, parentIDKey, options) {
const nodes = new Map();
const nodes = new Map;
if (!isObject(options)) { if (!isObject(options)) {
options = {} options = {};
} }
options = extend({}, { options = extend(
{},
{
rootReferences: [null, undefined], rootReferences: [null, undefined],
filter: undefined filter: undefined,
}, options) },
options,
);
const filter = options?.filter; const filter = options?.filter;
let rootReferences = options.rootReferences; let rootReferences = options.rootReferences;
...@@ -68,13 +71,12 @@ function buildTree(subject, selector, idKey, parentIDKey, options) { ...@@ -68,13 +71,12 @@ function buildTree(subject, selector, idKey, parentIDKey, options) {
} }
const childMap = assembleParts(subject, selector, filter, function (o, k, m) { const childMap = assembleParts(subject, selector, filter, function (o, k, m) {
const key = o?.[idKey];
const key = o?.[idKey] let ref = o?.[parentIDKey];
let ref = o?.[parentIDKey]
if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol; if (rootReferences.indexOf(ref) !== -1) ref = rootSymbol;
if (key === undefined) { if (key === undefined) {
throw new Error('the object has no value for the specified id') throw new Error("the object has no value for the specified id");
} }
o[parentSymbol] = ref; o[parentSymbol] = ref;
...@@ -82,28 +84,26 @@ function buildTree(subject, selector, idKey, parentIDKey, options) { ...@@ -82,28 +84,26 @@ function buildTree(subject, selector, idKey, parentIDKey, options) {
const node = new Node(o); const node = new Node(o);
this.has(ref) ? this.get(ref).add(node) : this.set(ref, new NodeList().add(node)); this.has(ref) ? this.get(ref).add(node) : this.set(ref, new NodeList().add(node));
nodes.set(key, node); nodes.set(key, node);
});
}) nodes.forEach((node) => {
let id = node?.["value"]?.[idKey];
nodes.forEach(node => {
let id = node?.['value']?.[idKey];
if (childMap.has(id)) { if (childMap.has(id)) {
node.childNodes = childMap.get(id); node.childNodes = childMap.get(id);
childMap.delete(id) childMap.delete(id);
} }
}) });
const list = new NodeList; const list = new NodeList();
childMap.forEach((s) => { childMap.forEach((s) => {
if (s instanceof Set) { if (s instanceof Set) {
s.forEach((n) => { s.forEach((n) => {
list.add(n); list.add(n);
}) });
} }
}) });
return list; return list;
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
*/ */
import { internalSymbol } from "../constants.mjs"; import { internalSymbol } from "../constants.mjs";
import {instanceSymbol} from '../constants.mjs'; import { instanceSymbol } from "../constants.mjs";
import { Base } from "../types/base.mjs"; import { Base } from "../types/base.mjs";
import { parseDataURL } from "../types/dataurl.mjs"; import { parseDataURL } from "../types/dataurl.mjs";
import { isString } from "../types/is.mjs"; import { isString } from "../types/is.mjs";
...@@ -15,8 +15,7 @@ import {validateObject} from "../types/validate.mjs"; ...@@ -15,8 +15,7 @@ import {validateObject} from "../types/validate.mjs";
import { extend } from "./extend.mjs"; import { extend } from "./extend.mjs";
import { Pathfinder } from "./pathfinder.mjs"; import { Pathfinder } from "./pathfinder.mjs";
export {Datasource} export { Datasource };
/** /**
* This callback can be passed to a datasource and is used to adapt data structures. * This callback can be passed to a datasource and is used to adapt data structures.
...@@ -28,7 +27,6 @@ export {Datasource} ...@@ -28,7 +27,6 @@ export {Datasource}
* @see Monster.Data.Datasource * @see Monster.Data.Datasource
*/ */
/** /**
* @private * @private
* @type {symbol} * @type {symbol}
...@@ -36,7 +34,7 @@ export {Datasource} ...@@ -36,7 +34,7 @@ export {Datasource}
* @license AGPLv3 * @license AGPLv3
* @since 1.24.0 * @since 1.24.0
*/ */
const internalDataSymbol = Symbol.for('@schukai/monster/data/datasource/@@data'); const internalDataSymbol = Symbol.for("@schukai/monster/data/datasource/@@data");
/** /**
* The datasource class is the basis for dealing with different data sources. * The datasource class is the basis for dealing with different data sources.
...@@ -49,7 +47,6 @@ const internalDataSymbol = Symbol.for('@schukai/monster/data/datasource/@@data') ...@@ -49,7 +47,6 @@ const internalDataSymbol = Symbol.for('@schukai/monster/data/datasource/@@data')
* @summary The datasource class encapsulates the access to data objects. * @summary The datasource class encapsulates the access to data objects.
*/ */
class Datasource extends Base { class Datasource extends Base {
/** /**
* creates a new datasource * creates a new datasource
* *
...@@ -57,14 +54,10 @@ class Datasource extends Base { ...@@ -57,14 +54,10 @@ class Datasource extends Base {
constructor() { constructor() {
super(); super();
this[internalSymbol] = new ProxyObserver({ this[internalSymbol] = new ProxyObserver({
'options': extend({}, this.defaults) options: extend({}, this.defaults),
}); });
this[internalDataSymbol] = new ProxyObserver({ this[internalDataSymbol] = new ProxyObserver({});
});
} }
/** /**
...@@ -74,7 +67,7 @@ class Datasource extends Base { ...@@ -74,7 +67,7 @@ class Datasource extends Base {
* @returns {Datasource} * @returns {Datasource}
*/ */
attachObserver(observer) { attachObserver(observer) {
this[internalDataSymbol].attachObserver(observer) this[internalDataSymbol].attachObserver(observer);
return this; return this;
} }
...@@ -85,7 +78,7 @@ class Datasource extends Base { ...@@ -85,7 +78,7 @@ class Datasource extends Base {
* @returns {Datasource} * @returns {Datasource}
*/ */
detachObserver(observer) { detachObserver(observer) {
this[internalDataSymbol].detachObserver(observer) this[internalDataSymbol].detachObserver(observer);
return this; return this;
} }
...@@ -120,7 +113,7 @@ class Datasource extends Base { ...@@ -120,7 +113,7 @@ class Datasource extends Base {
* @return {Datasource} * @return {Datasource}
*/ */
setOption(path, value) { setOption(path, value) {
new Pathfinder(this[internalSymbol].getSubject()['options']).setVia(path, value); new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia(path, value);
return this; return this;
} }
...@@ -130,13 +123,12 @@ class Datasource extends Base { ...@@ -130,13 +123,12 @@ class Datasource extends Base {
* @throws {Error} the options does not contain a valid json definition * @throws {Error} the options does not contain a valid json definition
*/ */
setOptions(options) { setOptions(options) {
if (isString(options)) { if (isString(options)) {
options = parseOptionsJSON(options) options = parseOptionsJSON(options);
} }
const self = this; const self = this;
extend(self[internalSymbol].getSubject()['options'], self.defaults, options); extend(self[internalSymbol].getSubject()["options"], self.defaults, options);
return self; return self;
} }
...@@ -152,10 +144,8 @@ class Datasource extends Base { ...@@ -152,10 +144,8 @@ class Datasource extends Base {
let value; let value;
try { try {
value = new Pathfinder(this[internalSymbol].getRealSubject()['options']).getVia(path); value = new Pathfinder(this[internalSymbol].getRealSubject()["options"]).getVia(path);
} catch (e) { } catch (e) {}
}
if (value === undefined) return defaultValue; if (value === undefined) return defaultValue;
return value; return value;
...@@ -166,7 +156,7 @@ class Datasource extends Base { ...@@ -166,7 +156,7 @@ class Datasource extends Base {
* @return {Promise} * @return {Promise}
*/ */
read() { read() {
throw new Error("this method must be implemented by derived classes") throw new Error("this method must be implemented by derived classes");
} }
/** /**
...@@ -174,10 +164,9 @@ class Datasource extends Base { ...@@ -174,10 +164,9 @@ class Datasource extends Base {
* @return {Promise} * @return {Promise}
*/ */
write() { write() {
throw new Error("this method must be implemented by derived classes") throw new Error("this method must be implemented by derived classes");
} }
/** /**
* Returns real object * Returns real object
* *
...@@ -206,7 +195,6 @@ class Datasource extends Base { ...@@ -206,7 +195,6 @@ class Datasource extends Base {
static get [instanceSymbol]() { static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/data/datasource"); return Symbol.for("@schukai/monster/data/datasource");
} }
} }
/** /**
...@@ -217,22 +205,18 @@ class Datasource extends Base { ...@@ -217,22 +205,18 @@ class Datasource extends Base {
*/ */
function parseOptionsJSON(data) { function parseOptionsJSON(data) {
if (isString(data)) { if (isString(data)) {
// the configuration can be specified as a data url. // the configuration can be specified as a data url.
try { try {
let dataUrl = parseDataURL(data); let dataUrl = parseDataURL(data);
data = dataUrl.content; data = dataUrl.content;
} catch (e) { } catch (e) {}
}
try { try {
let obj = JSON.parse(data); let obj = JSON.parse(data);
validateObject(obj); validateObject(obj);
return obj; return obj;
} catch (e) { } catch (e) {
throw new Error('the options does not contain a valid json definition (actual: ' + data + ').'); throw new Error(`the options does not contain a valid json definition (actual: ${data}).`);
} }
} }
......
...@@ -11,7 +11,7 @@ import {Datasource} from "../datasource.mjs"; ...@@ -11,7 +11,7 @@ import {Datasource} from "../datasource.mjs";
import { Pathfinder } from "../pathfinder.mjs"; import { Pathfinder } from "../pathfinder.mjs";
import { Pipe } from "../pipe.mjs"; import { Pipe } from "../pipe.mjs";
export {Server} export { Server };
/** /**
* Base class for all server datasources * Base class for all server datasources
...@@ -23,7 +23,6 @@ export {Server} ...@@ -23,7 +23,6 @@ export {Server}
* @summary The Server class encapsulates the access to a server datasource * @summary The Server class encapsulates the access to a server datasource
*/ */
class Server extends Datasource { class Server extends Datasource {
/** /**
* This method is called by the `instanceof` operator. * This method is called by the `instanceof` operator.
* @returns {symbol} * @returns {symbol}
...@@ -32,7 +31,6 @@ class Server extends Datasource { ...@@ -32,7 +31,6 @@ class Server extends Datasource {
return Symbol.for("@schukai/monster/data/datasource/server"); return Symbol.for("@schukai/monster/data/datasource/server");
} }
/** /**
* This prepares the data that comes from the server. * This prepares the data that comes from the server.
* Should not be called directly. * Should not be called directly.
...@@ -43,11 +41,11 @@ class Server extends Datasource { ...@@ -43,11 +41,11 @@ class Server extends Datasource {
*/ */
transformServerPayload(payload) { transformServerPayload(payload) {
const self = this; const self = this;
payload = doTransform.call(self, 'read', payload); payload = doTransform.call(self, "read", payload);
const dataPath = self.getOption('read.path'); const dataPath = self.getOption("read.path");
if (dataPath) { if (dataPath) {
payload = (new Pathfinder(payload)).getVia(dataPath); payload = new Pathfinder(payload).getVia(dataPath);
} }
return payload; return payload;
...@@ -63,23 +61,21 @@ class Server extends Datasource { ...@@ -63,23 +61,21 @@ class Server extends Datasource {
prepareServerPayload(payload) { prepareServerPayload(payload) {
const self = this; const self = this;
payload = doTransform.call(self, 'write', payload); payload = doTransform.call(self, "write", payload);
let sheathingObject = self.getOption('write.sheathing.object'); let sheathingObject = self.getOption("write.sheathing.object");
let sheathingPath = self.getOption('write.sheathing.path'); let sheathingPath = self.getOption("write.sheathing.path");
if (sheathingObject && sheathingPath) { if (sheathingObject && sheathingPath) {
const sub = payload; const sub = payload;
payload = sheathingObject; payload = sheathingObject;
(new Pathfinder(payload)).setVia(sheathingPath, sub); new Pathfinder(payload).setVia(sheathingPath, sub);
} }
return payload; return payload;
} }
} }
/** /**
* @private * @private
* @param self * @param self
...@@ -88,14 +84,14 @@ class Server extends Datasource { ...@@ -88,14 +84,14 @@ class Server extends Datasource {
*/ */
function doTransform(type, obj) { function doTransform(type, obj) {
const self = this; const self = this;
let transformation = self.getOption(type + '.mapping.transformer'); let transformation = self.getOption(`${type}.mapping.transformer`);
if (transformation !== undefined) { if (transformation !== undefined) {
const pipe = new Pipe(transformation); const pipe = new Pipe(transformation);
const callbacks = self.getOption(type + '.mapping.callbacks') const callbacks = self.getOption(`${type}.mapping.callbacks`);
if (isObject(callbacks)) { if (isObject(callbacks)) {
for (const key in callbacks) { for (const key in callbacks) {
if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === 'function') { if (callbacks.hasOwnProperty(key) && typeof callbacks[key] === "function") {
pipe.setCallback(key, callbacks[key]); pipe.setCallback(key, callbacks[key]);
} }
} }
......
...@@ -12,7 +12,7 @@ import {Pathfinder} from "../../pathfinder.mjs"; ...@@ -12,7 +12,7 @@ import {Pathfinder} from "../../pathfinder.mjs";
import { Pipe } from "../../pipe.mjs"; import { Pipe } from "../../pipe.mjs";
import { WriteError } from "./restapi/writeerror.mjs"; import { WriteError } from "./restapi/writeerror.mjs";
export {RestAPI} export { RestAPI };
/** /**
* The RestAPI is a class that enables a REST API server. * The RestAPI is a class that enables a REST API server.
...@@ -25,7 +25,6 @@ export {RestAPI} ...@@ -25,7 +25,6 @@ export {RestAPI}
* @summary The RestAPI is a class that binds a REST API server. * @summary The RestAPI is a class that binds a REST API server.
*/ */
class RestAPI extends Server { class RestAPI extends Server {
/** /**
* *
* @param {Object} [options] options contains definitions for the datasource. * @param {Object} [options] options contains definitions for the datasource.
...@@ -36,7 +35,6 @@ class RestAPI extends Server { ...@@ -36,7 +35,6 @@ class RestAPI extends Server {
if (isObject(options)) { if (isObject(options)) {
this.setOptions(options); this.setOptions(options);
} }
} }
/** /**
...@@ -76,34 +74,33 @@ class RestAPI extends Server { ...@@ -76,34 +74,33 @@ class RestAPI extends Server {
return Object.assign({}, super.defaults, { return Object.assign({}, super.defaults, {
write: { write: {
init: { init: {
method: 'POST', method: "POST",
}, },
acceptedStatus: [200, 201], acceptedStatus: [200, 201],
url: undefined, url: undefined,
mapping: { mapping: {
transformer: undefined, transformer: undefined,
callbacks: [] callbacks: [],
}, },
sheathing: { sheathing: {
object: undefined, object: undefined,
path: undefined, path: undefined,
}, },
report: { report: {
path: undefined path: undefined,
} },
}, },
read: { read: {
init: { init: {
method: 'GET' method: "GET",
}, },
acceptedStatus: [200], acceptedStatus: [200],
url: undefined, url: undefined,
mapping: { mapping: {
transformer: undefined, transformer: undefined,
callbacks: [] callbacks: [],
}, },
}, },
}); });
} }
...@@ -114,17 +111,15 @@ class RestAPI extends Server { ...@@ -114,17 +111,15 @@ class RestAPI extends Server {
* @throws {Error} the data cannot be read * @throws {Error} the data cannot be read
*/ */
read() { read() {
const self = this; const self = this;
let init = self.getOption('read.init'); let init = self.getOption("read.init");
if (!isObject(init)) init = {}; if (!isObject(init)) init = {};
if (!init['method']) init['method'] = 'GET'; if (!init["method"]) init["method"] = "GET";
return fetchData.call(this, 'read', (obj) => { return fetchData.call(this, "read", (obj) => {
self.set(self.transformServerPayload.call(self, obj)); self.set(self.transformServerPayload.call(self, obj));
}); });
} }
/** /**
...@@ -132,76 +127,67 @@ class RestAPI extends Server { ...@@ -132,76 +127,67 @@ class RestAPI extends Server {
* @throws {WriteError} the data cannot be written * @throws {WriteError} the data cannot be written
*/ */
write() { write() {
const self = this; const self = this;
let init = self.getOption('write.init'); let init = self.getOption("write.init");
if (!isObject(init)) init = {}; if (!isObject(init)) init = {};
if (typeof init['headers'] !== 'object') { if (typeof init["headers"] !== "object") {
init['headers'] = { init["headers"] = {
'Content-Type': 'application/json' "Content-Type": "application/json",
};
} }
} if (!init["method"]) init["method"] = "POST";
if (!init['method']) init['method'] = 'POST';
let obj = self.prepareServerPayload(self.get()); let obj = self.prepareServerPayload(self.get());
init['body'] = JSON.stringify(obj); init["body"] = JSON.stringify(obj);
return fetchData.call(this, init, 'write'); return fetchData.call(this, init, "write");
} }
/** /**
* @return {RestAPI} * @return {RestAPI}
*/ */
getClone() { getClone() {
const self = this; const self = this;
return new RestAPI(self[internalSymbol].getRealSubject()['options'].read, self[internalSymbol].getRealSubject()['options'].write); return new RestAPI(
self[internalSymbol].getRealSubject()["options"].read,
self[internalSymbol].getRealSubject()["options"].write,
);
} }
} }
function fetchData(init, key, callback) { function fetchData(init, key, callback) {
const self = this; const self = this;
let response; let response;
return fetch(self.getOption(`${key}.url`), init)
return fetch(self.getOption(key + '.url'), init).then(resp => { .then((resp) => {
response = resp; response = resp;
const acceptedStatus = self.getOption(key + '.acceptedStatus', [200]); const acceptedStatus = self.getOption(`${key}.acceptedStatus`, [200]);
if (acceptedStatus.indexOf(resp.status) === -1) { if (acceptedStatus.indexOf(resp.status) === -1) {
throw Error('the data cannot be ' + key + ' (response ' + resp.status + ')') throw Error(`the data cannot be ${key} (response ${resp.status})`);
} }
return resp.text() return resp.text();
}).then(body => { })
.then((body) => {
let obj; let obj;
try { try {
obj = JSON.parse(body); obj = JSON.parse(body);
} catch (e) { } catch (e) {
if (body.length > 100) { if (body.length > 100) {
body = body.substring(0, 97) + '...'; body = `${body.substring(0, 97)}...`;
} }
throw new Error('the response does not contain a valid json (actual: ' + body + ').'); throw new Error(`the response does not contain a valid json (actual: ${body}).`);
} }
if (callback && isFunction(callback)) { if (callback && isFunction(callback)) {
callback(obj); callback(obj);
} }
return response; return response;
}); });
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import { internalSymbol, instanceSymbol } from "../../../../constants.mjs"; import { internalSymbol, instanceSymbol } from "../../../../constants.mjs";
export {WriteError} export { WriteError };
/** /**
* Error message for API requests with extension of request and validation. * Error message for API requests with extension of request and validation.
...@@ -28,7 +28,7 @@ class WriteError extends Error { ...@@ -28,7 +28,7 @@ class WriteError extends Error {
super(message); super(message);
this[internalSymbol] = { this[internalSymbol] = {
response: response, response: response,
validation: validation validation: validation,
}; };
} }
...@@ -45,13 +45,13 @@ class WriteError extends Error { ...@@ -45,13 +45,13 @@ class WriteError extends Error {
* @return {Response} * @return {Response}
*/ */
getResponse() { getResponse() {
return this[internalSymbol]['response'] return this[internalSymbol]["response"];
} }
/** /**
* @return {Object} * @return {Object}
*/ */
getValidation() { getValidation() {
return this[internalSymbol]['validation'] return this[internalSymbol]["validation"];
} }
} }
...@@ -11,7 +11,7 @@ import {WebConnect as NetWebConnect} from "../../../net/webconnect.mjs"; ...@@ -11,7 +11,7 @@ import {WebConnect as NetWebConnect} from "../../../net/webconnect.mjs";
import { Message } from "../../../net/webconnect/message.mjs"; import { Message } from "../../../net/webconnect/message.mjs";
import { Server } from "../server.mjs"; import { Server } from "../server.mjs";
export {WebConnect} export { WebConnect };
/** /**
* @private * @private
...@@ -21,8 +21,6 @@ export {WebConnect} ...@@ -21,8 +21,6 @@ export {WebConnect}
*/ */
const webConnectSymbol = Symbol("connection"); const webConnectSymbol = Symbol("connection");
/** /**
* The RestAPI is a class that enables a REST API server. * The RestAPI is a class that enables a REST API server.
* *
...@@ -34,7 +32,6 @@ const webConnectSymbol = Symbol("connection"); ...@@ -34,7 +32,6 @@ const webConnectSymbol = Symbol("connection");
* @summary The LocalStorage class encapsulates the access to data objects. * @summary The LocalStorage class encapsulates the access to data objects.
*/ */
class WebConnect extends Server { class WebConnect extends Server {
/** /**
* *
* @param {Object} [options] options contains definitions for the datasource. * @param {Object} [options] options contains definitions for the datasource.
...@@ -51,15 +48,15 @@ class WebConnect extends Server { ...@@ -51,15 +48,15 @@ class WebConnect extends Server {
if (!isObject(options)) options = {}; if (!isObject(options)) options = {};
this.setOptions(options); this.setOptions(options);
this[webConnectSymbol] = new NetWebConnect({ this[webConnectSymbol] = new NetWebConnect({
url: self.getOption('url'), url: self.getOption("url"),
connection: { connection: {
timeout: self.getOption('connection.timeout'), timeout: self.getOption("connection.timeout"),
reconnect: { reconnect: {
timeout: self.getOption('connection.reconnect.timeout'), timeout: self.getOption("connection.reconnect.timeout"),
attempts: self.getOption('connection.reconnect.attempts'), attempts: self.getOption("connection.reconnect.attempts"),
enabled: self.getOption('connection.reconnect.enabled') enabled: self.getOption("connection.reconnect.enabled"),
} },
} },
}); });
} }
...@@ -112,7 +109,7 @@ class WebConnect extends Server { ...@@ -112,7 +109,7 @@ class WebConnect extends Server {
write: { write: {
mapping: { mapping: {
transformer: undefined, transformer: undefined,
callbacks: {} callbacks: {},
}, },
sheathing: { sheathing: {
object: undefined, object: undefined,
...@@ -122,7 +119,7 @@ class WebConnect extends Server { ...@@ -122,7 +119,7 @@ class WebConnect extends Server {
read: { read: {
mapping: { mapping: {
transformer: undefined, transformer: undefined,
callbacks: {} callbacks: {},
}, },
path: undefined, path: undefined,
}, },
...@@ -132,8 +129,8 @@ class WebConnect extends Server { ...@@ -132,8 +129,8 @@ class WebConnect extends Server {
timeout: 1000, timeout: 1000,
attempts: 1, attempts: 1,
enabled: false, enabled: false,
} },
} },
}); });
} }
...@@ -153,16 +150,15 @@ class WebConnect extends Server { ...@@ -153,16 +150,15 @@ class WebConnect extends Server {
const self = this; const self = this;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
while (this[webConnectSymbol].dataReceived() === true) { while (this[webConnectSymbol].dataReceived() === true) {
let obj = this[webConnectSymbol].poll(); let obj = this[webConnectSymbol].poll();
if (!isObject(obj)) { if (!isObject(obj)) {
reject(new Error('The received data is not an object.')); reject(new Error("The received data is not an object."));
return; return;
} }
if (!(obj instanceof Message)) { if (!(obj instanceof Message)) {
reject(new Error('The received data is not a Message.')); reject(new Error("The received data is not a Message."));
return; return;
} }
...@@ -172,11 +168,8 @@ class WebConnect extends Server { ...@@ -172,11 +168,8 @@ class WebConnect extends Server {
} }
resolve(self.get()); resolve(self.get());
});
}) }
};
/** /**
* @return {Promise} * @return {Promise}
...@@ -184,7 +177,7 @@ class WebConnect extends Server { ...@@ -184,7 +177,7 @@ class WebConnect extends Server {
write() { write() {
const self = this; const self = this;
let obj = self.prepareServerPayload(self.get()); let obj = self.prepareServerPayload(self.get());
return self[webConnectSymbol].send(obj) return self[webConnectSymbol].send(obj);
} }
/** /**
...@@ -192,8 +185,6 @@ class WebConnect extends Server { ...@@ -192,8 +185,6 @@ class WebConnect extends Server {
*/ */
getClone() { getClone() {
const self = this; const self = this;
return new WebConnect(self[internalSymbol].getRealSubject()['options']); return new WebConnect(self[internalSymbol].getRealSubject()["options"]);
} }
} }