var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ // } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ /** * @author fenris */ /*export*/ function pseudopointer_null() { return { "value": null }; } /** * @author fenris */ /*export*/ function pseudopointer_make(value) { return { "value": value }; } /** * @author fenris */ /*export*/ function pseudopointer_isset(pseudopointer) { return (pseudopointer.value != null); } /** * @author fenris */ /*export*/ function pseudopointer_read(pseudopointer) { if (pseudopointer.value != null) { return pseudopointer.value; } else { var message = "nullpointer dereferencation"; throw (new Error(message)); } } /** * @author fenris */ /*export*/ function pseudopointer_write(pseudopointer, value) { pseudopointer.value = value; } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ ; var lib_base; (function (lib_base) { /** * @author fenris */ function environment() { var entries = [ { "id": "web", "name": "Web", "predicate": function () { return (typeof (document) !== "undefined"); }, }, { "id": "node", "name": "Node.js", "predicate": function () { return (typeof (process) !== "undefined"); }, }, { "id": "rhino", "name": "Rhino", "predicate": function () { return (typeof (java) !== "undefined"); }, }, { "id": "webworker", "name": "WebWorker", "predicate": function () { return (typeof (self["WorkerNavigator"]) !== "undefined"); } } ]; var id; var found = entries.some(function (entry) { if (entry.predicate()) { id = entry.id; return true; } else { return false; } }); if (found) { return id; } else { throw (new Error("unknown environment")); } } lib_base.environment = environment; })(lib_base || (lib_base = {})); /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ /** * @author fenris */ var instance_verbosity = 0; /** * @author fenris */ function instance_collate(value1, value2) { if (typeof (value1) === "object") { if (value1 == null) { return (value2 == null); } else { if ("_collate" in value1) { return value1["_collate"](value2); } else { throw (new Error("[collate]" + " " + "object has no such method")); } } } else { if (instance_verbosity >= 1) { lib_log.warn("[collate]" + " " + "primitive value; using default implementation"); } return (value1 === value2); } } /** * @author fenris */ function instance_compare(value1, value2) { if (typeof (value1) === "object") { if ("_compare" in value1) { return value1["_compare"](value2); } else { throw (new Error("[compare]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { lib_log.warn("[compare]" + " " + "primitive value; using default implementation"); } return (value1 <= value2); } } /** * @author fenris */ function instance_clone(value) { if (typeof (value) === "object") { if ("_clone" in value) { return value["_clone"](); } else { throw (new Error("[clone]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { lib_log.warn("[clone]" + " " + "primitive value; using default implementation"); } return value; } } /** * @desc the ability to generate a string out of the element, which identifies it to a high degree * @author fenris */ function instance_hash(value) { if (typeof (value) === "object") { if ("_hash" in value) { return value["_hash"](); } else { throw (new Error("[hash]" + " " + "object has no such method")); } } else { if (instance_verbosity >= 1) { lib_log.warn("[hash]" + " " + "primitive value; using default implementation"); } return String(value); } } /** * @desc the ability to map the element to a textual representation (most likely not injective) * @author fenris */ function instance_show(value) { if (typeof (value) === "object") { if (value == null) { return "NULL"; } else { if ("_show" in value) { return value["_show"](); } else { // throw (new Error("[show]" + " " + "object has no such method")); return JSON.stringify(value); } } } else { if (instance_verbosity >= 1) { lib_log.warn("[show]" + " " + "primitive value; using default implementation"); } return String(value); } } /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ /** * @todo outsource to dedicated plankton-lib */ var lib_log; (function (lib_log) { /** * @author fenris */ function log() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } /*window.*/ console.log.apply(console, args); } lib_log.log = log; /** * @author fenris */ function info() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } /*window.*/ console.info.apply(console, args); } lib_log.info = info; /** * @author fenris */ function warn() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } /*window.*/ console.warn.apply(console, args); } lib_log.warn = warn; /** * @author fenris */ function error() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } /*window.*/ console.error.apply(console, args); } lib_log.error = error; })(lib_log || (lib_log = {})); /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ /** * @author frac */ var class_observer = /** @class */ (function () { /** * @author frac */ function class_observer() { this.counter = 0; this.actions = {}; this.buffer = []; } /** * @author frac */ class_observer.prototype.empty = function () { return (Object.keys(this.actions).length == 0); }; /** * @author frac */ class_observer.prototype.flush = function () { this.actions = {}; }; /** * @author frac */ class_observer.prototype.set = function (id, action) { this.actions[id] = action; }; /** * @author frac */ class_observer.prototype.del = function (id) { delete this.actions[id]; }; /** * @author frac */ class_observer.prototype.add = function (action) { this.set((this.counter++).toString(), action); }; /** * @author frac */ class_observer.prototype.notify = function (information, delayed) { var _this = this; if (information === void 0) { information = {}; } if (delayed === void 0) { delayed = false; } if (delayed) { this.buffer.push(information); } else { Object.keys(this.actions).forEach(function (id) { return _this.actions[id](information); }); } }; /** * @author frac */ class_observer.prototype.rollout = function () { var _this = this; this.buffer.forEach(function (information) { return _this.notify(information, false); }); this.buffer = []; }; return class_observer; }()); /** * @author frac */ /* export interface interface_readable { |** * @author frac *| read() : type_executor; } */ /** * @author frac */ /* export interface interface_writeable { |** * @author frac *| write(value : type_value) : type_executor; } */ /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ var lib_maybe; (function (lib_maybe) { /** * @author fenris */ function make_nothing() { return { "kind": "nothing", "parameters": {} }; } lib_maybe.make_nothing = make_nothing; /** * @author fenris */ function make_just(value) { return { "kind": "just", "parameters": { "value": value } }; } lib_maybe.make_just = make_just; /** * @author fenris */ function is_nothing(maybe) { return (maybe.kind === "nothing"); } lib_maybe.is_nothing = is_nothing; /** * @author fenris */ function is_just(maybe) { return (maybe.kind === "just"); } lib_maybe.is_just = is_just; /** * @author fenris */ function cull(maybe) { if (!is_just(maybe)) { var message = "cull from nothing"; throw (new Error(message)); } else { var value = maybe.parameters["value"]; return value; } } lib_maybe.cull = cull; /** * @author fenris */ function propagate(maybe, function_) { if (!is_just(maybe)) { } else { var value = maybe.parameters["value"]; var maybe_ = function_(value); return maybe_; } } lib_maybe.propagate = propagate; })(lib_maybe || (lib_maybe = {})); /** * @author fenris */ /*export*/ var class_maybe = /** @class */ (function () { function class_maybe() { } /** * @desc whether the wrapper is nothing * @author fenris */ class_maybe.prototype.is_nothing = function () { throw (new Error("not implemented: class_maybe.is_nothing")); }; /** * @desc whether the wrapper is just * @author fenris */ class_maybe.prototype.is_just = function () { throw (new Error("not implemented: class_maybe.is_just")); }; /** * @desc return the value, stored in the maybe-wrapper * @author fenris */ class_maybe.prototype.cull = function () { throw (new Error("not implemented: class_maybe.cull")); }; /** * @author fenris */ class_maybe.prototype.toString = function () { throw (new Error("not implemented: class_maybe.cull")); }; /** * @author fenris */ class_maybe.prototype.distinguish = function (action_just, action_nothing) { if (action_nothing === void 0) { action_nothing = function () { }; } throw (new Error("not implemented: class_maybe.distinguish")); }; /** * @author fenris */ class_maybe.prototype.propagate = function (action) { throw (new Error("not implemented: class_maybe.propagate")); }; /** * @desc [implementation] * @author fenris */ class_maybe.prototype._show = function () { return this.toString(); }; return class_maybe; }()); /** * @author fenris */ /*export*/ var class_nothing = /** @class */ (function (_super) { __extends(class_nothing, _super); /** * @author fenris */ function class_nothing(reason) { if (reason === void 0) { reason = null; } var _this = _super.call(this) || this; _this.reason = reason; return _this; } /** * @author fenris */ class_nothing.prototype.is_nothing = function () { return true; }; /** * @author fenris */ class_nothing.prototype.is_just = function () { return false; }; /** * @author fenris */ class_nothing.prototype.cull = function () { var message = "you shouldn't cull a nothing-value …"; lib_log.warn(message); return null; }; /** * @author fenris */ class_nothing.prototype.toString = function () { return "<\u00B7>"; }; /** * @author fenris */ class_nothing.prototype.reason_get = function () { var content = ((this.reason == null) ? "·" : this.reason); return "<- " + content + " ->"; }; /** * @author fenris */ class_nothing.prototype.distinguish = function (action_just, action_nothing) { if (action_nothing === void 0) { action_nothing = function () { }; } action_nothing(this.reason); }; /** * @author fenris */ class_nothing.prototype.propagate = function (action) { return (new class_nothing(this.reason)); }; return class_nothing; }(class_maybe)); /** * @author fenris */ /*export*/ var class_just = /** @class */ (function (_super) { __extends(class_just, _super); /** * @author fenris */ function class_just(value) { var _this = _super.call(this) || this; _this.value = value; return _this; } /** * @author fenris */ class_just.prototype.is_nothing = function () { return false; }; /** * @author fenris */ class_just.prototype.is_just = function () { return true; }; /** * @author fenris */ class_just.prototype.cull = function () { return this.value; }; /** * @author fenris */ class_just.prototype.toString = function () { var content = instance_show(this.value); return "<+ " + content + " +>"; }; /** * @author fenris */ class_just.prototype.distinguish = function (action_just, action_nothing) { if (action_nothing === void 0) { action_nothing = function () { }; } action_just(this.value); }; /** * @author fenris */ class_just.prototype.propagate = function (action) { return action(this.value); }; return class_just; }(class_maybe)); /* This file is part of »bacterio-plankton:base«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:base« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:base« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:base«. If not, see . */ /** * @author frac */ var class_error = /** @class */ (function (_super) { __extends(class_error, _super); /** * @author frac */ function class_error(message, suberrors) { if (suberrors === void 0) { suberrors = []; } var _this = _super.call(this, message) || this; _this.suberrors = suberrors; _this.mess = message; return _this; } /** * @override * @author frac */ class_error.prototype.toString = function () { return ( /*super.toString()*/this.mess + " " + ("[" + this.suberrors.map(function (x) { return x.toString(); }).join(",") + "]")); }; return class_error; }(Error)); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ "use strict"; /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { /** * @desc hacked class for postfix function application * @author fenris */ class class_valuewrapper { /** * @desc [constructor] * @author fenris */ constructor(value) { this.value = value; } /** * @desc [accessor] applies a function and returns a new valuewrapper * @author fenris */ pass(function_) { return (new class_valuewrapper(function_(this.value))); } /** * @desc [accessor] gives the wrapped value * @author fenris */ extract() { return this.value; } } lib_call.class_valuewrapper = class_valuewrapper; /** * @desc shortcut for constructing a valuewrapper-object * @author fenris */ function vw(value) { return (new class_valuewrapper(value)); } lib_call.vw = vw; /** * @author fenris */ function use(input, function_) { return function_(input); } lib_call.use = use; /** * @desc just the identity; useful for some callbacks etc. * @author fenris */ function id(x) { return x; } lib_call.id = id; /** * @desc composes two functions (i.e. returns a function that return the result of the successive execution of both input-functions) * @param {function} function_f * @param {function} function_g * @author fenris */ function compose(function_f, function_g) { return (function (x) { // return function_g(function_f(x)); return function_g(function_f.apply(function_f, lib_call.args2list(arguments))); }); } lib_call.compose = compose; /** * @desc transforms a function with sequential input into a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) * @param {function} f * @param {int} n (don't set manually) * @return {function} the currified version of the in put function * @author fenris */ function curryfy(f, n = f.length) { switch (n) { case 0: { throw (new Error("[curryfy] impossible")); // break; } case 1: { return f; // break; } default: { return (function (x) { return (curryfy(function () { return f.apply(f, [x].concat(lib_call.args2list(arguments))); }, n - 1)); }); // break; } } } lib_call.curryfy = curryfy; })(lib_call || (lib_call = {})); var lib_call; (function (lib_call) { /** * @author fenris */ function executor_resolve(result) { return ((resolve, reject) => resolve(result)); } lib_call.executor_resolve = executor_resolve; /** * @author fenris */ function executor_reject(reason) { return ((resolve, reject) => reject(reason)); } lib_call.executor_reject = executor_reject; /** * @author fenris */ function executor_transform(executor, transform_result, transform_reason) { return ((resolve, reject) => { executor(result => resolve(transform_result(result)), reason => reject(transform_reason(reason))); }); } lib_call.executor_transform = executor_transform; /** * @author fenris */ function executor_transform_default(executor, transform_result, wrap_string = null) { let transform_reason = (error => ((wrap_string == null) ? error : new class_error(wrap_string, [error]))); return (executor_transform(executor, transform_result, transform_reason)); } lib_call.executor_transform_default = executor_transform_default; /** * @author fenris */ function executor_compose_sequential(first, second) { return ((resolve, reject) => { first(result => { second(result)(resolve, reject); }, reason => { reject(reason); }); }); } lib_call.executor_compose_sequential = executor_compose_sequential; /** * @author fenris */ function executor_chain(state, executors) { return ((resolve, reject) => { if (executors.length == 0) { return resolve(state); } else { return executors[0](state)(result => { executor_chain(result, executors.slice(1))(resolve, reject); }, reject); } }); /* */ /* if (executors.length == 0) { return executor_resolve(state); } else if (executors.length == 1) { return executors[0](state); } else { return ( executor_chain( state, [ state => (resolve, reject) => executors[0](state)(result => executors[1](result)(resolve, reject), reject) ].concat(executors.slice(2)) ) ); } */ /* return ( executors.reduce( (chain, current) => executor_compose_sequential(chain, current, deferred), executor_resolve(state) ) ); */ } lib_call.executor_chain = executor_chain; /** * @author fenris */ function executor_first(executors) { /* return ( (resolve, reject) => { if (executors.length == 0) { reject(new Error("all failed")); } else { executors[0]( result => { resolve(result); }, reason => { executor_first(executors.slice(1))(resolve, reject); } ) } } ); */ return ((resolve, reject) => { executor_chain([], executors.map(executor => reasons => (resolve_, reject_) => { executor(result => reject_(result), reason => resolve_(reasons.concat([reason]))); }))(errors => reject(errors), result => resolve(result)); }); } lib_call.executor_first = executor_first; /** * @author fenris */ function executor_condense(executors) { return (executor_chain([], executors.map(executor => result => (resolve, reject) => { executor(element => resolve(result.concat([element])), reject); }))); } lib_call.executor_condense = executor_condense; /** * @author fenris * @deprecated use condense */ function executor_filter(executors, predicate) { return (executor_chain([], executors.map(executor => result => (resolve, reject) => { executor(element => resolve(predicate(element) ? result.concat([element]) : result), reject); }))); } lib_call.executor_filter = executor_filter; /** * @author fenris * @deprecated use condense */ function executor_map(executors, transformator) { return (executor_chain([], executors.map(executor => result => (resolve, reject) => { executor(element1 => resolve(result.concat([transformator(element1)])), reject); }))); } lib_call.executor_map = executor_map; /** * @author fenris * @deprecated use condense */ function executor_reduce(executors, initial, accumulator) { return (executor_chain(initial, executors.map(executor => result => (resolve, reject) => { executor(element => resolve(accumulator(result, element)), reject); }))); } lib_call.executor_reduce = executor_reduce; })(lib_call || (lib_call = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { /** * @author fenris */ function promise_reject(reason) { return Promise.reject(reason); } lib_call.promise_reject = promise_reject; /** * @author fenris */ function promise_resolve(result) { return Promise.resolve(result); } lib_call.promise_resolve = promise_resolve; /** * @author fenris */ function promise_make(executor) { return (new Promise(executor)); } lib_call.promise_make = promise_make; /** * @author fenris */ function promise_then_close(promise, resolver, rejector) { promise.then(resolver, rejector); } lib_call.promise_then_close = promise_then_close; /** * @author fenris */ function promise_then_append(promise, resolver, rejector = null) { if (rejector == null) { rejector = (reason) => promise_reject(reason); } return (promise.then(resolver, rejector)); } lib_call.promise_then_append = promise_then_append; /** * @author fenris */ function promise_all(promises) { return Promise.all(promises); } lib_call.promise_all = promise_all; /** * @author fenris */ function promise_chain(promises, start = undefined) { return (promises.reduce((chain, promise) => promise_then_append(chain, promise), promise_resolve(start))); } lib_call.promise_chain = promise_chain; /** * @author fenris */ function promise_condense(promises) { return (promise_chain(promises.map(promise => result => promise_then_append(promise(), element => promise_resolve(result.concat([element])))), [])); } lib_call.promise_condense = promise_condense; /** * @author fenris */ function promise_group(promises, serial = false) { const decorate = function (promise, name) { return (() => promise_then_append(promise(), value => promise_resolve({ "key": name, "value": value }))); }; const convert = function (array) { let object = {}; array.forEach(({ "key": key, "value": value }) => { object[key] = value; }); return object; }; if (serial) { return (promise_then_append(promise_condense(Object.keys(promises) .map(name => decorate(promises[name], name))), list => promise_resolve(convert(list)))); } else { return (promise_then_append(promise_all(Object.keys(promises) .map(name => decorate(promises[name], name)) .map(promise => promise())), list => promise_resolve(convert(list)))); } } lib_call.promise_group = promise_group; /** * @author fenris */ function promise_wrap(promise, transformator_result, transformator_reason = lib_call.id) { return (promise_make((resolve, reject) => { promise_then_close(promise, result => resolve(transformator_result(result)), reason => reject(transformator_reason(reason))); })); } lib_call.promise_wrap = promise_wrap; /** * @author fenris */ function promise_show(label) { return (result => promise_make((resolve, reject) => { lib_log.info(label + ": " + instance_show(result)); resolve(result); })); } lib_call.promise_show = promise_show; /** * @author fenris */ function promise_log(result) { return promise_show("log"); } lib_call.promise_log = promise_log; /** * @author fenris */ function promise_attach(state, promise, name) { return (promise_wrap(promise, result => { state[name] = result; return state; })); } lib_call.promise_attach = promise_attach; /** * @author fenris */ function promise_delay(promise, delay) { return promise_make((resolve, reject) => { lib_call.timeout(() => { promise_then_close(promise, resolve, reject); return null; }, delay); }); } lib_call.promise_delay = promise_delay; /** * @author fenris */ function promise_to_executor(promise) { return ((resolve, reject) => promise.then(resolve, reject)); } lib_call.promise_to_executor = promise_to_executor; })(lib_call || (lib_call = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { lib_call.initializer_state_initial = 0; lib_call.initializer_state_waiting = 1; lib_call.initializer_state_successful = 2; lib_call.initializer_state_failed = 3; /** * @author fenris */ function initializer_make(fetcher) { let subject = { "fetcher": fetcher, "state": lib_call.initializer_state_initial, "queue": [], "result": undefined, "reason": undefined, }; return subject; } lib_call.initializer_make = initializer_make; /** * @author fenris */ function initializer_actuate(subject) { switch (subject.state) { case lib_call.initializer_state_successful: { subject.queue.forEach(entry => entry.resolve(subject.result)); break; } case lib_call.initializer_state_failed: { subject.queue.forEach(entry => entry.reject(subject.reason)); break; } default: { let message = `unhandled state ${subject.state}`; throw (new Error(message)); break; } } } /** * @author fenris */ function initializer_reset(subject) { subject.state = lib_call.initializer_state_initial; subject.queue = []; } lib_call.initializer_reset = initializer_reset; /** * @author fenris */ function initializer_state(subject) { return subject.state; } lib_call.initializer_state = initializer_state; /** * @author fenris */ function initializer_get(subject) { switch (subject.state) { case lib_call.initializer_state_initial: { subject.state = lib_call.initializer_state_waiting; return (lib_call.promise_make((resolve, reject) => { subject.queue.push({ "resolve": resolve, "reject": reject }); subject.fetcher().then(result => { subject.state = lib_call.initializer_state_successful; subject.result = result; initializer_actuate(subject); }, reason => { subject.state = lib_call.initializer_state_failed; subject.reason = reason; initializer_actuate(subject); }); })); break; } case lib_call.initializer_state_waiting: { return (lib_call.promise_make((resolve, reject) => { subject.queue.push({ "resolve": resolve, "reject": reject }); })); break; } case lib_call.initializer_state_successful: { return (lib_call.promise_resolve(subject.result)); break; } case lib_call.initializer_state_failed: { return (lib_call.promise_reject(subject.reason)); break; } default: { let message = `unhandled state ${subject.state}`; throw (new Error(message)); break; } } } lib_call.initializer_get = initializer_get; /** * @author fenris */ function initializer_get_sync(subject) { switch (subject.state) { case lib_call.initializer_state_successful: { return subject.result; break; } case lib_call.initializer_state_failed: { throw subject.reason; break; } default: { let message = `unhandled state ${subject.state}`; throw (new Error(message)); break; } } } /** * @author fenris */ function initializer_set_sync(subject, result) { switch (subject.state) { case lib_call.initializer_state_successful: { subject.result = result; break; } case lib_call.initializer_state_failed: { subject.state = lib_call.initializer_state_successful; subject.result = result; break; } default: { let message = `unhandled state ${subject.state}`; throw (new Error(message)); break; } } } })(lib_call || (lib_call = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { /* The core idea of this library is to provide means for asynchronous program flow. The old-school way to do is, is to use callbacks. While this approach is simple and easy to understand, it has some disadvantages. As an attempt to relief and improve this, the promise-system was introduced. In principle it solves most of the problems found in the callback-approach; however it has some downsides as well: - Convolution of multiple principles Promises unite the ideas of asynchronous program flow and error handling. - Instant execution Creating a promise results in the instant execution of the given executor prodecure. While this might be convenient in some cases, it can be quite disturbing and counter-intuitive in others. - Broken typing The Promise system doesn't distinguish between an appending "then" (i.e. passing a function, which returns a new promise) and a closing "then" (i.e. passing a function, which has no return value). On top of that it allows returning simple values in an appending "then", which results in an implicit call of the executors "resolve"-function. The price for these "pragmatic" features is that the whole system can't be typed well. And even though JavaScript is not a strictly typed language, it was a quite questionable decision to design the promise system in a way, which breaks typing from the start. The deferral-system forseeks to solve these issues while retaining the advantages of the promise-system. */ /** * @author fenris * @desc activates the deferral and handles its output according to a given procedure * @param {(value : type_value)=>void} procedure a function which receives the output of the deferral as argument */ function deferral_use(deferral, input, procedure) { deferral.representation(input).then(value => { procedure(value); }, reason => { throw reason; }); } lib_call.deferral_use = deferral_use; /** * @author fenris * @desc creates a deferral-subject (similar to "new Promise", where "convey" reflects "resolve"/"reject") */ function deferral_make(handler) { return ({ "representation": ((input) => (new Promise((resolve, reject) => { handler(input, resolve); }))) }); } lib_call.deferral_make = deferral_make; /** * @author fenris * @desc wraps a simple function into a deferral (similar to "Promise.resolve"/"Promise.reject") */ function deferral_wrap(function_) { return (deferral_make((input, convey) => convey(function_(input)))); } lib_call.deferral_wrap = deferral_wrap; /** * @author fenris */ function deferral_id() { return (deferral_make((input, convey) => convey(input))); } lib_call.deferral_id = deferral_id; /** * @author fenris */ function deferral_const(value) { return (deferral_make((input, convey) => convey(value))); } lib_call.deferral_const = deferral_const; /** * @author fenris */ function deferral_delay(output, delay) { return (deferral_make((input, convey) => { setTimeout(() => convey(output), delay); })); } lib_call.deferral_delay = deferral_delay; /** * @author fenris * @desc connects two deferrals to form a new one; the output of the first is taken as input for the second * (similar to "Promise.then" when passing a function which returns a new promise) * @param {type_deferral} first a simple deferral * @param {(value1 : type_value1)=>type_deferral} second a function depending from a value returning a deferral */ function deferral_compose_serial(first, second) { return { "representation": ((input) => first.representation(input).then((between) => second.representation(between))) }; } lib_call.deferral_compose_serial = deferral_compose_serial; /** * @author fenris */ function deferral_compose_parallel({ "left": deferral_left, "right": deferral_right, }) { return (deferral_make((input, convey) => { let object = { "left": lib_maybe.make_nothing(), "right": lib_maybe.make_nothing(), }; let finish = function () { if (lib_maybe.is_just(object.left) && lib_maybe.is_just(object.right)) { let result = { "left": lib_maybe.cull(object.left), "right": lib_maybe.cull(object.right), }; convey(result); } else { // do nothing } }; deferral_use(deferral_left, input, output_left => { object.left = lib_maybe.make_just(output_left); finish(); }); deferral_use(deferral_right, input, output_right => { object.right = lib_maybe.make_just(output_right); finish(); }); })); } lib_call.deferral_compose_parallel = deferral_compose_parallel; /** * @author fenris * @desc repeatedly applied serial composition */ function deferral_chain(members) { return (members.reduce( // (result, current) => deferral_compose_serial(result, current), deferral_compose_serial, deferral_id())); } lib_call.deferral_chain = deferral_chain; /** * @author fenris */ /* export function deferral_bunch( members : {[name : string] : type_deferral} ) : type_deferral { } */ })(lib_call || (lib_call = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { /** * @author fenris */ class class_deferral { /** * @author fenris */ constructor(subject) { this.subject = subject; } /** * @author fenris */ static _cram(subject) { return (new class_deferral(subject)); } /** * @author fenris */ static _tear(instance) { return instance.subject; } /** * @author fenris */ static make(handler) { return (class_deferral._cram(lib_call.deferral_make(handler))); } /** * @author fenris */ use(input, procedure) { return (lib_call.deferral_use(class_deferral._tear(this), input, procedure)); } /** * @author fenris */ compose_serial(second) { return (class_deferral._cram(lib_call.deferral_compose_serial(class_deferral._tear(this), class_deferral._tear(second)))); } /** * @author fenris */ static chain(members) { return (class_deferral._cram(lib_call.deferral_chain(members.map(member => class_deferral._tear(member))))); } /** * @author fenris */ static wrap(function_) { return (class_deferral._cram(lib_call.deferral_wrap(function_))); } /** * @author fenris */ static const_(value) { return (class_deferral._cram(lib_call.deferral_const(value))); } /** * @author fenris */ static delay(output, delay) { return (class_deferral._cram(lib_call.deferral_delay(output, delay))); } } lib_call.class_deferral = class_deferral; })(lib_call || (lib_call = {})); /* This file is part of »bacterio-plankton:call«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:call« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:call« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:call«. If not, see . */ var lib_call; (function (lib_call) { /** * @author fenris */ function timeout(function_, delay) { return ( /*window.*/ setTimeout(function_, delay)); } lib_call.timeout = timeout; /** * @desc a definition for a value being "defined" * @author neuc */ function is_def(obj, null_is_valid = false) { return (!((typeof (obj) === "undefined") || (!null_is_valid && (obj === null)))); } lib_call.is_def = is_def; /** * @desc returns the value if set and, when a type is specified, if the type is correct, if not return default_value * @author neuc */ function def_val(value, default_value, type = null, null_is_valid = false) { if (is_def(value, null_is_valid) && (is_def(type) ? ((typeof value === type) || ((value === null) && null_is_valid)) : true)) { return value; } else { return default_value; } } lib_call.def_val = def_val; ; /** * @desc just the empty function; useful for some callbacks etc. * @author fenris */ function nothing() { } lib_call.nothing = nothing; /** * @desc outputs * @author fenris */ function output(...args) { lib_log.info.apply(lib_log, args); } lib_call.output = output; /** * @desc converts the "arguments"-map into an array * @param {Object} args * @author fenris */ function args2list(args) { return Object.keys(args).map(key => args[key]); } lib_call.args2list = args2list; /** * @desc provides the call for an attribute of a class as a regular function * @param {string} name the name of the attribute * @return {*} * @author fenris */ function attribute(name) { return ((object) => object[name]); } lib_call.attribute = attribute; /** * @desc provides a method of a class as a regular function * @param {string} name the name of the method * @return {function} * @author fenris */ function method(name) { return (function (object) { return object[name].apply(object, args2list(arguments).slice(1)); }); } lib_call.method = method; /** * @author fenris */ function distinguish(unival, handlers, fallback = null) { if (unival.kind in handlers) { let handler = handlers[unival.kind]; return handler(unival.data); } else { let message = ("unhandled kind '" + unival.kind + "'"); if (fallback !== null) { console.warn(message); return fallback(unival); } else { throw (new Error(message)); } } } lib_call.distinguish = distinguish; })(lib_call || (lib_call = {})); var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var enum_level; (function (enum_level) { enum_level[enum_level["debug"] = 0] = "debug"; enum_level[enum_level["info"] = 1] = "info"; enum_level[enum_level["notice"] = 2] = "notice"; enum_level[enum_level["warning"] = 3] = "warning"; enum_level[enum_level["error"] = 4] = "error"; })(enum_level = log.enum_level || (log.enum_level = {})); ; /** */ function level_order(level1, level2) { return (level1 <= level2); } log.level_order = level_order; /** */ function level_show(level) { switch (level) { case enum_level.debug: return "debug"; case enum_level.info: return "info"; case enum_level.notice: return "notice"; case enum_level.warning: return "warning"; case enum_level.error: return "error"; default: return "(unknown)"; } } log.level_show = level_show; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ /** * @deprecated * @todo remove */ var lib_log; (function (lib_log) { /** * @author fenris */ /*export*/ var level_stack = [0]; function level_push(level) { level_stack.push(level); } lib_log.level_push = level_push; function level_pop() { if (level_stack.length > 1) { level_stack.pop(); } } lib_log.level_pop = level_pop; function level_get() { return level_stack.slice(-1)[0]; } /* export function level_inc() : void {level_push(level_get()+1);} export function level_dec() : void {level_push(level_get()-1);} */ /** * @author fenris */ var indent_stack = [0]; function indent_push(indent) { indent_stack.push(indent); } lib_log.indent_push = indent_push; function indent_pop() { if (indent_stack.length > 1) { indent_stack.pop(); } } lib_log.indent_pop = indent_pop; function indent_get() { return level_stack.slice(-1)[0]; } function indent_inc() { level_push(level_get() + 1); } lib_log.indent_inc = indent_inc; function indent_dec() { level_push(level_get() - 1); } lib_log.indent_dec = indent_dec; /** * @author fenris */ function write(_a) { var message = _a["message"], _b = _a["type"], type = _b === void 0 ? null : _b, _c = _a["prefix"], prefix = _c === void 0 ? null : _c, _d = _a["level"], level = _d === void 0 ? 0 : _d, _e = _a["indent"], indent = _e === void 0 ? 0 : _e; var entry = { "level": ((type === null) ? lib_plankton.log.enum_level.info : { "debug": lib_plankton.log.enum_level.debug, "info": lib_plankton.log.enum_level.info, "notice": lib_plankton.log.enum_level.notice, "warning": lib_plankton.log.enum_level.warning, "error": lib_plankton.log.enum_level.error }[type]), "incident": message, "details": { "prefix": prefix, "level": level, "indent": indent } }; lib_plankton.log.add(entry); } lib_log.write = write; })(lib_log || (lib_log = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var class_channel = /** @class */ (function () { function class_channel() { } return class_channel; }()); log.class_channel = class_channel; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var class_channel_console = /** @class */ (function (_super) { __extends(class_channel_console, _super); function class_channel_console() { return _super !== null && _super.apply(this, arguments) || this; } /** */ class_channel_console.prototype.add = function (entry) { console.log(("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">") + " " + ("[" + log.level_show(entry.level) + "]") + " " + ("" + entry.incident + "") + ": " + JSON.stringify(entry.details, undefined, " ")); }; return class_channel_console; }(log.class_channel)); log.class_channel_console = class_channel_console; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var class_channel_notify = /** @class */ (function (_super) { __extends(class_channel_notify, _super); function class_channel_notify() { return _super !== null && _super.apply(this, arguments) || this; } /** */ class_channel_notify.prototype.add = function (entry) { var nm_child_process = require("child_process"); var command = ("notify-send" + " " + ("'" + ("[" + log.level_show(entry.level) + "]") + " " + entry.incident + "'") + " " + ("'" + (Object.keys(entry.details) .map(function (key) { return (key + ": " + JSON.stringify(entry.details[key])); }) .join("\n")) + "'")); nm_child_process.exec(command, function (error, stdout, stderr) { // do noting }); }; return class_channel_notify; }(log.class_channel)); log.class_channel_notify = class_channel_notify; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var class_channel_minlevel = /** @class */ (function (_super) { __extends(class_channel_minlevel, _super); /** */ function class_channel_minlevel(core, threshold) { var _this = _super.call(this) || this; _this.core = core; _this.threshold = threshold; return _this; } /** */ class_channel_minlevel.prototype.add = function (entry) { if (log.level_order(this.threshold, entry.level)) { this.core.add(entry); } }; return class_channel_minlevel; }(log.class_channel)); log.class_channel_minlevel = class_channel_minlevel; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ function translate_level(level_string) { return { "debug": log.enum_level.debug, "info": log.enum_level.info, "notice": log.enum_level.notice, "warning": log.enum_level.warning, "error": log.enum_level.error }[level_string]; } /** */ function channel_make(description) { var _a, _b; switch (description.kind) { default: { throw (new Error("unhandled log channel kind: " + description.kind)); break; } case "console": { return (new log.class_channel_minlevel(new log.class_channel_console(), translate_level((_a = description.data["threshold"]) !== null && _a !== void 0 ? _a : "debug"))); break; } case "notify": { return (new log.class_channel_minlevel(new log.class_channel_notify(), translate_level((_b = description.data["threshold"]) !== null && _b !== void 0 ? _b : "debug"))); break; } } } log.channel_make = channel_make; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:log«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:log« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var log; (function (log) { /** */ var _channel_stack = null; /** */ function conf_default() { return [ new log.class_channel_minlevel(new log.class_channel_console(), log.enum_level.notice), new log.class_channel_minlevel(new log.class_channel_notify(), log.enum_level.error), ]; } log.conf_default = conf_default; /** */ function conf_push(channels) { if (_channel_stack === null) { _channel_stack = []; } _channel_stack.push(channels); } log.conf_push = conf_push; /** */ function conf_pop() { if (_channel_stack.length > 0) { _channel_stack.pop(); } else { // do nothing } } log.conf_pop = conf_pop; /** */ function setup() { if (_channel_stack === null) { _channel_stack = []; conf_push(conf_default()); } else { // do nothing } } log.setup = setup; /** */ function add(entry) { setup(); _channel_stack.slice(-1)[0].forEach(function (channel) { return channel.add(entry); }); } log.add = add; /** */ function debug(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.debug, "incident": incident, "details": details }); } log.debug = debug; /** */ function info(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.info, "incident": incident, "details": details }); } log.info = info; /** */ function notice(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.notice, "incident": incident, "details": details }); } log.notice = notice; /** */ function warning(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.warning, "incident": incident, "details": details }); } log.warning = warning; /** */ function error(incident, details) { if (details === void 0) { details = {}; } add({ "level": log.enum_level.error, "incident": incident, "details": details }); } log.error = error; })(log = lib_plankton.log || (lib_plankton.log = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:args«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:args« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:args« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:args«. If not, see . */ var lib_args; (function (lib_args) { /** */ var enum_environment; (function (enum_environment) { enum_environment["cli"] = "cli"; enum_environment["url"] = "url"; })(enum_environment = lib_args.enum_environment || (lib_args.enum_environment = {})); ; /** */ var enum_kind; (function (enum_kind) { enum_kind["positional"] = "positional"; enum_kind["volatile"] = "volatile"; })(enum_kind = lib_args.enum_kind || (lib_args.enum_kind = {})); ; /** */ var enum_type; (function (enum_type) { enum_type["boolean"] = "boolean"; enum_type["integer"] = "int"; enum_type["float"] = "float"; enum_type["string"] = "string"; })(enum_type = lib_args.enum_type || (lib_args.enum_type = {})); ; /** */ var enum_mode; (function (enum_mode) { enum_mode["replace"] = "replace"; enum_mode["accumulate"] = "accumulate"; })(enum_mode = lib_args.enum_mode || (lib_args.enum_mode = {})); ; })(lib_args || (lib_args = {})); /* This file is part of »bacterio-plankton:args«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:args« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:args« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:args«. If not, see . */ var lib_args; (function (lib_args) { /** * @author fenris */ var class_argument = /** @class */ (function () { /** * @author fenris */ function class_argument(_a) { var name = _a["name"], _b = _a["type"], type = _b === void 0 ? lib_args.enum_type.string : _b, _c = _a["kind"], kind = _c === void 0 ? lib_args.enum_kind.positional : _c, _d = _a["mode"], mode = _d === void 0 ? lib_args.enum_mode.replace : _d, _e = _a["default"], default_ = _e === void 0 ? null : _e, _f = _a["info"], info = _f === void 0 ? null : _f, _g = _a["parameters"], parameters = _g === void 0 ? {} : _g, _h = _a["hidden"], hidden = _h === void 0 ? false : _h; this.name = name; this.type = type; this.kind = kind; this.mode = mode; this.default_ = default_; this.info = info; this.parameters = parameters; this.hidden = hidden; if (!this.check()) { throw (new Error("invalid argument-setup")); } } /** * @author fenris */ class_argument.positional = function (_a) { var name = _a["name"], _b = _a["type"], type = _b === void 0 ? lib_args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? lib_args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, index = _a["index"]; return (new class_argument({ "name": name, "kind": lib_args.enum_kind.positional, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "parameters": { "index": index } })); }; /** * @author fenris */ class_argument.volatile = function (_a) { var name = _a["name"], _b = _a["type"], type = _b === void 0 ? lib_args.enum_type.string : _b, _c = _a["mode"], mode = _c === void 0 ? lib_args.enum_mode.replace : _c, _d = _a["default"], default_ = _d === void 0 ? null : _d, _e = _a["info"], info = _e === void 0 ? null : _e, _f = _a["hidden"], hidden = _f === void 0 ? false : _f, indicators_short = _a["indicators_short"], indicators_long = _a["indicators_long"]; return (new class_argument({ "name": name, "kind": lib_args.enum_kind.volatile, "type": type, "mode": mode, "default": default_, "info": info, "hidden": hidden, "parameters": { "indicators_short": indicators_short, "indicators_long": indicators_long } })); }; /** * @author fenris */ class_argument.prototype.check = function () { var _this = this; return [ function () { return ((!(_this.kind == lib_args.enum_kind.volatile)) || (("indicators_long" in _this.parameters) && (_this.parameters["indicators_long"]["length"] >= 0))); }, ].every(function (condition) { return condition(); }); }; /** * @author fenris */ class_argument.prototype.name_get = function () { return this.name; }; /** * @author fenris */ class_argument.prototype.kind_get = function () { return this.kind; }; /** * @author fenris */ class_argument.prototype.type_get = function () { return this.type; }; /** * @author fenris */ class_argument.prototype.mode_get = function () { return this.mode; }; /** * @author fenris */ class_argument.prototype.default_get = function () { return this.default_; }; /** * @author fenris */ class_argument.prototype.parameters_get = function () { return this.parameters; }; /** * @author fenris */ class_argument.prototype.hidden_get = function () { return this.hidden; }; /** * @author fenris */ class_argument.prototype.toString = function () { return "<" + this.name + ">"; }; /** * @author fenris */ class_argument.prototype.indicator_main = function () { if (this.kind === lib_args.enum_kind.volatile) { return this.parameters["indicators_long"][0]; } else { return null; } }; /** * @author fenris */ class_argument.prototype.pattern_value = function () { switch (this.type) { case lib_args.enum_type.boolean: { return "false|true"; break; } case lib_args.enum_type.integer: { return "[0-9]+"; break; } case lib_args.enum_type.float: { return "\\d*(?:\\.\\d+)?"; break; } case lib_args.enum_type.string: { return "\\S+"; break; } default: { throw (new Error("unhandled type " + this.type)); break; } } }; /** * @author fenris */ class_argument.prototype.extract = function (raw) { switch (this.type) { case lib_args.enum_type.boolean: { return (raw != "false"); break; } case lib_args.enum_type.integer: { return parseInt(raw); break; } case lib_args.enum_type.float: { return parseFloat(raw); break; } case lib_args.enum_type.string: { return raw; break; } default: { throw (new Error("unhandled type " + this.type)); break; } } }; /** * @author fenris */ class_argument.prototype.assign = function (data, target, raw) { var value = this.extract(raw); switch (this.mode) { case lib_args.enum_mode.replace: { data[target] = value; break; } case lib_args.enum_mode.accumulate: { /* if (! (this.name in data)) { data[this.name] = []; } */ data[target].push(value); break; } default: { throw (new Error("unhandled mode " + this.mode)); } } }; /** * @author fenris */ class_argument.prototype.make = function (data, target) { var value = data[target]; return value.toString(); }; /** * @author fenris */ class_argument.prototype.generate_help = function () { var _this = this; var _a, _b, _c, _d; var output = ""; { switch (this.kind) { case lib_args.enum_kind.positional: { var line = ""; line += "\t"; line += "<" + this.name + ">"; line += "\n"; output += line; } case lib_args.enum_kind.volatile: { var line = ""; line += "\t"; if (this.type === lib_args.enum_type.boolean) { line += ([] .concat(((_a = this.parameters["indicators_short"]) !== null && _a !== void 0 ? _a : []).map(function (indicator) { return ("-" + indicator); })) .concat(((_b = this.parameters["indicators_long"]) !== null && _b !== void 0 ? _b : []).map(function (indicator) { return ("--" + indicator); })) .join(" | ")); } else { line += ([] .concat(((_c = this.parameters["indicators_short"]) !== null && _c !== void 0 ? _c : []).map(function (indicator) { return ("-" + indicator + " " + ("<" + _this.name + ">")); })) .concat(((_d = this.parameters["indicators_long"]) !== null && _d !== void 0 ? _d : []).map(function (indicator) { return ("--" + indicator + "=" + ("<" + _this.name + ">")); })) .join(" | ")); } line += "\n"; output += line; } } } { var line = ""; line += "\t\t"; var infotext = ((this.info == null) ? "(no info available)" : this.info); line += infotext; if ((this.type != "boolean") && (this.default_ != null)) { line += "; default: " + this.default_.toString(); } line += "\n"; output += line; } return output; }; return class_argument; }()); lib_args.class_argument = class_argument; })(lib_args || (lib_args = {})); /* This file is part of »bacterio-plankton:args«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:args« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:args« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:args«. If not, see . */ var lib_args; (function (lib_args) { /** * @author fenris */ var settings = { "environment": { "cli": { "symbols": { "delimiter": " ", "prefix": "--", "assignment": "=" } }, "url": { "symbols": { "delimiter": "&", "prefix": "", "assignment": "=" } } } }; /** * @author fenris */ lib_args.verbosity = 0; /** * @author fenris * @todo check validity */ var class_handler = /** @class */ (function () { /** * @author fenris */ function class_handler(arguments_) { this.arguments_ = arguments_; } /** * @author fenris */ class_handler.prototype.filter = function (kind) { var arguments_ = {}; for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { var _b = _a[_i], name = _b[0], argument = _b[1]; if (argument.kind_get() == kind) { arguments_[name] = argument; } } return arguments_; }; /** * @author fenris */ class_handler.prototype.read = function (environment, input, data) { var _this = this; if (data === void 0) { data = {}; } switch (environment) { case lib_args.enum_environment.cli: case lib_args.enum_environment.url: { // default values { for (var _i = 0, _a = Object.entries(this.arguments_); _i < _a.length; _i++) { var _b = _a[_i], name = _b[0], argument = _b[1]; data[name] = argument.default_get(); } } // preprocessing { // short indicators (lil hacky ...) { if (environment == lib_args.enum_environment.cli) { for (var _c = 0, _d = Object.entries(this.filter(lib_args.enum_kind.volatile)); _c < _d.length; _c++) { var _e = _d[_c], name = _e[0], argument = _e[1]; // console.info(argument.parameters_get()["indicators_short"].join("|")); var pattern_from = ""; { pattern_from += "(?:^|" + settings["environment"][environment]["symbols"]["delimiter"] + ")"; pattern_from += "-" + argument.parameters_get()["indicators_short"].join("|"); pattern_from += "(?:$|" + settings["environment"][environment]["symbols"]["delimiter"] + ")"; } var pattern_to = ""; { pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; pattern_to += settings["environment"][environment]["symbols"]["prefix"]; pattern_to += argument.indicator_main(); if (argument.type_get() == lib_args.enum_type.boolean) { pattern_to += settings["environment"][environment]["symbols"]["delimiter"]; } else { pattern_to += settings["environment"][environment]["symbols"]["assignment"]; } } var result = input.replace(new RegExp(pattern_from, "g"), pattern_to); lib_plankton.log.debug("lib_args:read:replacing", { "pattern_from": pattern_from, "pattern_to": pattern_to, "input": input, "result": result }); input = result; } } } lib_plankton.log.debug("lib_args:read:current_input", { "input": input }); } // parsing { var parts = input .split(settings["environment"][environment]["symbols"]["delimiter"]) .filter(function (x) { return (x != ""); }); var index_expected_1 = 0; parts.forEach(function (part) { lib_plankton.log.debug("lib_args:read:analyzing", { "part": part }); var found = [ function () { lib_plankton.log.debug("lib_args:read:probing_as_volatile", { "part": part }); for (var _i = 0, _a = Object.entries(_this.filter(lib_args.enum_kind.volatile)); _i < _a.length; _i++) { var _b = _a[_i], name = _b[0], argument = _b[1]; lib_plankton.log.debug("lib_args:read:probing_as_volatile:trying", { "part": part, "argument": argument.toString() }); var pattern = ""; { var pattern_front = ""; pattern_front += "" + settings["environment"][environment]["symbols"]["prefix"]; pattern_front += "(?:" + argument.parameters_get()["indicators_long"].join("|") + ")"; pattern += pattern_front; } { var pattern_back = ""; pattern_back += "" + settings["environment"][environment]["symbols"]["assignment"]; pattern_back += "(" + argument.pattern_value() + ")"; if (argument.type_get() == lib_args.enum_type.boolean) { pattern_back = "(?:" + pattern_back + ")?"; } pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", { "pattern": pattern }); var regexp = new RegExp(pattern); var matching = regexp.exec(part); lib_plankton.log.debug("lib_args:read:probing_as_volatile:matching", { "matching": matching }); if (matching == null) { // do nothing } else { argument.assign(data, name, matching[1]); return true; } } return false; }, function () { lib_plankton.log.debug("lib_args:read:probing_as_positional", { "part": part }); var positional = _this.filter(lib_args.enum_kind.positional); for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) { var _b = _a[_i], name = _b[0], argument = _b[1]; if (argument.parameters_get()['index'] !== index_expected_1) { // do nothing } else { lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", { "part": part, "argument": argument.toString() }); var pattern = ""; { var pattern_back = ""; pattern_back += "(" + argument.pattern_value() + ")"; pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", { "pattern": pattern }); var regexp = new RegExp(pattern); var matching = regexp.exec(part); lib_plankton.log.debug("lib_args:read:probing_as_positional:matching", { "matching": matching }); if (matching == null) { return false; } else { argument.assign(data, name, matching[1]); index_expected_1 += 1; return true; } } } return false; }, ].some(function (x) { return x(); }); if (!found) { lib_plankton.log.warning("lib_args:read:could_not_parse", { "part": part }); } }); } return data; break; } default: { throw (new Error("unhandled environment " + environment)); break; } } }; /** * @author fenris * @todo handle if the data object doesn't have the required field or the type is wrong or sth. */ class_handler.prototype.write = function (environment, data) { switch (environment) { case lib_args.enum_environment.cli: { return (([] .concat(Object.entries(this.filter(lib_args.enum_kind.volatile)).map(function (_a) { var name = _a[0], argument = _a[1]; var values; switch (argument.mode_get()) { case lib_args.enum_mode.replace: { values = [data[argument.name_get()]]; break; } case lib_args.enum_mode.accumulate: { values = data[argument.name_get()]; break; } } return (values .map(function (value) { return ((settings["environment"][environment]["symbols"]["prefix"] + argument.parameters_get()["indicators_long"][0]) + (settings["environment"][environment]["symbols"]["assignment"] + value.toString())); }) .join(" ")); })) .concat(Object.entries(this.filter(lib_args.enum_kind.positional)).map(function (_a) { var name = _a[0], argument = _a[1]; var raw = ""; { var raw_back = ""; raw_back += argument.make(data, name); raw += raw_back; } return raw; }))) .join(settings["environment"][environment]["symbols"]["delimiter"])); break; } default: { throw (new Error("unhandled environment " + environment)); break; } } }; /** * @desc manpage-like info-sheet * @author fenris */ class_handler.prototype.generate_help = function (_a) { var _b = _a["programname"], programname = _b === void 0 ? null : _b, _c = _a["author"], author = _c === void 0 ? null : _c, _d = _a["description"], description = _d === void 0 ? null : _d, _e = _a["executable"], executable = _e === void 0 ? null : _e; var environment = lib_args.enum_environment.cli; var output = ""; { var section = ""; { var line = ""; line += ""; line += "INFO"; line += "\n"; section += line; } { var line = ""; line += "\t"; line += programname + " -- " + description; line += "\n"; section += line; } section += "\n"; output += section; } { if (author != null) { var section = ""; { var line = ""; line += ""; line += "AUTHOR"; line += "\n"; section += line; } { var line = ""; line += "\t"; line += "" + author; line += "\n"; section += line; } section += "\n"; output += section; } } { var section = ""; { var line = ""; line += ""; line += "SYNOPSIS"; line += "\n"; section += line; } { var line = ""; line += "\t"; line += executable; line += settings["environment"][environment]["symbols"]["delimiter"]; line += Object.entries(this.filter(lib_args.enum_kind.positional)) .map(function (_a) { var name = _a[0], argument = _a[1]; var part = ""; part += "<" + argument.name_get() + ">"; return part; }) .join(settings["environment"][environment]["symbols"]["delimiter"]); line += settings["environment"][environment]["symbols"]["delimiter"]; line += Object.entries(this.filter(lib_args.enum_kind.volatile)) .filter(function (_a) { var name = _a[0], argument = _a[1]; return (!argument.hidden_get()); }) .map(function (_a) { var name = _a[0], argument = _a[1]; var part = ""; // part += settings["environment"][environment]["symbols"]["prefix"]; part += "-"; part += argument.parameters_get()["indicators_short"][0]; if (argument.type_get() != "boolean") { /* part += settings["environment"][environment]["symbols"]["assignment"]; part += `<${argument.name_get()}>`; */ part += " "; part += "<" + argument.name_get() + ">"; } part = "[" + part + "]"; return part; }) .join(settings["environment"][environment]["symbols"]["delimiter"]); line += "\n"; section += line; } section += "\n"; output += section; } { var section = ""; { var line = ""; line += ""; line += "OPTIONS"; line += "\n"; section += line; } { section += (Object.entries(this.arguments_) .filter(function (_a) { var name = _a[0], argument = _a[1]; return (!argument.hidden_get()); }) .map(function (_a) { var name = _a[0], argument = _a[1]; return argument.generate_help(); }) .join("\n")); } section += "\n"; output += section; } return output; }; return class_handler; }()); lib_args.class_handler = class_handler; })(lib_args || (lib_args = {})); /* This file is part of »bacterio-plankton:client«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:client« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:client« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:client«. If not, see . */ var lib_client; (function (lib_client) { /** * @author fenris */ function make(host, port, verbosity = 1) { return { "host": host, "port": port, "verbosity": verbosity, }; } lib_client.make = make; /** * @author fenris */ function log(subject, level, message) { if (subject.verbosity >= level) { console.log("[client]", message); } else { // do nothing } } /** * @author fenris */ function query(subject, input) { const nm_net = require("net"); return (new Promise((resolve, reject) => { const client = nm_net.createConnection({ "host": subject.host, "port": subject.port }, () => { log(subject, 2, "connection established"); client.write(input); }); client.on("data", (output_raw) => { const output = output_raw.toString(); resolve(output); client.end(); }); client.on("end", () => { log(subject, 2, "connection terminated"); }); })); } lib_client.query = query; })(lib_client || (lib_client = {})); /* This file is part of »bacterio-plankton:client«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:client« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:client« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:client«. If not, see . */ var lib_client; (function (lib_client) { /** * @author fenris */ class class_client { /** * @author fenris */ constructor(host, port, verbosity) { this.subject = lib_client.make(host, port, verbosity); } /** * @author fenris */ query(input) { return lib_client.query(this.subject, input); } } lib_client.class_client = class_client; })(lib_client || (lib_client = {})); /* This file is part of »bacterio-plankton:file«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:file« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:file« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:file«. If not, see . */ var lib_file; (function (lib_file) { /** * @author fenris */ function read_regular_promise(path) { const nm_fs = require("fs"); return (lib_call.promise_make((resolve, reject) => { nm_fs.readFile(path, { "encoding": "utf8", "flag": "r", }, (error, content) => { if (error == null) { resolve(content); } else { reject(error); } }); })); } /** * @author fenris */ function read_http_promise(path) { return (lib_call.promise_make((resolve, reject) => { const nm_url = require("url"); const parsed_url = nm_url.parse(path, false, true); const client = ((parsed_url.protocol === "https:") ? require("https") : require("http")); const default_port = ((parsed_url.protocol == "https:") ? 443 : 80); const options = { "hostname": parsed_url.hostname, "port": (parsed_url.port || default_port), "path": parsed_url.path, "method": "GET" }; let req = client.request(options, (res) => { let data = ""; // @todo res.on("data", (chunk) => { data += chunk; }); res.on("end", () => { resolve(data); }); }); req.end(); req.on("error", (error) => { reject(error); }); })); } /** * @author fenris */ function write_regular_promise(path, content) { const nm_fs = require("fs"); return (lib_call.promise_make((resolve, reject) => { nm_fs.writeFile(path, content, { "encoding": "utf8", "flag": "w", }, (error) => { if (error == null) { resolve(undefined); } else { reject(error); } }); })); } /** * @author maspr,fenris */ function determine_handler(path) { if (new RegExp("^https?:\/\/").test(path)) { return "http"; } else { return "file"; } } /** * @author fenris,maspr * @todo clear up if http(s)-handling belongs here or not ... */ function read_promise(path) { switch (determine_handler(path)) { case "file": { return read_regular_promise(path); break; } case "http": { return read_http_promise(path); break; } default: { const message = "unhandled protocol"; return lib_call.promise_reject(new Error(message)); break; } } } lib_file.read_promise = read_promise; /** * @author fenris */ function write_promise(path, content) { return write_regular_promise(path, content); } lib_file.write_promise = write_promise; /** * @author fenris */ function read_stdin() { return (new Promise((resolve, reject) => { let input_raw = ""; process.stdin.setEncoding("utf8"); process.stdin.on("readable", () => { let chunk; while ((chunk = process.stdin.read()) !== null) { input_raw += chunk; } }); process.stdin.on("end", () => { resolve(input_raw); }); })); } lib_file.read_stdin = read_stdin; })(lib_file || (lib_file = {})); /* This file is part of »bacterio-plankton:file«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:file« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:file« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:file«. If not, see . */ var lib_file; (function (lib_file) { /** * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead */ function read_json_promise(path) { return (lib_call.promise_resolve(undefined) .then(_ => lib_file.read_promise(path)) .then(content => lib_call.promise_make((resolve, reject) => { let error; let data; try { data = JSON.parse(content); error = null; } catch (exception) { let message = `invalid json '${path}'`; error = new class_error(message, [exception]); } if (error == null) { resolve(data); } else { reject(error); } }))); } lib_file.read_json_promise = read_json_promise; /** * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead */ function write_json_promise(path, data) { return lib_file.write_promise(path, JSON.stringify(data, undefined, "\t")); } lib_file.write_json_promise = write_json_promise; /** * @author fenris * @deprecated use promises instead of executors */ function read_executor(path) { return lib_call.promise_to_executor(lib_file.read_promise(path)); } lib_file.read_executor = read_executor; /** * @author fenris * @deprecated use promises instead of executors */ function write_executor(path, content) { return lib_call.promise_to_executor(lib_file.write_promise(path, content)); } lib_file.write_executor = write_executor; /** * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead * @deprecated use promises instead of executors */ function read_json_executor(path) { return lib_call.promise_to_executor(read_json_promise(path)); } lib_file.read_json_executor = read_json_executor; /** * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead * @deprecated use promises instead of executors */ function write_json_executor(path, data) { return lib_call.promise_to_executor(write_json_promise(path, data)); } lib_file.write_json_executor = write_json_executor; /** * @desc reads a file * @author fenris * @todo replace with promise version */ function read(path) { return read_executor(path); } lib_file.read = read; /** * @desc writes a file * @author fenris * @todo replace with promise version */ function write(path, content) { return write_executor(path, content); } lib_file.write = write; /** * @desc reads a json file * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead */ function read_json(path) { return read_json_executor(path); } lib_file.read_json = read_json; /** * @desc writes a json file * @author fenris * @deprecated lib_file shouldn't care for code stuff; use a combination of lib_file and lib_code instead */ function write_json(path, data) { return write_json_executor(path, data); } lib_file.write_json = write_json; })(lib_file || (lib_file = {})); /* This file is part of »bacterio-plankton:observer«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:observer« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:observer« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:observer«. If not, see . */ var lib_observer; (function (lib_observer) { /** * @author fenris */ function make(_a) { var _b = _a === void 0 ? {} : _a, _c = _b["force_registration"], force_registration = _c === void 0 ? false : _c, _d = _b["no_attendants_warn_do"], no_attendants_warn_do = _d === void 0 ? false : _d, _e = _b["no_attendants_warn_action"], no_attendants_warn_action = _e === void 0 ? (function (eventname) { return console.warn("no attendants for event '" + eventname + "'"); }) : _e; return { "actions": {}, "force_registration": force_registration, "no_attendants_warn_do": no_attendants_warn_do, "no_attendants_warn_action": no_attendants_warn_action, }; } lib_observer.make = make; /** * @author fenris */ function present(observer, eventname) { return (observer.actions.hasOwnProperty(eventname)); } /** * @author fenris */ function register(observer, eventname) { if (!present(observer, eventname)) { observer.actions[eventname] = []; } else { // do nothing // warn that it is already registered? } } lib_observer.register = register; /** * @author fenris */ function attend(observer, eventname, action) { if (!present(observer, eventname)) { if (observer.force_registration) { throw (new Error("no event '" + eventname + "'")); } else { register(observer, eventname); } } else { // do nothing } observer.actions[eventname].push(action); } lib_observer.attend = attend; /** * @author fenris */ function notify(observer, eventname, data) { if (!present(observer, eventname)) { if (observer.force_registration) { throw (new Error("no event '" + eventname + "'")); } else { register(observer, eventname); } } else { if (observer.no_attendants_warn_do) { if (observer.actions[eventname].length <= 0) { observer.no_attendants_warn_action(eventname); } else { // do nothing } } else { // do nothing } observer.actions[eventname] .forEach(function (action) { action(data); }); } } lib_observer.notify = notify; })(lib_observer || (lib_observer = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ function sequence(length) { return ((length > 0) ? sequence(length - 1).concat([length - 1]) : []); } /** * @author fenris */ function find(word, part, equality, /*= instance_collate*/ right_to_left = false) { let result = -1; let found = sequence(word.length - part.length + 1).some(function (position) { let position_ = (right_to_left ? (word.length - part.length - position) : (position)); let matches = sequence(part.length).every(index => equality(word[position_ + index], part[index])); if (matches) { result = position_; return true; } else { return false; } }); return result; } lang.find = find; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ class class_symbol_terminal { /** * @desc [constructor] * @author fenris */ constructor(terminal, equality_terminal = ((x, y) => (x == y))) { this.terminal = terminal; this.equality_terminal = equality_terminal; } /** * @author fenris */ terminal_get() { return this.terminal; } /** * @override * @author fenris */ equals(symbol) { if (symbol instanceof class_symbol_terminal) { let symbol_terminal = (symbol); return this.equality_terminal(this.terminal, symbol_terminal.terminal); } else { return false; } } /** * @override * @author fenris */ toString() { return JSON.stringify(this); } /** * @author fenris */ static tree_generic(terminal) { return (new lib_plankton.lang.class_symbol_terminal(terminal)); } /** * @author fenris */ static tree_default(terminal) { return (new lib_plankton.lang.class_symbol_terminal(terminal)); } } lang.class_symbol_terminal = class_symbol_terminal; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ class class_symbol_variable { /** * @desc [constructor] * @author fenris */ constructor(variable, meaning = undefined) { this.variable = variable; this.meaning = meaning; } /** * @desc [accessor] [getter] * @author fenris */ variable_get() { return this.variable; } /** * @desc [accessor] [getter] * @author fenris */ meaning_get() { return this.meaning; } /** * @override * @author fenris */ equals(symbol) { if (symbol instanceof class_symbol_variable) { let symbol_variable = (symbol); return (this.variable == symbol_variable.variable); } else { return false; } } /** * @override * @author fenris */ toString() { return JSON.stringify(this); } /** * @author fenris */ static tree_generic(variable) { return (new lib_plankton.lang.class_symbol_variable(variable)); } /** * @author fenris */ static tree_default(variable) { return (new lib_plankton.lang.class_symbol_variable(variable)); } } lang.class_symbol_variable = class_symbol_variable; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ function lexerrule_make(search, construct) { let observer = lib_observer.make(); lib_observer.register(observer, "start"); lib_observer.register(observer, "message_sequence"); lib_observer.register(observer, "maximum_reached"); lib_observer.attend(observer, "start", ({ "rule": rule }) => { lib_plankton.log.debug("lang:lexer:run:current_rule", { "rule": lexerrule_show(rule), }); }); lib_observer.attend(observer, "message_sequence", ({ "tokens": tokens }) => { lib_plankton.log.debug("lang:lexer:run:current_sequence", { "tokens": tokens, }); }); lib_observer.attend(observer, "maximum_reached", () => { lib_plankton.log.warning("lang:lexer:run:maximum_reached", {}); }); return { "search": search, "construct": construct, "observer": observer, }; } lang.lexerrule_make = lexerrule_make; /** * @author fenris * @todo schön machen? is aber vermutlich gar nicht möglich :/ */ function lexerrule_show(rule) { return "(nicht darstellbar)"; } lang.lexerrule_show = lexerrule_show; /** * @author fenris */ function lexerrule_apply(rule, tokens) { /** * @todo Wert sollte konfigurierbar sein */ let maximum = (1 << 10); lib_observer.notify(rule.observer, "start", { "rule": rule }); let offset = 0; // process _all_ occurences while (true) { lib_observer.notify(rule.observer, "message_sequence", { "tokens": tokens }); if (maximum-- <= 0) { lib_observer.notify(rule.observer, "maximum_reached", {}); break; } let found = tokens.slice(offset).some(function (token_old, index) { if (token_old.terminal.is_just()) { return false; } else { let result = rule.search(token_old.sequence); if (!result.found) { return false; } else { // der Ersatz für den Platz von "token_old" let tokens_new = []; // die Zeichen des alten Tokens, die vor der Übereinstimmung stehen { let nonempty = (result.data.position > 0); if (nonempty) { let sequence = token_old.sequence.slice(0, result.data.position); tokens_new.push({ "sequence": sequence, "terminal": new class_nothing(), }); } } // die Zeichen der Übereinstimmung { let sequence = token_old.sequence.slice(result.data.position, result.data.position + result.data.length); let terminals = rule.construct(sequence); terminals.forEach((terminal) => { tokens_new.push({ "sequence": null, "terminal": new class_just(terminal), }); }); } // die Zeichen des alten Tokens, die hinter der Übereinstimmung stehen { let nonempty = (result.data.position + result.data.length < token_old.sequence.length); if (nonempty) { let sequence = token_old.sequence.slice(result.data.position + result.data.length /*, token_old.sequence.length*/); tokens_new.push({ "sequence": sequence, "terminal": new class_nothing(), }); } } /* console.log("-- offset_old: ", offset); console.log("-- index: ", index); console.log("-- token_old: ", token_old); offset += index; console.log("-- offset_new: ", offset); */ tokens = [] .concat(tokens.slice(0, index)) .concat(tokens_new) .concat(tokens.slice(index + 1)); return true; } } }); if (!found) { break; } } return tokens; } lang.lexerrule_apply = lexerrule_apply; /** * @author fenris */ function lexerrule_pass() { return lexerrule_make((part) => ({ "found": true, "data": { "position": 0, "length": 1 } }), (part) => part); } lang.lexerrule_pass = lexerrule_pass; /** * @author fenris */ function lexerrule_pattern_generic(rule_raw) { let regexp = new RegExp(rule_raw.pattern); return lexerrule_make((part) => { const part_ = part.join(""); // console.log(`searching for '${regexp.toString()}' in '${part_}' ...`); const match_ = regexp.exec(part_); // console.log(`... result: `, match_); if (match_ == null) { return { "found": false }; } else { return { "found": true, "data": { "position": match_.index, "length": match_[0].length } }; } }, rule_raw.construct); } lang.lexerrule_pattern_generic = lexerrule_pattern_generic; /** * @author fenris */ function lexerrule_pattern_ignore(pattern) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [] })); } lang.lexerrule_pattern_ignore = lexerrule_pattern_ignore; /** * @author fenris */ function lexerrule_pattern_void(pattern, id) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [{ "id": id, "data": {} }], })); } lang.lexerrule_pattern_void = lexerrule_pattern_void; /** * @author fenris */ function lexerrule_pattern_boolean(pattern, id, value) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [{ "id": id, "data": { "value": value } }], })); } lang.lexerrule_pattern_boolean = lexerrule_pattern_boolean; /** * @author fenris */ function lexerrule_pattern_int(pattern, id) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [{ "id": id, "data": { "value": parseInt(tokens.join("")) } }], })); } lang.lexerrule_pattern_int = lexerrule_pattern_int; /** * @author fenris */ function lexerrule_pattern_float(pattern, id) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [{ "id": id, "data": { "value": parseFloat(tokens.join("")) } }], })); } lang.lexerrule_pattern_float = lexerrule_pattern_float; /** * @author fenris */ function lexerrule_pattern_string(pattern, id) { return (lexerrule_pattern_generic({ "pattern": pattern, "construct": tokens => [{ "id": id, "data": { "value": tokens.join("") } }], })); } lang.lexerrule_pattern_string = lexerrule_pattern_string; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /* -- input [("0 & !0",—)] -- ws [("0",—),("& !0",—)] [("0",—),("&",—),("!0",—)] -- const [("0",),("&",—),("!0",—)] [("0",),("&",—),("!",—),("0",)] -- not [("0",),("&",—),("!",),("0",)] -- and [("0",),("&",),("!",),("0",)] */ /** * @author fenris */ function lexer_dumb_make(rules) { let observer = lib_observer.make(); lib_observer.register(observer, "start"); lib_observer.register(observer, "fail"); lib_observer.attend(observer, "start", ({ "input": input }) => { lib_plankton.log.info("lib_plankton.lang:lexer:run:begin", { "input": input, }); }); lib_observer.attend(observer, "fail", ({ "open": open }) => { lib_plankton.log.warning("lib_plankton.lang:lexer:run:fail", { "sequence": open.map(token => String(token.sequence)), }); }); return { "rules": rules, "observer": observer, }; } lang.lexer_dumb_make = lexer_dumb_make; /** * @author fenris */ function lexer_dumb_run(subject, input, configuration = { "use_reduce": false, }) { lib_observer.notify(subject.observer, "start", { "input": input }); let tokens; if (configuration.use_reduce) { tokens = subject.rules.reduce((tokens, rule) => lang.lexerrule_apply(rule, tokens), [ { "sequence": input, "terminal": new class_nothing(), } ]); } else { tokens = [ { "sequence": input, "terminal": new class_nothing(), } ]; subject.rules.forEach((rule) => (tokens = lang.lexerrule_apply(rule, tokens))); } let open = tokens.filter(token => token.terminal.is_nothing()); if (open.length > 0) { lib_observer.notify(subject.observer, "fail", { "open": open }); throw (new Error("failed")); } else { return tokens.map(token => token.terminal.cull()); } } lang.lexer_dumb_run = lexer_dumb_run; /** * @author fenris */ function lexer_dumb_pass() { return lexer_dumb_make([ lang.lexerrule_pass(), ]); } lang.lexer_dumb_pass = lexer_dumb_pass; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ class class_lexerrule { /** * @author fenris */ constructor(subject) { this.subject = subject; } /** * @author fenris */ static construct({ "search": search, "construct": construct, }) { let subject = lang.lexerrule_make(search, construct); return (new class_lexerrule(subject)); } /** * @author fenris */ subject_get() { return this.subject; } /** * @author fenris */ search(part) { return this.subject.search(part); } /** * @author fenris */ construct(part) { return this.subject.construct(part); } /** * @author fenris */ static pass() { return (new class_lexerrule(lang.lexerrule_pass())); } /** * @author fenris */ static pattern_generic(rule_raw) { return (new class_lexerrule(lang.lexerrule_pattern_generic(rule_raw))); } /** * @author fenris */ static pattern_ignore(pattern) { return (new class_lexerrule(lang.lexerrule_pattern_ignore(pattern))); } /** * @author fenris */ static pattern_void(pattern, id) { return (new class_lexerrule(lang.lexerrule_pattern_void(pattern, id))); } /** * @author fenris */ static pattern_boolean(pattern, id, value) { return (new class_lexerrule(lang.lexerrule_pattern_boolean(pattern, id, value))); } /** * @author fenris */ static pattern_int(pattern, id) { return (new class_lexerrule(lang.lexerrule_pattern_int(pattern, id))); } /** * @author fenris */ static pattern_float(pattern, id) { return (new class_lexerrule(lang.lexerrule_pattern_float(pattern, id))); } /** * @author fenris */ static pattern_string(pattern, id) { return (new class_lexerrule(lang.lexerrule_pattern_string(pattern, id))); } } lang.class_lexerrule = class_lexerrule; /** * @author fenris */ class class_lexer_dumb { /** * @author fenris */ constructor(subject) { this.subject = subject; } /** * @author fenris */ static construct(rules) { const subject = lang.lexer_dumb_make(rules.map(rule => rule.subject_get())); return (new class_lexer_dumb(subject)); } /** * @author fenris */ run(input) { return lang.lexer_dumb_run(this.subject, input); } /** * @author fenris */ static pass() { return (new class_lexer_dumb(lang.lexer_dumb_pass())); } } lang.class_lexer_dumb = class_lexer_dumb; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @desc [constructor] * @author fenris */ function parserrule_make({ "premise": premise, "conclusion": conclusion, "construct": construct, "right_to_left": right_to_left = false, }) { return { "premise": premise, "conclusion": conclusion, "construct": construct, "right_to_left": right_to_left, }; } lang.parserrule_make = parserrule_make; /** * @author fenris */ function parserrule_check(parserrule, sequence) { let position = lang.find(sequence, parserrule.conclusion, (x, y) => x.equals(y), parserrule.right_to_left); return position; } lang.parserrule_check = parserrule_check; /** * @author fenris */ function parserrule_construct(parserrule, args, terminals) { return parserrule.construct(args, terminals); } lang.parserrule_construct = parserrule_construct; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ function parser_dumb_make(start, rules, equality_terminal = ((x, y) => (x == y))) { let observer = lib_observer.make(); lib_observer.register(observer, "start"); lib_observer.register(observer, "message_sequence"); lib_observer.register(observer, "use_rule"); lib_observer.register(observer, "fail"); lib_observer.attend(observer, "start", ({ "input": input }) => { lib_plankton.log.info("lib_plankton.lang:parser:run:begin", { "input": input }); }); lib_observer.attend(observer, "message_sequence", ({ "sequence": sequence }) => { lib_plankton.log.debug("lib_plankton.lang:parser:run:current_sequence", { "tokens": sequence, }); }); lib_observer.attend(observer, "use_rule", ({ "rule": rule, "conclusion": conclusion }) => { lib_plankton.log.debug("lib_plankton.lang:parser:run:using_the_following_rule", { "conclusion": conclusion.map(symbol => symbol.toString()), "premise": rule.premise.toString(), }); }); lib_observer.attend(observer, "fail", ({ "sequence": sequence }) => { lib_plankton.log.error("lib_plankton.lang:parser:run:failed", { "last_sequence": sequence, }); }); return { "start": start, "rules": rules, "equality_terminal": equality_terminal, "observer": observer, }; } lang.parser_dumb_make = parser_dumb_make; /** * @override * @author fenris */ function parser_dumb_run(parser_dumb, input, target_variable) { if (target_variable === undefined) { target_variable = parser_dumb.start; } lib_observer.notify(parser_dumb.observer, "start", { "input": input }); let maximum = (1 << 10); let current = (input .map((terminal) => { return (new lang.class_symbol_terminal(terminal, parser_dumb.equality_terminal)); })); while (true) { lib_observer.notify(parser_dumb.observer, "message_sequence", { "sequence": current }); if (maximum-- <= 0) { break; } const found = parser_dumb.rules.some(function (rule, index) { let conclusion = rule.conclusion; let position = lang.parserrule_check(rule, current); if (position >= 0) { lib_observer.notify(parser_dumb.observer, "use_rule", { "rule": rule, "conclusion": conclusion }); let terminals = (current .slice(position, position + conclusion.length) .filter(x => (x instanceof lang.class_symbol_terminal /**/)) .map(element => (element).terminal_get())); let args = (current .slice(position, position + conclusion.length) .filter(x => (x instanceof lang.class_symbol_variable /**/)) .map(element => (element).meaning_get())); let meaning = rule.construct(args, terminals); let symbol = (new lang.class_symbol_variable(rule.premise, meaning)); current = ([] .concat(current.slice(0, position)) .concat([symbol]) .concat(current.slice(position + conclusion.length))); return true; } else { return false; } }); if (!found) { break; } } if ((current.length == 1) && (current[0] instanceof lang.class_symbol_variable /**/) && ((current[0]).variable_get() === target_variable)) { return (current[0]).meaning_get(); } else { lib_observer.notify(parser_dumb.observer, "fail", { "sequence": current }); /* console.warn("--", "parsing failed"); console.info("--", "last sequence was:"); current.forEach(element => console.info(element)); */ // return null; throw (new Error("parsing failed")); } } lang.parser_dumb_run = parser_dumb_run; /** * @author fenris */ function parser_dumb_tree(start, rules_raw, equality_terminal = ((x, y) => (x == y))) { return (parser_dumb_make(start, rules_raw.map((rule_raw) => { return (lang.parserrule_make({ "premise": rule_raw.premise, "conclusion": rule_raw.conclusion, "construct": (args, tokens) => { return { "label": rule_raw.label, "value": tokens, "children": args, }; }, "right_to_left": rule_raw.right_to_left, })); }), equality_terminal)); } lang.parser_dumb_tree = parser_dumb_tree; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ class class_parserrule { /** * @desc [constructor] * @author fenris */ constructor(subject) { this.subject = subject; } /** * @desc [constructor] * @author fenris */ static construct({ "premise": premise, "conclusion": conclusion, "construct": construct, "right_to_left": right_to_left = false, }) { return (new class_parserrule({ "premise": premise, "conclusion": conclusion, "construct": construct, "right_to_left": right_to_left, })); } /** * @desc [accessor] [getter] * @author fenris */ subject_get() { return this.subject; } /** * @desc [accessor] [getter] * @author fenris */ premise_get() { return this.subject.premise; } /** * @desc [accessor] [getter] * @author fenris */ conclusion_get() { return this.subject.conclusion; } /** * @desc [accessor] * @author fenris */ check(sequence) { return (lang.parserrule_check(this.subject, sequence)); } /** * @desc [accessor] * @author fenris */ construct(args, terminals) { return (lang.parserrule_construct(this.subject, args, terminals)); } } lang.class_parserrule = class_parserrule; /** * @author fenris * @todo fatal error on empty conclusion */ class class_parser_dumb { /** * @author fenris */ constructor(subject) { this.subject = subject; } /** * @author fenris */ static construct(start, rules, equality_terminal = ((x, y) => (x == y))) { const subject = lang.parser_dumb_make(start, rules.map(rule => rule.subject_get()), equality_terminal); return (new class_parser_dumb(subject)); } /** * @override * @author fenris */ run(input, target_variable) { return lang.parser_dumb_run(this.subject, input, target_variable); } /** * @author fenris */ static tree(start, rules_raw, equality_terminal = ((x, y) => (x == y))) { return (new class_parser_dumb(lang.parser_dumb_tree(start, rules_raw, equality_terminal))); } } lang.class_parser_dumb = class_parser_dumb; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ function reader_run(lexer_run, parser_run, input, target_variable) { const syntax = lexer_run(input); lib_plankton.log.info("lib_plankton.lang:reader:syntax", { "syntax": syntax, }); const semantics = parser_run(syntax, target_variable); lib_plankton.log.info("lib_plankton.lang:reader:semantics", { "semantics": semantics, }); return semantics; } lang.reader_run = reader_run; /** * @author fenris */ function reader_default({ "lexer_rules": lexer_rules, "parser_start": parser_start, "parser_rules": parser_rules, }) { return (new lib_plankton.lang.class_reader(lang.class_lexer_dumb.construct(lexer_rules), lang.class_parser_dumb.tree(parser_start, parser_rules, (x, y) => (x.id == y.id)))); } lang.reader_default = reader_default; /** * @author fenris */ function default_raw({ "lexer_rules": lexer_rules, "parser_start": parser_start, "parser_rules": parser_rules, }) { return (this.default({ "lexer_rules": lexer_rules.map((lexerrule_raw) => { switch (lexerrule_raw.type) { case "ignore": { return lang.class_lexerrule.pattern_ignore(lexerrule_raw.parameters["pattern"]); break; } case "void": { return lang.class_lexerrule.pattern_void(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "boolean": { return lang.class_lexerrule.pattern_boolean(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"], lexerrule_raw.parameters["value"]); break; } case "int": { return lang.class_lexerrule.pattern_int(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "float": { return lang.class_lexerrule.pattern_float(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "string": { return lang.class_lexerrule.pattern_string(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } default: { throw (new Error(`unhandled type for raw lexer-rule '${lexerrule_raw.type}'`)); break; } } }), "parser_start": parser_start, "parser_rules": parser_rules.map((parserrule_raw) => { return ({ "label": parserrule_raw.label, "premise": parserrule_raw.premise, "conclusion": parserrule_raw.conclusion.map(entry => { switch (entry.type) { case "terminal": { return (new lib_plankton.lang.class_symbol_terminal({ "id": entry.parameters["id"] })); break; } case "variable": { return (new lib_plankton.lang.class_symbol_variable(entry.parameters["id"])); break; } default: { throw (new Error(`unhandled type for raw parser-rule '${entry.type}'`)); break; } } }), "right_to_left": parserrule_raw.right_to_left, }); }), })); } lang.default_raw = default_raw; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {})); /* This file is part of »bacterio-plankton:lang«. Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' »bacterio-plankton:lang« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »bacterio-plankton:lang« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »bacterio-plankton:lang«. If not, see . */ var lib_plankton; (function (lib_plankton) { var lang; (function (lang) { /** * @author fenris */ class class_reader { /** * @author fenris */ constructor(lexer, parser) { this.lexer = lexer; this.parser = parser; } /** * @desc [accessor] yes, it's really just lexing and parsing * @author fenris */ run(input, target_variable) { /* const syntax : Array = this.lexer.run(input); lib_plankton.log.info( "lang:reader:syntax", { "syntax": syntax, } ); const semantics : type_result = this.parser.run(syntax, target_variable); lib_plankton.log.info( "lang:reader:semantics", { "semantics": semantics, } ); return semantics; */ return lang.reader_run((input) => this.lexer.run(input), (input, target_variable) => this.parser.run(input, target_variable), input, target_variable); } /** * @author fenris */ static default({ "lexer_rules": lexer_rules, "parser_start": parser_start, "parser_rules": parser_rules, }) { return (new lib_plankton.lang.class_reader(lang.class_lexer_dumb.construct(lexer_rules), lang.class_parser_dumb.tree(parser_start, parser_rules, (x, y) => (x.id == y.id)))); } /** * @author fenris */ static default_raw({ "lexer_rules": lexer_rules, "parser_start": parser_start, "parser_rules": parser_rules, }) { return (this.default({ "lexer_rules": lexer_rules.map((lexerrule_raw) => { switch (lexerrule_raw.type) { case "ignore": { return lang.class_lexerrule.pattern_ignore(lexerrule_raw.parameters["pattern"]); break; } case "void": { return lang.class_lexerrule.pattern_void(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "boolean": { return lang.class_lexerrule.pattern_boolean(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"], lexerrule_raw.parameters["value"]); break; } case "int": { return lang.class_lexerrule.pattern_int(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "float": { return lang.class_lexerrule.pattern_float(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } case "string": { return lang.class_lexerrule.pattern_string(lexerrule_raw.parameters["pattern"], lexerrule_raw.parameters["id"]); break; } default: { throw (new Error(`unhandled type for raw lexer-rule '${lexerrule_raw.type}'`)); break; } } }), "parser_start": parser_start, "parser_rules": parser_rules.map((parserrule_raw) => { return ({ "label": parserrule_raw.label, "premise": parserrule_raw.premise, "conclusion": parserrule_raw.conclusion.map(entry => { switch (entry.type) { case "terminal": { return (new lib_plankton.lang.class_symbol_terminal({ "id": entry.parameters["id"] })); break; } case "variable": { return (new lib_plankton.lang.class_symbol_variable(entry.parameters["id"])); break; } default: { throw (new Error(`unhandled type for raw parser-rule '${entry.type}'`)); break; } } }), "right_to_left": parserrule_raw.right_to_left, }); }), })); } } lang.class_reader = class_reader; })(lang = lib_plankton.lang || (lib_plankton.lang = {})); })(lib_plankton || (lib_plankton = {}));