diff --git a/lib/plankton/plankton.d.ts b/lib/plankton/plankton.d.ts index 9857f91..12c1050 100644 --- a/lib/plankton/plankton.d.ts +++ b/lib/plankton/plankton.d.ts @@ -6,13 +6,28 @@ type int = number; * @author fenris */ type float = number; +/** + * @author fenris + */ +type type_date = { + year: int; + month: int; + day: int; +}; /** * @author fenris */ type type_time = { - hours: int; - minutes: int; - seconds: int; + hour: int; + minute: int; + second: int; +}; +/** + * @author fenris + */ +type type_datetimeobject = { + date: type_date; + time: type_time; }; declare var process: any; declare var require: any; @@ -230,12 +245,12 @@ declare namespace lib_plankton.base { * * @author fenris */ - function get_current_timestamp(rounded?: boolean): int; + function get_current_timestamp(rounded?: boolean): float; /** */ function object_merge(core: Record, mantle: Record): Record; } -declare namespace lib_plankton.pod { +declare module lib_plankton.pod { /** * @author fenris */ @@ -279,7 +294,7 @@ declare namespace lib_plankton.pod { show_value?: ((value: type_value) => string); }): string; } -declare namespace lib_plankton.pod { +declare module lib_plankton.pod { /** */ class class_pod { @@ -294,59 +309,9 @@ declare namespace lib_plankton.pod { distinguish(function_empty: (() => type_result), function_filled: ((value: type_value) => type_result)): type_result; } } -declare namespace lib_plankton.call { - /** - * @author fenris - */ - type type_executor = ((resolve: (result?: type_result) => any, reject?: (reason?: type_reason) => void) => void); - /** - * @author fenris - */ - function executor_resolve(result: type_result): type_executor; - /** - * @author fenris - */ - function executor_reject(reason: type_reason): type_executor; - /** - * @author fenris - */ - function executor_transform(executor: type_executor, transform_result: (result_from: type_result_from) => type_result_to, transform_reason: (error_from: type_error_from) => type_error_to): type_executor; - /** - * @author fenris - */ - function executor_transform_default(executor: type_executor, transform_result: (result_from: type_result_from) => type_result_to, wrap_string?: string): type_executor; - /** - * @author fenris - */ - function executor_compose_sequential(first: type_executor, second: (result: type_result_first) => type_executor): type_executor; - /** - * @author fenris - */ - function executor_chain(state: type_state, executors: Array<(state: type_state) => type_executor>): type_executor; - /** - * @author fenris - */ - function executor_first(executors: Array>): type_executor>; - /** - * @author fenris - */ - function executor_condense(executors: Array>): type_executor, Error>; - /** - * @author fenris - * @deprecated use condense - */ - function executor_filter(executors: Array>, predicate: (element: type_element) => boolean): type_executor, Error>; - /** - * @author fenris - * @deprecated use condense - */ - function executor_map(executors: Array>, transformator: (element1: type_element1) => type_element2): type_executor, Error>; - /** - * @author fenris - * @deprecated use condense - */ - function executor_reduce(executors: Array>, initial: type_result, accumulator: (result: type_result, element: type_element) => type_result): type_executor; -} +/** + * might be completely obsolete + */ declare namespace lib_plankton.call { /** * @author fenris @@ -363,15 +328,15 @@ declare namespace lib_plankton.call { /** * @author fenris */ - function promise_make(executor: (resolve: (result?: type_result) => void, reject: (reason?: type_reason) => void) => void): type_promise; + function promise_make(executor: (resolve: ((result?: type_result) => void), reject: ((reason?: type_reason) => void)) => void): type_promise; /** * @author fenris */ - function promise_then_close(promise: type_promise, resolver: (result: type_result) => void, rejector: (reason: type_reason) => void): void; + function promise_then_close(promise: type_promise, resolver: ((result: type_result) => void), rejector: ((reason: type_reason) => void)): void; /** * @author fenris */ - function promise_then_append(promise: type_promise, resolver: (result: type_result) => type_promise, rejector?: (reason: type_reason) => type_promise): type_promise; + function promise_then_append(promise: type_promise, resolver: ((result: type_result) => type_promise), rejector?: ((reason: type_reason) => type_promise)): type_promise; /** * @author fenris */ @@ -379,7 +344,7 @@ declare namespace lib_plankton.call { /** * @author fenris */ - function promise_chain(promises: Array<(input: type_result) => type_promise>, start?: type_result): type_promise; + function promise_chain(promises: (Array<(input: type_result) => type_promise>), start?: type_result): type_promise; /** * @author fenris */ @@ -387,15 +352,13 @@ declare namespace lib_plankton.call { /** * @author fenris */ - function promise_group(promises: { - [name: string]: () => type_promise; - }, serial?: boolean): type_promise<{ - [name: string]: any; - }, type_reason>; + function promise_group(promises: Record type_promise)>, options?: { + serial?: boolean; + }): type_promise, type_reason>; /** * @author fenris */ - function promise_wrap(promise: type_promise, transformator_result: (reason: type_result_inner) => type_result_outer, transformator_reason?: (reason: type_reason) => type_reason): type_promise; + function promise_wrap(promise: type_promise, transformator_result: ((reason: type_result_inner) => type_result_outer), transformator_reason?: ((reason: type_reason) => type_reason)): type_promise; /** * @author fenris */ @@ -405,19 +368,11 @@ declare namespace lib_plankton.call { /** * @author fenris */ - function promise_attach(state: { - [name: string]: any; - }, promise: type_promise, name: string): type_promise<{ - [name: string]: any; - }, type_reason>; + function promise_attach(state: Record, promise: type_promise, name: string): type_promise, type_reason>; /** * @author fenris */ function promise_delay(promise: type_promise, delay: int): type_promise; - /** - * @author fenris - */ - function promise_to_executor(promise: type_promise): type_executor; } declare namespace lib_plankton.call { /** @@ -449,6 +404,9 @@ declare namespace lib_plankton.call { cancel(): void; } } +/** + * initializer might be obsolete, since promises are reusable after having been resolved or rejected + */ declare namespace lib_plankton.call { /** * @author fenris @@ -637,7 +595,7 @@ declare namespace lib_plankton.call { */ function compose(function_f: ((type_x: any) => type_y), function_g: ((type_y: any) => type_z)): ((value: type_x) => type_z); /** - * transforms a function with sequential input into a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) + * transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) * * @param {function} f * @return {function} the currified version of the in put function @@ -651,7 +609,13 @@ declare namespace lib_plankton.call { /** * @author fenris */ - function timeout(procedure: (() => void), delay: int): int; + function timeout(procedure: (() => void), delay_in_seconds: float): int; + /** + * Promise version of "setTimeout" + * + * @author fenris + */ + function defer(seconds: float, action: (() => type_result)): Promise; /** * a definition for a value being "defined" * @@ -698,12 +662,6 @@ declare namespace lib_plankton.call { function distinguish(coproduct: type_coproduct, handlers: Record type_output)>, options?: { fallback?: (null | ((coproduct?: type_coproduct) => type_output)); }): type_output; - /** - * Promise version of "setTimeout" - * - * @author fenris - */ - function defer(seconds: float, action: (() => type_result)): Promise; /** * for rate_limit_check * @@ -733,6 +691,207 @@ declare namespace lib_plankton.call { seconds: (null | float); }>; } +declare namespace lib_plankton.list { + /** + * @desc returns a certain list of integer numbers + * @param {int} from + * @param {int} to + * @param {int} step; default: 1 + * @author fenris + */ + function range(from: int, to: int, step?: int): Array; + /** + * @desc returns a certain list of integer numbers + * @param {int} length + * @author fenris + */ + function sequence(length: int): Array; + /** + * @author fenris + */ + function from_structure(structure: { + length: int; + }): Array; + /** + * @author fenris + */ + function from_iterator(iterator: any): Array; + /** + * @author fenris + */ + function empty(list: Array): boolean; + /** + * @desc creates a list, which contains pairs of elements from the input lists (corresponding by index) + * @param {boolean} [cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true + * @author fenris + */ + function zip(list1: Array, list2: Array, cut?: boolean): Array<{ + first: type_element1; + second: type_element2; + }>; + /** + * @desc checks whether two lists are equal + * @todo define common function "equals" and default predicate to + * @author fenris + */ + function equals(list1: Array, list2: Array, collate?: (element1: type_element, element2: type_element) => boolean): boolean; + /** + * @author fenris + */ + function reversed(list: Array): Array; + /** + * @author fenris + */ + function sorted(list: Array, order: (element1: type_element, element2: type_element) => int): Array; + /** + * @desc creates a list with the elements from the input list, which fulfil a certain predicate + * @author fenris + */ + function keep(list: Array, predicate: (element: type_element, index?: int) => boolean): Array; + /** + * @desc creates a list with the elements from the input list, which do not fulfil a certain predicate + * @author fenris + */ + function drop(list: Array, predicate: (element: type_element, index?: int) => boolean): Array; + /** + * @desc returns a list with no duplicates + * @author fenris + */ + function clean(list: Array, collate?: (x: type_element, y: type_element) => boolean): Array; + /** + * @author fenris + */ + function clone(list: Array): Array; + /** + * @desc creates a binary partition of the list according to a given predicate + * @author fenris + */ + type type_separation = { + yes: Array; + no: Array; + }; + function separate(list: Array, predicate: (element: type_element) => boolean): type_separation; + /** + * die Liste in gleich große Blöcke zerlegen + * + * @author fenris + */ + function split(list: Array, chunk_size: int): Array>; + /** + * @author fenris + */ + function group(list: Array, collate?: (x: type_element, y: type_element) => boolean): Array>; + /** + * @author fenris + */ + function groups_(list: Array, collate?: (x: type_element, y: type_element) => boolean): Array>; + /** + * @author fenris + * @deprecated + */ + function groups(list: Array, sorting: (x: type_element, y: type_element) => int, hashing: (element: type_element) => type_value): Array>; + /** + * @desc searches for the first element in a list, that fulfils a given condition + * @author fenris + */ + function find(list: Array, predicate: (element: type_element) => boolean, null_if_not_found?: boolean): type_element; + /** + * @author fenris + */ + function has(list: Array, predicate: (element: type_element) => boolean): boolean; + /** + * @author fenris + */ + function contains(list: Array, element: type_element, collation?: (element1: type_element, element2: type_element) => boolean): boolean; + /** + * @desc retrieves the element and its index of the list, which has the maximum value + * @author fenris + */ + type type_result_max = { + index: int; + element: type_element; + value: type_value; + }; + function max(list: Array, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_result_max; + /** + * @desc retrieves the element and its index of the list, which has the mininum value + * @author fenris + */ + function min(list: Array, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_result_max; + /** + * @desc retrieves the element of the list, which has the maximum output for a given target-function + * @author fenris + */ + function maxarg(list: Array, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_element; + /** + * @desc retrieves the element of the list, which has the minimum output for a given target-function + * @author fenris + */ + function minarg(list: Array, targetfunction: (element: type_element) => type_value, compare?: (value1: type_value, value2: type_value) => boolean): type_element; + /** + * @desc implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)" + * example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]] + * @author fenris + */ + function distribute(lists: Array>): Array>; + /** + * @desc lexicographic order + * @author fenris + * @deprecated + */ + function lex(list1: Array, list2: Array, order?: (element1: type_element, element2: type_element) => int): int; + function lex_lt(list1: Array, list2: Array): boolean; + function lex_gt(list1: Array, list2: Array): boolean; + function lex_le(list1: Array, list2: Array): boolean; + function lex_ge(list1: Array, list2: Array): boolean; + function lex_eq(list1: Array, list2: Array): boolean; + function lex_ne(list1: Array, list2: Array): boolean; + /** + * @author fenris + */ + function filter_inplace(list: Array, predicate: (element: type_element, index?: int) => boolean): void; +} +/** + * @deprecated + */ +declare namespace lib_list { + type type_separation = lib_plankton.list.type_separation; + type type_result_max = lib_plankton.list.type_result_max; + const range: typeof lib_plankton.list.range; + const sequence: typeof lib_plankton.list.sequence; + const from_structure: typeof lib_plankton.list.from_structure; + const from_iterator: typeof lib_plankton.list.from_iterator; + const empty: typeof lib_plankton.list.empty; + const zip: typeof lib_plankton.list.zip; + const equals: typeof lib_plankton.list.equals; + const reversed: typeof lib_plankton.list.reversed; + const sorted: typeof lib_plankton.list.sorted; + const keep: typeof lib_plankton.list.keep; + const drop: typeof lib_plankton.list.drop; + const clean: typeof lib_plankton.list.clean; + const clone: typeof lib_plankton.list.clone; + const separate: typeof lib_plankton.list.separate; + const split: typeof lib_plankton.list.split; + const group: typeof lib_plankton.list.group; + const groups_: typeof lib_plankton.list.groups_; + const groups: typeof lib_plankton.list.groups; + const find: typeof lib_plankton.list.find; + const has: typeof lib_plankton.list.has; + const contains: typeof lib_plankton.list.contains; + const max: typeof lib_plankton.list.max; + const min: typeof lib_plankton.list.min; + const maxarg: typeof lib_plankton.list.maxarg; + const minarg: typeof lib_plankton.list.minarg; + const distribute: typeof lib_plankton.list.distribute; + const lex: typeof lib_plankton.list.lex; + const lex_lt: typeof lib_plankton.list.lex_lt; + const lex_gt: typeof lib_plankton.list.lex_gt; + const lex_le: typeof lib_plankton.list.lex_le; + const lex_ge: typeof lib_plankton.list.lex_ge; + const lex_eq: typeof lib_plankton.list.lex_eq; + const lex_ne: typeof lib_plankton.list.lex_ne; + const filter_inplace: typeof lib_plankton.list.filter_inplace; +} declare namespace lib_plankton.code { /** * @author fenris @@ -948,6 +1107,10 @@ declare namespace lib_plankton.json { } } declare namespace lib_plankton.file { + /** + * @author fenris + */ + function exists(path: string): Promise; /** * @author fenris */ diff --git a/lib/plankton/plankton.js b/lib/plankton/plankton.js index 05d0204..3ecab20 100644 --- a/lib/plankton/plankton.js +++ b/lib/plankton/plankton.js @@ -595,197 +595,8 @@ 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"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var lib_plankton; -(function (lib_plankton) { - var call; - (function (call) { - /** - * @author fenris - */ - function executor_resolve(result) { - return ((resolve, reject) => resolve(result)); - } - call.executor_resolve = executor_resolve; - /** - * @author fenris - */ - function executor_reject(reason) { - return ((resolve, reject) => reject(reason)); - } - 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))); - }); - } - 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)); - } - 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); - }); - }); - } - 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) - ) - ); - */ - } - 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)); - }); - } - 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); - }))); - } - 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); - }))); - } - 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); - }))); - } - 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); - }))); - } - call.executor_reduce = executor_reduce; - })(call = lib_plankton.call || (lib_plankton.call = {})); -})(lib_plankton || (lib_plankton = {})); -/* -This file is part of »bacterio-plankton:call«. - -Copyright 2016-2023 '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 . +/** + * might be completely obsolete */ var lib_plankton; (function (lib_plankton) { @@ -853,23 +664,20 @@ var lib_plankton; /** * @author fenris */ - function promise_group(promises, serial = false) { + function promise_group(promises, options = { + "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) { + if (options.serial) { return (promise_then_append(promise_condense(Object.keys(promises) - .map(name => decorate(promises[name], name))), list => promise_resolve(convert(list)))); + .map(name => decorate(promises[name], name))), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value])))))); } else { return (promise_then_append(promise_all(Object.keys(promises) .map(name => decorate(promises[name], name)) - .map(promise => promise())), list => promise_resolve(convert(list)))); + .map(promise => promise())), list => promise_resolve(Object.fromEntries(list.map(({ "key": key, "value": value }) => ([key, value])))))); } } call.promise_group = promise_group; @@ -928,13 +736,6 @@ var lib_plankton; }); } call.promise_delay = promise_delay; - /** - * @author fenris - */ - function promise_to_executor(promise) { - return ((resolve, reject) => promise.then(resolve, reject)); - } - call.promise_to_executor = promise_to_executor; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* @@ -1039,6 +840,9 @@ 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 . */ +/** + * initializer might be obsolete, since promises are reusable after having been resolved or rejected + */ var lib_plankton; (function (lib_plankton) { var call; @@ -1541,7 +1345,7 @@ var lib_plankton; } } /** - * transforms a function with sequential input into a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) + * transforms a function with sequential input to a function with leveled input; example: add(2,3) = curryfy(add)(2)(3) * * @param {function} f * @return {function} the currified version of the in put function @@ -1565,11 +1369,22 @@ var lib_plankton; /** * @author fenris */ - function timeout(procedure, delay) { + function timeout(procedure, delay_in_seconds) { return ( - /*window.*/ setTimeout(procedure, delay)); + /*window.*/ setTimeout(procedure, Math.floor(delay_in_seconds * 1000))); } call.timeout = timeout; + /** + * Promise version of "setTimeout" + * + * @author fenris + */ + function defer(seconds, action) { + return (new Promise((resolve, reject) => { + setTimeout(() => resolve(action()), Math.floor(seconds * 1000)); + })); + } + call.defer = defer; /** * a definition for a value being "defined" * @@ -1656,17 +1471,6 @@ var lib_plankton; } } call.distinguish = distinguish; - /** - * Promise version of "setTimeout" - * - * @author fenris - */ - function defer(seconds, action) { - return (new Promise((resolve, reject) => { - setTimeout(() => resolve(action()), Math.floor(seconds * 1000)); - })); - } - call.defer = defer; /** * rate limiting algorithm, based on the idea of mana (magic power) in video games: * - an actor has a fixed mana capacity, i.e. the maximum amount of available power @@ -1676,58 +1480,544 @@ var lib_plankton; * * @author fenris */ - function rate_limit_check(setup, heft) { - return __awaiter(this, void 0, void 0, function* () { - if (heft > setup.capacity) { + async function rate_limit_check(setup, heft) { + if (heft > setup.capacity) { + return Promise.resolve({ + "granted": false, + "seconds": null, + }); + } + else { + // get current value + const current_timestamp = (Date.now() / 1000); + const old_snapshot_raw = (await setup.get_snapshot()); + const old_snapshot = (old_snapshot_raw + ?? + { "timestamp": current_timestamp, "value": setup.capacity }); + const seconds_passed = (current_timestamp - old_snapshot.timestamp); + const current_value = Math.min(setup.capacity, (old_snapshot.value + + + (setup.regeneration_rate + * + seconds_passed))); + // analyze + if (current_value < heft) { + // too less + const seconds_needed = ((setup.regeneration_rate <= 0) + ? null + : ((heft - old_snapshot.value) / setup.regeneration_rate)); return Promise.resolve({ "granted": false, - "seconds": null, + "seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)), }); } else { - // get current value - const current_timestamp = (Date.now() / 1000); - const old_snapshot_raw = (yield setup.get_snapshot()); - const old_snapshot = (old_snapshot_raw !== null && old_snapshot_raw !== void 0 ? old_snapshot_raw : { "timestamp": current_timestamp, "value": setup.capacity }); - const seconds_passed = (current_timestamp - old_snapshot.timestamp); - const current_value = Math.min(setup.capacity, (old_snapshot.value - + - (setup.regeneration_rate - * - seconds_passed))); - // analyze - if (current_value < heft) { - // too less - const seconds_needed = ((setup.regeneration_rate <= 0) - ? null - : ((heft - old_snapshot.value) / setup.regeneration_rate)); - return Promise.resolve({ - "granted": false, - "seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)), - }); + // enough -> update snapshot + const new_value = (current_value - heft); + // set_snapshot + if (old_snapshot_raw === null) { + await setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value }); } else { - // enough -> update snapshot - const new_value = (current_value - heft); - // set_snapshot - if (old_snapshot_raw === null) { - yield setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value }); - } - else { - yield setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value)); - } - return Promise.resolve({ - "granted": true, - "seconds": 0, - }); + await setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value)); } + return Promise.resolve({ + "granted": true, + "seconds": 0, + }); } - }); + } } call.rate_limit_check = rate_limit_check; })(call = lib_plankton.call || (lib_plankton.call = {})); })(lib_plankton || (lib_plankton = {})); /* +This file is part of »bacterio-plankton:list«. + +Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' + + +»bacterio-plankton:list« 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:list« 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:list«. If not, see . + */ +var lib_plankton; +(function (lib_plankton) { + var list; + (function (list_1) { + /** + * @desc returns a certain list of integer numbers + * @param {int} from + * @param {int} to + * @param {int} step; default: 1 + * @author fenris + */ + function range(from, to, step) { + if (step === void 0) { step = 1; } + var list = []; + for (var value = from; value <= to; value += step) { + list.push(value); + } + return list; + } + list_1.range = range; + /** + * @desc returns a certain list of integer numbers + * @param {int} length + * @author fenris + */ + function sequence(length) { + return range(0, length - 1); + } + list_1.sequence = sequence; + /** + * @author fenris + */ + function from_structure(structure) { + var list = []; + for (var index = 0; index < structure.length; index += 1) { + list.push(structure[index]); + } + return list; + } + list_1.from_structure = from_structure; + /** + * @author fenris + */ + function from_iterator(iterator /* : Iterator*/) { + var list = []; + for (var _i = 0, iterator_1 = iterator; _i < iterator_1.length; _i++) { + var element = iterator_1[_i]; + list.push(element); + } + return list; + } + list_1.from_iterator = from_iterator; + /** + * @author fenris + */ + function empty(list) { + return (list.length <= 0); + } + list_1.empty = empty; + /** + * @desc creates a list, which contains pairs of elements from the input lists (corresponding by index) + * @param {boolean} [cut] whether the result list will be as long as the shortest input list or an exception is thrown if they have different lengths; default: true + * @author fenris + */ + function zip(list1, list2, cut) { + if (cut === void 0) { cut = true; } + var empty1 = empty(list1); + var empty2 = empty(list2); + if (empty1 || empty2) { + if (cut || (empty1 && empty2)) { + return []; + } + else { + var message = "lists have different lengths"; + throw (new Error(message)); + } + } + else { + return ([{ "first": list1[0], "second": list2[0] }] + .concat(zip(list1.slice(1), list2.slice(1), cut))); + } + } + list_1.zip = zip; + /** + * @desc checks whether two lists are equal + * @todo define common function "equals" and default predicate to + * @author fenris + */ + function equals(list1, list2, collate) { + if (collate === void 0) { collate = instance_collate; } + if (list1.length == list2.length) { + return zip(list1, list2, true).every(function (pair) { return collate(pair.first, pair.second); }); + } + else { + return false; + } + } + list_1.equals = equals; + /** + * @author fenris + */ + function reversed(list) { + var list_ = clone(list); + list_.reverse(); + return list_; + } + list_1.reversed = reversed; + /** + * @author fenris + */ + function sorted(list, order) { + var list_ = clone(list); + list_.sort(order); + return list_; + } + list_1.sorted = sorted; + /** + * @desc creates a list with the elements from the input list, which fulfil a certain predicate + * @author fenris + */ + function keep(list, predicate) { + return list.filter(predicate); + } + list_1.keep = keep; + /** + * @desc creates a list with the elements from the input list, which do not fulfil a certain predicate + * @author fenris + */ + function drop(list, predicate) { + return list.filter(function (element, index) { return (!predicate(element, index)); }); + } + list_1.drop = drop; + /** + * @desc returns a list with no duplicates + * @author fenris + */ + function clean(list, collate) { + if (collate === void 0) { collate = instance_collate; } + var list_ = []; + list.forEach(function (element) { + if (!list_.some(function (element_) { return collate(element, element_); })) { + list_.push(element); + } + }); + return list_; + } + list_1.clean = clean; + /** + * @author fenris + */ + function clone(list) { + return keep(list, function (x) { return true; }); + } + list_1.clone = clone; + function separate(list, predicate) { + return (list.reduce(function (seperation, element) { + return (predicate(element) + ? { "yes": seperation.yes.concat([element]), "no": seperation["no"] } + : { "yes": seperation.yes, "no": seperation["no"].concat([element]) }); + }, { "yes": [], "no": [] })); + } + list_1.separate = separate; + ; + /** + * die Liste in gleich große Blöcke zerlegen + * + * @author fenris + */ + function split(list, chunk_size) { + var chunks = []; + var index = 0; + while (index < list.length) { + var chunk = list.slice(index, Math.min(list.length, index + chunk_size)); + index += chunk_size; + chunks.push(chunk); + } + return chunks; + } + list_1.split = split; + /** + * @author fenris + */ + function group(list, collate) { + if (collate === void 0) { collate = instance_collate; } + var result = []; + list.forEach(function (element) { + var target = find(result, function (group) { return collate(group[0], element); }); + if (target == null) { + target = []; + result.push(target); + } + target.push(element); + }); + return result; + } + list_1.group = group; + /** + * @author fenris + */ + function groups_(list, collate) { + if (collate === void 0) { collate = instance_collate; } + var message = "this function is deprecated; please use 'lib_plankton.list.group' instead (beware: it takes other arguments)"; + console.warn(message); + return group(list, collate); + } + list_1.groups_ = groups_; + /** + * @author fenris + * @deprecated + */ + function groups(list, sorting, hashing) { + var message = "this function is deprecated; please use 'lib_plankton.list.group' instead (beware: it takes other arguments)"; + console.warn(message); + list.sort(sorting); + return (groups_(list, function (x, y) { return (hashing(x) == hashing(y)); })); + } + list_1.groups = groups; + /** + * @desc searches for the first element in a list, that fulfils a given condition + * @author fenris + */ + function find(list, predicate, null_if_not_found) { + if (null_if_not_found === void 0) { null_if_not_found = true; } + var result = null; + var found = list.some(function (element, index) { + if (predicate(element)) { + result = element; + return true; + } + else { + return false; + } + }); + if (found) { + return result; + } + else { + if (null_if_not_found) { + return undefined; + } + else { + throw (new Error("no element in the list fulfils the given predicate")); + } + } + } + list_1.find = find; + /** + * @author fenris + */ + function has(list, predicate) { + try { + find(list, predicate, false); + return true; + } + catch (exception) { + return false; + } + } + list_1.has = has; + /** + * @author fenris + */ + function contains(list, element, collation) { + if (collation === void 0) { collation = instance_collate; } + return has(list, function (element_) { return collation(element_, element); }); + } + list_1.contains = contains; + function max(list, targetfunction, compare) { + if (compare === void 0) { compare = instance_compare; } + if (empty(list)) { + var message = "the max-arg of an empty list is not defined"; + throw (new Error(message)); + } + else { + return (list.reduce(function (result, element, index) { + var value = targetfunction(element); + if ((result == null) || (!compare(value, result.value))) { + return { "index": index, "element": element, "value": value }; + } + else { + return result; + } + }, null)); + } + } + list_1.max = max; + /** + * @desc retrieves the element and its index of the list, which has the mininum value + * @author fenris + */ + function min(list, targetfunction, compare) { + if (compare === void 0) { compare = instance_compare; } + return max(list, targetfunction, function (x, y) { return compare(y, x); }); + } + list_1.min = min; + /** + * @desc retrieves the element of the list, which has the maximum output for a given target-function + * @author fenris + */ + function maxarg(list, targetfunction, compare) { + if (compare === void 0) { compare = instance_compare; } + var message = "this function is deprecated; please use 'lib_plankton.list.max' instead (beware: it has a different output)"; + console.warn(message); + return max(list, targetfunction, compare).element; + } + list_1.maxarg = maxarg; + /** + * @desc retrieves the element of the list, which has the minimum output for a given target-function + * @author fenris + */ + function minarg(list, targetfunction, compare) { + if (compare === void 0) { compare = instance_compare; } + var message = "this function is deprecated; please use 'lib_plankton.list.min' instead (beware: it has a different output)"; + console.warn(message); + return min(list, targetfunction, compare).element; + } + list_1.minarg = minarg; + /** + * @desc implements the idea of arithmetic distribution like in "(a+b)·(c+d) = (a·c)+(a·d)+(b·c)+(b·d)" + * example: distribute([[1,2],[3],[4,5,6]]) = [[1,3,4],[1,3,5],[1,3,6],[2,3,4],[2,3,5],[2,3,6]] + * @author fenris + */ + function distribute(lists) { + if (empty(lists)) { + return [[]]; + } + else { + var subresult_1 = distribute(lists.slice(1)); + return (lists[0] + .map(function (element) { return subresult_1.map(function (list) { return [element].concat(list); }); }) + .reduce(function (x, y) { return x.concat(y); }, [])); + } + } + list_1.distribute = distribute; + /** + * @desc lexicographic order + * @author fenris + * @deprecated + */ + function lex(list1, list2, order) { + if (order === void 0) { order = null; } + console.warn("deprecated!"); + if (order == null) { + order = function (x, y) { + if (x < y) { + return -1; + } + else if (x > y) { + return +1; + } + else /*(x == y)*/ { + return 0; + } + }; + } + if (list1.length <= 0) { + if (list2.length <= 0) { + return 0; + } + else { + return -1; + } + } + else { + if (list2.length <= 0) { + return +1; + } + else { + var result = order(list1[0], list2[0]); + if (result == 0) { + return lex(list1.slice(1), list2.slice(1), order); + } + else { + return result; + } + } + } + } + list_1.lex = lex; + function lex_lt(list1, list2) { + return (lex(list1, list2) < 0); + } + list_1.lex_lt = lex_lt; + ; + function lex_gt(list1, list2) { + return (lex(list1, list2) > 0); + } + list_1.lex_gt = lex_gt; + ; + function lex_le(list1, list2) { + return (lex(list1, list2) <= 0); + } + list_1.lex_le = lex_le; + ; + function lex_ge(list1, list2) { + return (lex(list1, list2) >= 0); + } + list_1.lex_ge = lex_ge; + ; + function lex_eq(list1, list2) { + return (lex(list1, list2) == 0); + } + list_1.lex_eq = lex_eq; + ; + function lex_ne(list1, list2) { + return (lex(list1, list2) != 0); + } + list_1.lex_ne = lex_ne; + ; + /** + * @author fenris + */ + function filter_inplace(list, predicate) { + var index = 0; + while (index < list.length) { + var element = list[index]; + if (predicate(element, index)) { + index += 1; + } + else { + list.splice(index, 1); + } + } + } + list_1.filter_inplace = filter_inplace; + })(list = lib_plankton.list || (lib_plankton.list = {})); +})(lib_plankton || (lib_plankton = {})); +/** + * @deprecated + */ +var lib_list; +(function (lib_list) { + lib_list.range = lib_plankton.list.range; + lib_list.sequence = lib_plankton.list.sequence; + lib_list.from_structure = lib_plankton.list.from_structure; + lib_list.from_iterator = lib_plankton.list.from_iterator; + lib_list.empty = lib_plankton.list.empty; + lib_list.zip = lib_plankton.list.zip; + lib_list.equals = lib_plankton.list.equals; + lib_list.reversed = lib_plankton.list.reversed; + lib_list.sorted = lib_plankton.list.sorted; + lib_list.keep = lib_plankton.list.keep; + lib_list.drop = lib_plankton.list.drop; + lib_list.clean = lib_plankton.list.clean; + lib_list.clone = lib_plankton.list.clone; + lib_list.separate = lib_plankton.list.separate; + lib_list.split = lib_plankton.list.split; + lib_list.group = lib_plankton.list.group; + lib_list.groups_ = lib_plankton.list.groups_; + lib_list.groups = lib_plankton.list.groups; + lib_list.find = lib_plankton.list.find; + lib_list.has = lib_plankton.list.has; + lib_list.contains = lib_plankton.list.contains; + lib_list.max = lib_plankton.list.max; + lib_list.min = lib_plankton.list.min; + lib_list.maxarg = lib_plankton.list.maxarg; + lib_list.minarg = lib_plankton.list.minarg; + lib_list.distribute = lib_plankton.list.distribute; + lib_list.lex = lib_plankton.list.lex; + lib_list.lex_lt = lib_plankton.list.lex_lt; + lib_list.lex_gt = lib_plankton.list.lex_gt; + lib_list.lex_le = lib_plankton.list.lex_le; + lib_list.lex_ge = lib_plankton.list.lex_ge; + lib_list.lex_eq = lib_plankton.list.lex_eq; + lib_list.lex_ne = lib_plankton.list.lex_ne; + lib_list.filter_inplace = lib_plankton.list.filter_inplace; +})(lib_list || (lib_list = {})); +/* This file is part of »bacterio-plankton:code«. Copyright 2016-2023 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' @@ -2096,7 +2386,7 @@ var lib_plankton; } return { "keys": keys, - "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }), + "data": from.map(function (line) { return keys.map(function (name) { return line[name]; }); }) }; } code.flatten_encode = flatten_encode; @@ -2281,6 +2571,23 @@ var lib_plankton; (function (lib_plankton) { var file; (function (file) { + /** + * @author fenris + */ + function exists(path) { + var nm_fs = require("fs"); + return (new Promise(function (resolve, reject) { + nm_fs.stat(path, function (error, stats) { + if (error) { + resolve(false); + } + else { + resolve(true); + } + }); + })); + } + file.exists = exists; /** * @author fenris */ @@ -2289,7 +2596,7 @@ var lib_plankton; return (new Promise(function (resolve, reject) { nm_fs.readFile(path, { "encoding": "utf8", - "flag": "r", + "flag": "r" }, function (error, content) { if (error == null) { resolve(content); @@ -2308,7 +2615,7 @@ var lib_plankton; var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.readFile(path, { - "flag": "r", + "flag": "r" }, function (error, content) { if (error == null) { resolve(content); @@ -2345,13 +2652,13 @@ var lib_plankton; function write(path, content, options) { if (options === void 0) { options = {}; } options = Object.assign({ - "encoding": "utf-8", + "encoding": "utf-8" }, options); var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.writeFile(path, content, { "encoding": options.encoding, - "flag": "w", + "flag": "w" }, function (error) { if (error == null) { resolve(undefined); @@ -2372,7 +2679,7 @@ var lib_plankton; var nm_fs = require("fs"); return (new Promise(function (resolve, reject) { nm_fs.writeFile(path, content, { - "flag": "w", + "flag": "w" }, function (error) { if (error == null) { resolve(undefined); @@ -2537,14 +2844,14 @@ var lib_plankton; "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, + "error": lib_plankton.log.enum_level.error }[type]), "incident": message, "details": { "prefix": prefix, "level": level, - "indent": indent, - }, + "indent": indent + } }; lib_plankton.log.add(entry); } @@ -2680,7 +2987,7 @@ var lib_plankton; var _this = this; var nm_fs = require("fs"); nm_fs.writeFile(this.path, { - "flag": "a+", + "flag": "a+" }, (("<" + (new Date(Date.now())).toISOString().slice(0, 19) + ">") + " " @@ -2853,7 +3160,7 @@ var lib_plankton; "info": log.enum_level.info, "notice": log.enum_level.notice, "warning": log.enum_level.warning, - "error": log.enum_level.error, + "error": log.enum_level.error }[level_string]; } /** @@ -3119,8 +3426,8 @@ var lib_plankton; "info": info, "hidden": hidden, "parameters": { - "index": index, - }, + "index": index + } })); }; /** @@ -3138,8 +3445,8 @@ var lib_plankton; "hidden": hidden, "parameters": { "indicators_short": indicators_short, - "indicators_long": indicators_long, - }, + "indicators_long": indicators_long + } })); }; /** @@ -3385,17 +3692,17 @@ var lib_plankton; "symbols": { "delimiter": " ", "prefix": "--", - "assignment": "=", - }, + "assignment": "=" + } }, "url": { "symbols": { "delimiter": "&", "prefix": "", - "assignment": "=", + "assignment": "=" } } - }, + } }; /** * @author fenris @@ -3472,14 +3779,14 @@ var lib_plankton; "pattern_from": pattern_from, "pattern_to": pattern_to, "input": input, - "result": result, + "result": result }); input = result; } } } lib_plankton.log.debug("lib_args:read:current_input", { - "input": input, + "input": input }); } // parsing @@ -3490,18 +3797,18 @@ var lib_plankton; var index_expected_1 = 0; parts.forEach(function (part) { lib_plankton.log.debug("lib_args:read:analyzing", { - "part": part, + "part": part }); var found = [ function () { lib_plankton.log.debug("lib_args:read:probing_as_volatile", { - "part": part, + "part": part }); for (var _i = 0, _a = Object.entries(_this.filter(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(), + "argument": argument.toString() }); var pattern = ""; { @@ -3520,12 +3827,12 @@ var lib_plankton; pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_volatile:pattern", { - "pattern": 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, + "matching": matching }); if (matching == null) { // do nothing @@ -3539,7 +3846,7 @@ var lib_plankton; }, function () { lib_plankton.log.debug("lib_args:read:probing_as_positional", { - "part": part, + "part": part }); var positional = _this.filter(args.enum_kind.positional); for (var _i = 0, _a = Object.entries(positional); _i < _a.length; _i++) { @@ -3550,7 +3857,7 @@ var lib_plankton; else { lib_plankton.log.debug("lib_args:read:probing_as_positional:trying", { "part": part, - "argument": argument.toString(), + "argument": argument.toString() }); var pattern = ""; { @@ -3559,12 +3866,12 @@ var lib_plankton; pattern += pattern_back; } lib_plankton.log.debug("lib_args:read:probing_as_positional:pattern", { - "pattern": 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, + "matching": matching }); if (matching == null) { return false; @@ -3581,7 +3888,7 @@ var lib_plankton; ].some(function (x) { return x(); }); if (!found) { lib_plankton.log.warning("lib_args:read:could_not_parse", { - "part": part, + "part": part }); } }); diff --git a/tools/update-plankton b/tools/update-plankton index 169a714..4f266c6 100755 --- a/tools/update-plankton +++ b/tools/update-plankton @@ -10,6 +10,7 @@ dir="lib/plankton" modules="" modules="${modules} base" modules="${modules} call" +modules="${modules} list" modules="${modules} json" modules="${modules} file" modules="${modules} args"