diff --git a/package-lock.json b/package-lock.json --- a/package-lock.json +++ b/package-lock.json @@ -133,7 +133,7 @@ }, "minimist": { "version": "0.0.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz", "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=", "dev": true }, @@ -319,9 +319,9 @@ } }, "requirejs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz", - "integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", "dev": true }, "resolve": { @@ -413,9 +413,9 @@ } }, "typescript": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.3.tgz", + "integrity": "sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==", "dev": true }, "wrappy": { diff --git a/src/js/log/listeners/console.js b/src/js/log/listeners/console.js deleted file mode 100644 --- a/src/js/log/listeners/console.js +++ /dev/null @@ -1,25 +0,0 @@ -define([], function () { - if (console && console.log) - return function (ch, name, msg) { - - var args = [ch + ":"]; - - switch (name) { - case "warn": - case "error": - case "log": - break; - default: - args.push(name + ":"); - name = "log"; - } - - - if (msg instanceof Array) - args.push.apply(args, msg); - else - args.push(msg); - - console[name].apply(console, args); - }; -}); \ No newline at end of file diff --git a/src/js/safe.js b/src/js/safe.js deleted file mode 100644 --- a/src/js/safe.js +++ /dev/null @@ -1,325 +0,0 @@ -define([], - - function () { - var _create = Object.create, - _keys = Object.keys; - - var safe = null; - safe = { - argumentNotNull: function (arg, name) { - if (arg === null || arg === undefined) - throw new Error("The argument " + name + " can't be null or undefined"); - }, - - argumentNotEmptyString: function (arg, name) { - if (typeof (arg) !== "string" || !arg.length) - throw new Error("The argument '" + name + "' must be a not empty string"); - }, - - argumentNotEmptyArray: function (arg, name) { - if (!(arg instanceof Array) || !arg.length) - throw new Error("The argument '" + name + "' must be a not empty array"); - }, - - argumentOfType: function (arg, type, name) { - if (!(arg instanceof type)) - throw new Error("The argument '" + name + "' type doesn't match"); - }, - - isNull: function (arg) { - return (arg === null || arg === undefined); - }, - - isPrimitive: function (arg) { - return (arg === null || arg === undefined || typeof (arg) === "string" || - typeof (arg) === "number" || typeof (arg) === "boolean"); - }, - - isInteger: function (arg) { - return parseInt(arg) == arg; - }, - - isNumber: function (arg) { - return parseFloat(arg) == arg; - }, - - isString: function (val) { - return typeof (val) == "string" || val instanceof String; - }, - - isNullOrEmptyString: function (str) { - if (str === null || str === undefined || - ((typeof (str) == "string" || str instanceof String) && str.length === 0)) - return true; - }, - - isNotEmptyArray: function (arg) { - return (arg instanceof Array && arg.length > 0); - }, - - /** - * Выполняет метод для каждого элемента массива, останавливается, когда - * либо достигнут конец массива, либо функция cb вернула - * значение. - * - * @param{Array | Object} obj массив элементов для просмотра - * @param{Function} cb функция, вызываемая для каждого элемента - * @param{Object} thisArg значение, которое будет передано в качестве - * this в cb. - * @returns Результат вызова функции cb, либо undefined - * если достигнут конец массива. - */ - each: function (obj, cb, thisArg) { - safe.argumentNotNull(cb, "cb"); - var i, x; - if (obj instanceof Array) { - for (i = 0; i < obj.length; i++) { - x = cb.call(thisArg, obj[i], i); - if (x !== undefined) - return x; - } - } else { - var keys = _keys(obj); - for (i = 0; i < keys.length; i++) { - var k = keys[i]; - x = cb.call(thisArg, obj[k], k); - if (x !== undefined) - return x; - } - } - }, - - /** - * Копирует свойства одного объекта в другой. - * - * @param{Any} dest объект в который нужно скопировать значения - * @param{Any} src источник из которого будут копироваться значения - * @tmpl{Object|Array} tmpl шаблон по которому будет происходить - * копирование. Если шаблон является массивом - * (список свойств), тогда значения этого массива - * являются именами свойсвт которые будут - * скопированы. Если шаблон является объектом (карта - * преобразования имен свойств src->dst), тогда - * копирование будет осуществляться только - * собственных свойств источника, присутсвующих в - * шаблоне, при этом значение свойства шаблона - * является именем свойства в которое будет - * произведено коприрование - */ - mixin: function (dest, src, tmpl) { - safe.argumentNotNull(dest, "dest"); - if (!src) - return dest; - - var keys, i, p; - if (arguments.length < 3) { - keys = _keys(src); - for (i = 0; i < keys.length; i++) { - p = keys[i]; - dest[p] = src[p]; - } - } else { - if (tmpl instanceof Array) { - for (i = 0; i < tmpl.length; i++) { - p = tmpl[i]; - if (p in src) - dest[p] = src[p]; - } - - } else { - keys = _keys(src); - for (i = 0; i < keys.length; i++) { - p = keys[i]; - if (p in tmpl) - dest[tmpl[p]] = src[p]; - } - } - } - return dest; - }, - - /** Wraps the specified function to emulate an asynchronous execution. - * @param{Object} thisArg [Optional] Object which will be passed as 'this' to the function. - * @param{Function|String} fn [Required] Function wich will be wrapped. - */ - async: function (fn, thisArg) { - if (arguments.length == 2 && !(fn instanceof Function)) - fn = thisArg[fn]; - - if (fn == null) - throw new Error("The function must be specified"); - - function wrapresult(x, e) { - if (e) { - return { - then: function (cb, eb) { - try { - return eb ? wrapresult(eb(e)) : this; - } catch (e2) { - return wrapresult(null, e2); - } - } - }; - } else { - if (x && x.then) - return x; - return { - then : function(cb) { - try { - return cb ? wrapresult(cb(x)) : this; - } catch(e2) { - return wrapresult(e2); - } - } - }; - } - } - - return function() { - try { - return wrapresult(fn.apply(thisArg, arguments)); - } catch (e) { - return wrapresult(null, e); - } - }; - }, - - create: function () { - if (console && console.warn) - console.warn("implab/safe::create is deprecated use Object.create instead"); - _create.apply(this, arguments); - }, - - delegate: function (target, method) { - if (!(method instanceof Function)) { - this.argumentNotNull(target, "target"); - method = target[method]; - } - - if (!(method instanceof Function)) - throw new Error("'method' argument must be a Function or a method name"); - - return function () { - return method.apply(target, arguments); - }; - }, - - /** - * Для каждого элемента массива вызывает указанную функцию и сохраняет - * возвращенное значение в массиве результатов. - * - * @remarks cb может выполняться асинхронно, при этом одновременно будет - * только одна операция. - * - * @async - */ - pmap: function (items, cb) { - safe.argumentNotNull(cb, "cb"); - - if (items && items.then instanceof Function) - return items.then(function (data) { - return safe.pmap(data, cb); - }); - - if (safe.isNull(items) || !items.length) - return items; - - var i = 0, - result = []; - - function next() { - var r, ri; - - function chain(x) { - result[ri] = x; - return next(); - } - - while (i < items.length) { - r = cb(items[i], i); - ri = i; - i++; - if (r && r.then) { - return r.then(chain); - } else { - result[ri] = r; - } - } - return result; - } - - return next(); - }, - - /** - * Для каждого элемента массива вызывает указанную функцию, результаты - * не сохраняются - * - * @remarks cb может выполняться асинхронно, при этом одновременно будет - * только одна операция. - * @async - */ - pfor: function (items, cb) { - safe.argumentNotNull(cb, "cb"); - - if (items && items.then instanceof Function) - return items.then(function (data) { - return safe.pmap(data, cb); - }); - - if (safe.isNull(items) || !items.length) - return items; - - var i = 0; - - function next() { - while (i < items.length) { - var r = cb(items[i], i); - i++; - if (r && r.then) - return r.then(next); - } - } - - return next(); - }, - - /** - * Выбирает первый элемент из последовательности, или обещания, если в - * качестве параметра используется обещание, оно должно вернуть массив. - * - * @param{Function} cb обработчик результата, ему будет передан первый - * элемент последовательности в случае успеха - * @param{Fucntion} err обработчик исключения, если массив пустой, либо - * не массив - * - * @remarks Если не указаны ни cb ни err, тогда функция вернет либо - * обещание, либо первый элемент. - * @async - */ - first: function (sequence, cb, err) { - if (sequence) { - if (sequence.then instanceof Function) { - return sequence.then(function (res) { - return safe.first(res, cb, err); - }, err); - } else if (sequence && "length" in sequence) { - if (sequence.length === 0) { - if (err) - return err(new Error("The sequence is empty")); - else - throw new Error("The sequence is empty"); - } - return cb ? cb(sequence[0]) : sequence[0]; - } - } - - if (err) - return err(new Error("The sequence is required")); - else - throw new Error("The sequence is required"); - } - }; - - return safe; - }); \ No newline at end of file diff --git a/src/ts/safe.d.ts b/src/ts/safe.d.ts deleted file mode 100644 --- a/src/ts/safe.d.ts +++ /dev/null @@ -1,1 +0,0 @@ -export declare function argumentNotNull(v: any, paramName: string); \ No newline at end of file diff --git a/src/ts/safe.ts b/src/ts/safe.ts new file mode 100644 --- /dev/null +++ b/src/ts/safe.ts @@ -0,0 +1,231 @@ +export function argumentNotNull(arg, name) { + if (arg === null || arg === undefined) + throw new Error("The argument " + name + " can't be null or undefined"); +} + +export function argumentNotEmptyString(arg, name) { + if (typeof (arg) !== "string" || !arg.length) + throw new Error("The argument '" + name + "' must be a not empty string"); +} + +export function argumentNotEmptyArray(arg, name) { + if (!(arg instanceof Array) || !arg.length) + throw new Error("The argument '" + name + "' must be a not empty array"); +} + +export function argumentOfType(arg, type, name) { + if (!(arg instanceof type)) + throw new Error("The argument '" + name + "' type doesn't match"); +} + +export function isNull(arg) { + return (arg === null || arg === undefined); +} + +export function isPrimitive(arg) { + return (arg === null || arg === undefined || typeof (arg) === "string" || + typeof (arg) === "number" || typeof (arg) === "boolean"); +} + +export function isInteger(arg) { + return parseInt(arg) == arg; +} + +export function isNumber(arg) { + return parseFloat(arg) == arg; +} + +export function isString(val) { + return typeof (val) == "string" || val instanceof String; +} + +export function isNullOrEmptyString(str) { + if (str === null || str === undefined || + ((typeof (str) == "string" || str instanceof String) && str.length === 0)) + return true; +} + +export function isNotEmptyArray(arg) { + return (arg instanceof Array && arg.length > 0); +} + +/** + * Выполняет метод для каждого элемента массива, останавливается, когда + * либо достигнут конец массива, либо функция cb вернула + * значение. + * + * @param {Array | Object} obj массив элементов для просмотра + * @param {Function} cb функция, вызываемая для каждого элемента + * @param {Object} thisArg значение, которое будет передано в качестве + * this в cb. + * @returns Результат вызова функции cb, либо undefined + * если достигнут конец массива. + */ +export function each(obj, cb, thisArg) { + argumentNotNull(cb, "cb"); + var i, x; + if (obj instanceof Array) { + for (i = 0; i < obj.length; i++) { + x = cb.call(thisArg, obj[i], i); + if (x !== undefined) + return x; + } + } else { + var keys = Object.keys(obj); + for (i = 0; i < keys.length; i++) { + var k = keys[i]; + x = cb.call(thisArg, obj[k], k); + if (x !== undefined) + return x; + } + } +} + +/** Wraps the specified function to emulate an asynchronous execution. + * @param{Object} thisArg [Optional] Object which will be passed as 'this' to the function. + * @param{Function|String} fn [Required] Function wich will be wrapped. + */ +export function async(_fn: (...args: any[]) => any, thisArg) : (...args: any[]) => PromiseLike { + let fn = _fn; + + if (arguments.length == 2 && !(fn instanceof Function)) + fn = thisArg[fn]; + + if (fn == null) + throw new Error("The function must be specified"); + + function wrapresult(x, e?) : PromiseLike { + if (e) { + return { + then: function (cb, eb) { + try { + return eb ? wrapresult(eb(e)) : this; + } catch (e2) { + return wrapresult(null, e2); + } + } + }; + } else { + if (x && x.then) + return x; + return { + then: function (cb) { + try { + return cb ? wrapresult(cb(x)) : this; + } catch (e2) { + return wrapresult(e2); + } + } + }; + } + } + + return function () { + try { + return wrapresult(fn.apply(thisArg, arguments)); + } catch (e) { + return wrapresult(null, e); + } + }; +} + +export function delegate(target, _method: (string | Function)) { + let method : Function; + + if (!(_method instanceof Function)) { + argumentNotNull(target, "target"); + method = target[_method]; + } else { + method = _method; + } + + if (!(method instanceof Function)) + throw new Error("'method' argument must be a Function or a method name"); + + return function () { + return method.apply(target, arguments); + }; +} + +/** + * Для каждого элемента массива вызывает указанную функцию и сохраняет + * возвращенное значение в массиве результатов. + * + * @remarks cb может выполняться асинхронно, при этом одновременно будет + * только одна операция. + * + * @async + */ +export function pmap(items, cb) { + argumentNotNull(cb, "cb"); + + if (items && items.then instanceof Function) + return items.then(function (data) { + return pmap(data, cb); + }); + + if (isNull(items) || !items.length) + return items; + + var i = 0, + result = []; + + function next() { + var r, ri; + + function chain(x) { + result[ri] = x; + return next(); + } + + while (i < items.length) { + r = cb(items[i], i); + ri = i; + i++; + if (r && r.then) { + return r.then(chain); + } else { + result[ri] = r; + } + } + return result; + } + + return next(); +} + +/** + * Выбирает первый элемент из последовательности, или обещания, если в + * качестве параметра используется обещание, оно должно вернуть массив. + * + * @param {Function} cb обработчик результата, ему будет передан первый + * элемент последовательности в случае успеха + * @param {Function} err обработчик исключения, если массив пустой, либо + * не массив + * + * @remarks Если не указаны ни cb ни err, тогда функция вернет либо + * обещание, либо первый элемент. + * @async + */ +export function first(sequence: any, cb: Function, err: Function) { + if (sequence) { + if (sequence.then instanceof Function) { + return sequence.then(function (res) { + return first(res, cb, err); + }, err); + } else if (sequence && "length" in sequence) { + if (sequence.length === 0) { + if (err) + return err(new Error("The sequence is empty")); + else + throw new Error("The sequence is empty"); + } + return cb ? cb(sequence[0]) : sequence[0]; + } + } + + if (err) + return err(new Error("The sequence is required")); + else + throw new Error("The sequence is required"); +} \ No newline at end of file diff --git a/test/ts/TestTraits.ts b/test/ts/TestTraits.ts --- a/test/ts/TestTraits.ts +++ b/test/ts/TestTraits.ts @@ -1,9 +1,9 @@ -import { IObservable, ICancellation, IDestroyable } from "@implab/core/interfaces"; -import * as TraceEvent from '@implab/core/log/TraceEvent'; -import { Cancellation } from "@implab/core/Cancellation"; -import * as TraceSource from "@implab/core/log/TraceSource"; +import { IObservable, ICancellation, IDestroyable } from "../../build/dist/interfaces"; +import * as TraceEvent from '../../build/dist/log/TraceEvent'; +import { Cancellation } from "../../build/dist/Cancellation"; +import * as TraceSource from "../../build/dist/log/TraceSource"; import * as tape from 'tape'; -import { argumentNotNull } from "@implab/core/safe"; +import { argumentNotNull } from "../../build/dist/safe"; export class TapeWriter implements IDestroyable { readonly _tape: tape.Test diff --git a/test/ts/TraceSourceTests.ts b/test/ts/TraceSourceTests.ts --- a/test/ts/TraceSourceTests.ts +++ b/test/ts/TraceSourceTests.ts @@ -1,6 +1,6 @@ -import * as TraceSource from '@implab/core/log/TraceSource' +import * as TraceSource from '../../build/dist/log/TraceSource' import * as tape from 'tape'; -import * as ConsoleWriter from '@implab/core/log/writers/ConsoleWriter'; +import * as ConsoleWriter from '../../build/dist/log/writers/ConsoleWriter'; import { TapeWriter } from './TestTraits'; const sourceId = 'test/TraceSourceTests'; @@ -61,7 +61,7 @@ tape('tape comment writer', async t => { trace.error("DIE!"); writer.destroy(); - + trace.log("You shouldn't see it!"); t.comment("DONE");