diff --git a/.project b/.project deleted file mode 100644 --- a/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - core - Project core created by Buildship. - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/build.gradle b/build.gradle --- a/build.gradle +++ b/build.gradle @@ -5,41 +5,128 @@ if (release != 'rtm') { if(!npmName) npmName = name; -if(!["amd", "cjs"].contains(platform)) - throw new Exception("Invalid platform specified: $platform"); +if(!["amd", "commonjs", "system", "umd", "es6", "esnext"].contains(jsmodule)) + throw new Exception("Invalid jsmodule specified: $jsmodule"); +if(!["es3", "es5", "es6", "es2016", "es2017", "esnext"].contains(target)) + throw new Exception("Invalid target specified: $target") -def moduleTypes = [ - "amd": "amd", - "cjs": "commonjs" -] +def targetLibs = [ + "es3" : "es5,es2015.promise,es2015.symbol,dom,scripthost", + "es5" : "es5,es2015.promise,es2015.symbol,dom,scripthost" +]; -ext.packageName="$npmScope/$npmName-$platform"; +ext.packageName="$npmScope/$npmName"; def srcDir = "$projectDir/src" def typingsDir = "$srcDir/typings" -def distDir = "$buildDir/dist/$platform" -def testDir = "$buildDir/test/$platform" -def moduleType = moduleTypes[platform] +def distDir = "$buildDir/dist" +def testDir = "$buildDir/test" +def lib = targetLibs[target] ?: "${target},dom"; + +println "lib: $lib"; + +def sourceSets = ["main", "amd", "cjs"]; +def testSets = ["test", "testAmd", "testCjs"]; + +task beforeBuild { +} + +def createSoursetTasks = { String name, String outDir -> + def setName = name.capitalize(); + + def destDir = "$buildDir/compile/$name" + def declDir = "$typingsDir/$name" + def setDir = "$projectDir/src/$name" + + def beforeBuildTask = task "beforeBuild$setName"(dependsOn: beforeBuild) { + } + + def copyJsTask = task "copyJs$setName"(dependsOn: beforeBuildTask, type: Copy) { + from "$setDir/js" + into outDir + } + + def compileTypingsTask = task "compileTypings$setName"(dependsOn: beforeBuildTask, type: Exec) { + inputs.dir("$setDir/ts") + inputs.file("$srcDir/tsconfig.json") + inputs.file("$setDir/tsconfig.json") + outputs.dir(declDir) -def sourceSets = ["main", "amd", "cjs", "test"]; + commandLine 'node_modules/.bin/tsc', + '-p', "$setDir/tsconfig.json", + '-t', target, + '-m', jsmodule, + '-d', + '--emitDeclarationOnly', + '--declarationDir', declDir + + if (lib) + args '--lib', lib + } + + def compileTsTask = task "compileTs$setName"(dependsOn: beforeBuildTask, type: Exec) { + inputs.dir("$setDir/ts") + inputs.file("$srcDir/tsconfig.json") + inputs.file("$setDir/tsconfig.json") + outputs.dir(destDir) + + commandLine 'node_modules/.bin/tsc', + '-p', "$setDir/tsconfig.json", + '-t', target, + '-m', jsmodule, + '--outDir', destDir + + if (lib) + args '--lib', lib + } + + def copyTsOutputTask = task "copyTsOutput$setName"(dependsOn: compileTsTask, type: Copy) { + from compileTsTask + into outDir + } + + def copyTypingsTask = task "copyTypings$setName"(dependsOn: compileTypingsTask, type: Copy) { + from compileTypingsTask + into outDir + } + + task "build$setName"(dependsOn: [copyTypingsTask, copyTsOutputTask, copyJsTask]) { + } +} task printVersion { doLast { println "version: $version" println "packageName: $packageName" - println "platform: $platform" - println "module: $moduleType" + println "target: $target" + println "module: $jsmodule" } } task clean { doLast { delete buildDir - delete "node_modules/$packageName" delete typingsDir } } +task _initBuild { + mustRunAfter clean + + def buildInfoFile = "$buildDir/platform"; + inputs.property('target',target); + inputs.property('jsmodule',jsmodule); + outputs.file(buildInfoFile); + + doLast { + delete buildDir + mkdir buildDir + + def f = new File(buildInfoFile); + f << "$target-$jsmodule"; + } +} + task cleanNpm { doLast { delete 'node_modules' @@ -56,78 +143,55 @@ task _npmInstall() { } } -sourceSets.each { - def setName = it.capitalize(); - - def destDir = "$buildDir/compile/$it" - def declDir = "$typingsDir/$it" - def setDir = "$projectDir/src/$it" - - task "_copyJs$setName"(type:Copy) { - from "$setDir/js" - into distDir - } +beforeBuild { + dependsOn _initBuild + dependsOn _npmInstall +} - task "_compileTs$setName"(dependsOn: _npmInstall, type:Exec) { - inputs.dir("$setDir/ts") - inputs.file("$srcDir/tsconfig.json") - inputs.file("$setDir/tsconfig.json") - outputs.dir(destDir) - outputs.dir(declDir) +sourceSets.each { createSoursetTasks(it, distDir) } - commandLine 'node_modules/.bin/tsc', - '-p', "$setDir/tsconfig.json", - '-m', moduleType, - '--outDir', destDir, - '--declarationDir', declDir - } +testSets.each { createSoursetTasks(it, testDir) } - task "_buildTs$setName"(dependsOn: "_compileTs$setName", type:Copy) { - from tasks.getByPath("_compileTs$setName"); - into distDir - } +compileTsAmd { + dependsOn compileTypingsMain } -_compileTsAmd { - dependsOn _buildTsMain +compileTypingsAmd { + dependsOn compileTypingsMain +} + +task build(dependsOn: buildMain) { + if (jsmodule == "amd") + dependsOn buildAmd } -_buildTsTest { - into testDir +compileTsTest { + dependsOn build } -_copyJsTest { - into testDir +compileTsTestAmd { + dependsOn compileTypingsTestAmd +} + +task test(dependsOn: [buildTest, buildTestAmd], type: Exec) { + commandLine 'node', "$testDir/run-amd-tests.js" } task _packageMeta(type: Copy) { + mustRunAfter build + inputs.property("version", version) from('.') { include '.npmignore', 'readme.md', 'license', 'history.md' } - from("$srcDir/package.template.json") { + from("$srcDir/package.${jsmodule}.tmpl.json") { expand project.properties rename { "package.json" } } into distDir } -task build(dependsOn: [_copyJsMain, _copyJsAmd, _npmInstall, _buildTsMain, _buildTsAmd, _packageMeta]) { - -} - -_compileTsTest { - dependsOn build -} - -task buildTests(dependsOn: [_copyJsTest, _buildTsTest]) { -} - -task test(dependsOn: buildTests, type: Exec) { - commandLine 'node', "$testDir/run-amd-tests.js" -} - -task pack(dependsOn: build, type: Exec) { +task pack(dependsOn: [build, _packageMeta], type: Exec) { workingDir distDir commandLine 'npm', 'pack' diff --git a/docs/ru/build.md b/docs/ru/build.md new file mode 100644 --- /dev/null +++ b/docs/ru/build.md @@ -0,0 +1,13 @@ +# Сборка проекта + +Проект представляет собой сложную структуру, которая делится на несколько наборов, которые используются при условной сборке. +Каждый набор сожержит в себе множество артефактов, которые класифицируются по способу сборки, например, исходные тексты js и ts и набор файлов, которые будут просто скопированы без изменений. + +Такая структура позволяет сочитать в проекте несколько языков, а также делать сборки с разными параметрами для разных платформ. + +## NPM + +Довольно ограниченная среда, поскольку может быть опубликован только один вариант библиотеки, можно конечно использовать разные версии, чтобы публиковать разные сборки, но это приведет к определенным сложностям, по крайней мере при использовании зависимостей, уже не говоря о том, что это будет путать разработчиков. +Использование суффиксов в имени пакета только частично решает задачу, поскольку не все системы могут использовать указание путей при настройке загрузчиков. RequireJS позволяет указывать месторасположение пакета, commonJs не позволяет это сделать без использования специальных средств. + +npm позволяет устанавливать библиотеку используя ссылку, что дает возможность ее устанавки из произвольных мест. например, можно установить нужный вариант библиотеки по ссылке . \ No newline at end of file diff --git a/docs/ru/messaging.md b/docs/ru/messaging.md new file mode 100644 --- /dev/null +++ b/docs/ru/messaging.md @@ -0,0 +1,56 @@ +# Обмен сообщениями + +## Session + +Контекст обмена сообщениями, отвечает за создание конечных точек для получения и отправки сообщений, а также инкапсулирует в себе работу с провайдером системы обмена сообщениями. + +Сессия позволяет выполнить конфигурацию компонент обработки сообщений, до начала реального обмена и после окончания конфигурации выполнить метод `start` после которого начнется реальная обработка. Такой способ позволяет избежать ошибки и потерю сообщений по причине того, что часть компонент готова к работе и уже получает и отправляет сообщения, а часть еще не настроена. + +```ts + +// some provider related code +const connection = new StompService("ws://broker.329broker.com:15674/ws", { user: "user", pass: "secret" }); +const session = connection.createSession(); + +// create and configure consumers and producers +const consumer = session.createConsumer("topic://notify"); + +// make event driven consumer +consumer.observe().on(msg => { + // do something + + // mark the message as processed + msg.ack(); +}); + +const producer = session.createProducer("queue://requests"); + +// signal the session to start +session.start(); + +// await the session is started +await session.getCompletion(); + +``` + +### start + +Начинает сессию + +### createConsumer + +### createProducer + +## Consumer + +### Push-consumer + +#### messages + +### Pull-consumer + +#### read + +## Producer + +### post \ No newline at end of file diff --git a/docs/ru/observable.md b/docs/ru/observable.md --- a/docs/ru/observable.md +++ b/docs/ru/observable.md @@ -119,18 +119,14 @@ let msg = await pushEvents.next(); class Map { /** - Получает координаты по щелчку мыши. - @async - @returns [lon,lat] - */ async peekCoordinates(ct: ICancellation = Cancellation.none) { // получаем событие клика let evt = this.viewport.click.next(ct); - + // преобразуем позицию на экране в координаты карты return this.clientToCoodinates([evt.clientx,evt.clientY]); } diff --git a/gradle.properties b/gradle.properties --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,8 @@ version=1.2.0 release=rc author=Implab team -platform=amd +jsmodule=amd +target=es5 description=Dependency injection, logging, simple and fast text template engine license=BSD-2-Clause repository=https://bitbucket.org/implab/implabjs diff --git a/history.md b/history.md --- a/history.md +++ b/history.md @@ -1,12 +1,20 @@ HISTORY ======= +1.2.0 +----- + +Major rafactoring, moving to support browser (rjs) and server (cjs) environments. + +- dependency injection container ported to typescript +- sources are split to several sets to provide the ability for the conditional build of the project. + 1.0.1 ----- -First release, intorduces the followinf features +First release, intorduces the following features -- `di` - dependency injection conyainer +- `di` - dependency injection container - `log` - log4 style logging system - `text` - simple and fast text templating and formatting - `Uuid` - uuid generation traits \ No newline at end of file diff --git a/package-lock.json b/package-lock.json --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@types/node": { - "version": "10.12.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz", - "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==", + "version": "10.12.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", + "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", "dev": true }, "@types/requirejs": { @@ -17,9 +17,9 @@ "dev": true }, "@types/tape": { - "version": "4.2.32", - "resolved": "http://registry.npmjs.org/@types/tape/-/tape-4.2.32.tgz", - "integrity": "sha512-xil0KO5wkPoixdBWGIGolPv9dekf6dVkjjJLAFYchfKcd4DICou67rgGCIO7wAh3i5Ff/6j9IDgZz+GU9cMaqQ==", + "version": "4.2.33", + "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", + "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", "dev": true, "requires": { "@types/node": "*" @@ -95,16 +95,25 @@ "dev": true }, "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, "requires": { - "es-to-primitive": "^1.1.1", + "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + }, + "dependencies": { + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + } } }, "es-to-primitive": { @@ -375,9 +384,9 @@ } }, "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz", + "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==", "dev": true, "requires": { "deep-equal": "~1.0.1", diff --git a/package.json b/package.json --- a/package.json +++ b/package.json @@ -21,15 +21,15 @@ "tslib": "latest" }, "devDependencies": { - "typescript": "latest", - "tape": "latest", - "@types/tape": "latest", + "@types/node": "latest", "@types/requirejs": "latest", - "@types/node": "latest", - "requirejs": "latest", + "@types/tape": "latest", + "dojo": "^1.10.0", "faucet": "latest", - "dojo": "^1.10.0", - "tslib": "latest" + "requirejs": "latest", + "tape": "^4.9.2", + "tslib": "latest", + "typescript": "latest" }, "types": "main.d.ts" } diff --git a/src/amd/js/Uri.js b/src/amd/js/Uri.js --- a/src/amd/js/Uri.js +++ b/src/amd/js/Uri.js @@ -1,95 +1,97 @@ -define( - [ "./declare" ], - function(declare) { - function parseURI(uri) { - var schema, host, port, path, query, hash, i; - if (typeof (uri) == "string") { - if ((i = uri.indexOf(":")) >= 0 && - uri.substr(0, i).match(/^\w+$/)) { - schema = uri.substr(0, i); - uri = uri.substr(i + 1); - } +define(["./declare", "./log/trace!"], function (declare, trace) { + trace.warn("THIS MODULE IS DEPRECATED! use uri-js or similar alternatives."); + + function parseURI(uri) { + var schema, host, port, path, query, hash, i; + if (typeof (uri) == "string") { + if ((i = uri.indexOf(":")) >= 0 && + uri.substr(0, i).match(/^\w+$/)) { + schema = uri.substr(0, i); + uri = uri.substr(i + 1); + } - if (uri.indexOf("//") === 0) { - uri = uri.substr(2); - if ((i = uri.indexOf("/")) >= 0) { - host = uri.substr(0, i); - uri = uri.substr(i); - } else { - host = uri; - uri = ""; - } + if (uri.indexOf("//") === 0) { + uri = uri.substr(2); + if ((i = uri.indexOf("/")) >= 0) { + host = uri.substr(0, i); + uri = uri.substr(i); + } else { + host = uri; + uri = ""; } - - if ((i = uri.indexOf("?")) >= 0) { - path = uri.substr(0, i); - uri = uri.substr(i + 1); + } - } else { - path = uri; - uri = ""; + if ((i = uri.indexOf("?")) >= 0) { + path = uri.substr(0, i); + uri = uri.substr(i + 1); - if ((i = path.indexOf("#")) >= 0) { - hash = path.substr(i + 1); - path = path.substr(0, i); - } - } + } else { + path = uri; + uri = ""; - if ((i = uri.indexOf("#")) >= 0) { - query = uri.substr(0, i); - hash = uri.substr(i + 1); - } else { - query = uri; + if ((i = path.indexOf("#")) >= 0) { + hash = path.substr(i + 1); + path = path.substr(0, i); } } - if (host && (i = host.lastIndexOf(":")) >= 0) { - port = host.substr(i + 1); - host = host.substr(0, i); + if ((i = uri.indexOf("#")) >= 0) { + query = uri.substr(0, i); + hash = uri.substr(i + 1); + } else { + query = uri; } + } - return { - schema : schema, - host : host, - port : port, - path : path, - query : query, - hash : hash - }; + if (host && (i = host.lastIndexOf(":")) >= 0) { + port = host.substr(i + 1); + host = host.substr(0, i); } - function makeURI(options) { - var uri = []; + return { + schema: schema, + host: host, + port: port, + path: path, + query: query, + hash: hash + }; + } - if (options.schema) - uri.push(options.schema, ":"); - if (options.host) - uri.push("//", options.host); - if (options.host && options.port) - uri.push(":", options.port); + function makeURI(options) { + var uri = []; - if (options.path) { - if (options.host && options.path[0] != "/") - uri.push("/"); - uri.push(options.path); - } else if (options.host) { + if (options.schema) + uri.push(options.schema, ":"); + if (options.host) + uri.push("//", options.host); + if (options.host && options.port) + uri.push(":", options.port); + + if (options.path) { + if (options.host && options.path[0] != "/") uri.push("/"); - } - - if (options.query) - uri.push("?", options.query); - if (options.hash) - uri.push("#", options.hash); - - return uri.join(""); + uri.push(options.path); + } else if (options.host) { + uri.push("/"); } - function reducePath(parts) { - var balance = 0, result = [], isRoot; + if (options.query) + uri.push("?", options.query); + if (options.hash) + uri.push("#", options.hash); + + return uri.join(""); + } - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - switch (part) { + function reducePath(parts) { + var balance = 0, + result = [], + isRoot; + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + switch (part) { case "..": if (balance > 0) { result.pop(); @@ -113,120 +115,122 @@ define( result.push(part); balance++; break; - } } - - return result.join("/"); } - var meta = { - schema : null, - host : null, - port : null, - path : null, - query : null, - hash : null - }; - - var URI = declare(null, { - constructor : function(opts) { - if (typeof (opts) == "string") - opts = parseURI(opts); - for ( var p in meta) - if (p in opts) - this[p] = opts[p]; - }, - - clone : function() { - return new URI(this); - }, + return result.join("/"); + } - combine : function(rel) { - var me = this; - - if (typeof (rel) === "string") - rel = new URI(rel); - else - rel = rel.clone(); - - // //some.host:123/path?q=a#123 - if (rel.host) - return rel; + var meta = { + schema: null, + host: null, + port: null, + path: null, + query: null, + hash: null + }; - // /abs/path?q=a#123 - if (rel.path && rel.path[0] == "/") { - if (me.host) { - rel.schema = me.schema; - rel.host = me.host; - rel.port = me.port; - } - return rel; - } - - var base = me.clone(); + var URI = declare(null, { + constructor: function (opts) { + trace.warn("This class is deprecated use uri-js or similar"); + if (typeof (opts) == "string") + opts = parseURI(opts); + for (var p in meta) + if (p in opts) + this[p] = opts[p]; + }, - // rel/path?a=b#cd - if (rel.path) { - var segments = base.getSegments(); - segments.pop(); - segments.push.apply(segments, rel.getSegments()); - - base.path = reducePath(segments); - } + clone: function () { + return new URI(this); + }, - // ?q=a#123 - if (rel.query) - base.query = rel.query; - if (rel.hash) - base.hase = rel.hash; + combine: function (rel) { + var me = this; - return base; - }, - - optimize : function() { - this.path = reducePath(this.getSegments()); - }, + if (typeof (rel) === "string") + rel = new URI(rel); + else + rel = rel.clone(); - getSegments : function() { - if (typeof (this.path) === "string") - return this.path.split("/"); - else - return []; - }, - - toString : function() { - var uri = [], me = this; + // //some.host:123/path?q=a#123 + if (rel.host) + return rel; - if (me.schema) - uri.push(me.schema, ":"); - if (me.host) - uri.push("//", me.host); - if (me.host && me.port) - uri.push(":", me.port); - - if (me.path) { - if (me.host && me.path[0] != "/") - uri.push("/"); - uri.push(me.path); - } else if (me.host) { - uri.push("/"); + // /abs/path?q=a#123 + if (rel.path && rel.path[0] == "/") { + if (me.host) { + rel.schema = me.schema; + rel.host = me.host; + rel.port = me.port; } - - if (me.query) - uri.push("?", me.query); - if (me.hash) - uri.push("#", me.hash); - - return uri.join(""); + return rel; } - }); + var base = me.clone(); + + // rel/path?a=b#cd + if (rel.path) { + var segments = base.getSegments(); + segments.pop(); + segments.push.apply(segments, rel.getSegments()); + + base.path = reducePath(segments); + } + + // ?q=a#123 + if (rel.query) + base.query = rel.query; + if (rel.hash) + base.hase = rel.hash; + + return base; + }, + + optimize: function () { + this.path = reducePath(this.getSegments()); + }, + + getSegments: function () { + if (typeof (this.path) === "string") + return this.path.split("/"); + else + return []; + }, - URI.combine = function(base, rel) { - if (typeof (base) === "string") - base = new URI(base); - return base.combine(rel).toString(); - }; + toString: function () { + var uri = [], + me = this; + + if (me.schema) + uri.push(me.schema, ":"); + if (me.host) + uri.push("//", me.host); + if (me.host && me.port) + uri.push(":", me.port); + + if (me.path) { + if (me.host && me.path[0] != "/") + uri.push("/"); + uri.push(me.path); + } else if (me.host) { + uri.push("/"); + } - return URI; - }); \ No newline at end of file + if (me.query) + uri.push("?", me.query); + if (me.hash) + uri.push("#", me.hash); + + return uri.join(""); + } + + }); + + URI.combine = function (base, rel) { + if (typeof (base) === "string") + base = new URI(base); + return base.combine(rel).toString(); + }; + + return URI; +}); \ No newline at end of file diff --git a/src/amd/js/data/ObjectStore.js b/src/amd/js/data/ObjectStore.js deleted file mode 100644 --- a/src/amd/js/data/ObjectStore.js +++ /dev/null @@ -1,174 +0,0 @@ -define([ "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", - "../safe", "dojo/when", "dojo/Deferred", "dojo/store/util/QueryResults" ], function(declare, - lang, array, safe, when, Deferred, QueryResults) { - /** - * @module implab/data/RestStore - * - * Реализует шаблон репозитария dojo/store над уже имеющимся хранилищем. При получении и - * отправке данных в нижележащие хранилище используется implab/data/MapSchema для преобразования - * данных. - */ - return declare(null, { - - model: null, - - mapping: null, - - _dataContext: null, - - _store : null, // backing store - - _cache : null, - - constructor : function(options) { - options = options || {}; - - if (options.store) - this._store = options.store; - - if (options.dataContext) { - this._dataContext = options.dataContext; - } - - if (options.cache === false) { - // no cache at all - } else if (options.cache === "string" && options.dataContext) { - this._cache = this._dataContext.getCache(options.cache); - } else { - this._cache = {}; - } - }, - - getDataContext : function() { - return this._dataContext; - }, - - // READ - get : function(id) { - var me = this; - var cache = me.getCacheEntry(id); - if (cache) - return cache; - else - return when(me._store.get(id), function(data) { - return me._mapToObject(id, data); - }); - }, - - query : function(query, options) { - var me = this; - var d = me._store.query(query, options); - var result = QueryResults(when(d, function(data) { - return array.map(data, function(item) { - return me._mapToObject(me._store.getIdentity(item), item); - }); - })); - result.total = d.total; - return result; - }, - - getIdentity : function(object) { - return object.getId(); - }, - - // UPDATE - put : function(object, directives) { - return this._store.put(this._mapFromObject(object), directives); - }, - - // INSERT - add : function(object, directives) { - var me = this; - // добавляем в хранилище данные, сохраняем в кеше объект с - // полученным идентификатором - return when( - me._store.add(this._mapFromObject(object), directives), - function(id) { - object.attach(id, me); - me.storeCacheEntry(id, object); - return id; - }); - }, - - // DELETE - remove : function(id) { - var me = this; - return when(me._store.remove(id), function() { - me.removeCacheEntry(id); - }); - }, - - _mapToObject : function(id, data) { - var instance = this.createInstance(id); - this.populateInstance(instance, data); - return instance; - }, - - _mapFromObject : function(object) { - return this.serializeInstance(object); - }, - - getCacheEntry : function(id) { - safe.argumentNotNull(id, "id"); - id = id.toString(); - - return this._cache[id]; - }, - - storeCacheEntry : function(id, object) { - safe.argumentNotNull(id, "id"); - id = id.toString(); - - this._cache[id] = object; - }, - - removeCacheEntry : function(id) { - safe.argumentNotNull(id, "id"); - id = id.toString(); - delete this._cache[id]; - }, - - /** Создает экземпляр сущности с указанным идентификатором, либо извлекает из кеша, если таковая уже имеется. - * @remarks - * Технически сюда можно было бы дополнительно передать данные для ининциализации объекта, - * но концептуально это не верно, поскольку процесс чтения объекта состоит из двух этапов: - * 1. Создание пустого объекта (createInstance) - * 2. Заполнение объекта при помощи схемы отображения (populateInstance) - * при этом первый этап может быть выполнен за долго до второго, например, - * при создании заглушек в процессе установления ссылок между объектами. - */ - createInstance : function(id) { - var instance = this.getCacheEntry(id); - if (!instance) { - instance = this.createInstanceImpl(id); - this.storeCacheEntry(id, instance); - } - return instance; - }, - - /** Непосредственно создает экземпляр сущнсти, т.е. является фабричным методом. - * @param {String} id идентификатор создаваемого экземпляра. - */ - createInstanceImpl : function(id) { - var opts = { - dataContext : this.getDataContext(), - id : id - }; - - return new this.itemsType(opts); - }, - - populateInstance : function(instance, data) { - this.mapping.readData(instance, data,this.getDataContext()); - if (instance.onPopulate) - instance.onPopulate(); - }, - - serializeInstance : function(instance) { - var data = {}; - this.mapping.writeData(instance, data, this.getDataContext()); - return data; - } - - }); -}); \ No newline at end of file diff --git a/src/amd/js/data/StatefullStoreAdapter.js b/src/amd/js/data/StatefullStoreAdapter.js deleted file mode 100644 --- a/src/amd/js/data/StatefullStoreAdapter.js +++ /dev/null @@ -1,19 +0,0 @@ -define(["dojo/_base/declare", "dojo/_base/array", "../safe", "./StoreAdapter"], function(declare, array, safe ,AdapterStore){ - return declare([AdapterStore], { - _attrs : null, - - constructor : function(opts) { - safe.argumentNotEmptyArray(opts.attrs, "opts.attrs"); - this._attrs = opts.attrs; - }, - - mapItem : function(item) { - var result = {}; - array.forEach(this._attrs, function(p) { - result[p] = item.get(p); - }); - return result; - } - }); - -}); \ No newline at end of file diff --git a/src/amd/js/data/declare-model.js b/src/amd/js/data/declare-model.js deleted file mode 100644 --- a/src/amd/js/data/declare-model.js +++ /dev/null @@ -1,72 +0,0 @@ -define([ "dojo/_base/declare", "./_ModelBase", "./MapSchema" ], function( - declare, _ModelBase, MapSchema) { - /** - * Создает новый класс, унаследованный от ./ModelBase, с указанной схемой - * отображения данных. - * - * @details Модель представляет собой объект, живущий в рамках контекста - * данных, также имеющий две схемы отображения: из модели хранения - * в источнике данных (toObjectMap) и наооборот в модель хранения в - * источнике данных (fromObjectMap). - * - * Описание схемы выглядит следующим образом - *
-     * {
-     *      name : null, // отображение в обе стороны без преобразования
-     *      
-     *      age : Number,   // при преобразоваении к объекту поле будет преобразовано dst.age = Number(src.age)
-     *                      // обратное преобразование отсутстсвует
-     *      
-     *      age : [Number, null] // тоже самое что и age : Number
-     *      
-     *      date : [Date, function(v) { return v.toString() }] // указывается преобразование в одну и в другую сторону
-     * }
-     * 
-     */
-    return function(schema, mixins, opts) {
-        var fromObjectSchema = {}, toObjectSchema = {};
-        if (schema !== null && schema !== undefined) {
-            for ( var p in schema) {
-                var mapper = schema[p];
-
-                if (mapper instanceof Array) {
-                    toObjectSchema[p] = mapper[0];
-                    fromObjectSchema[p] = mapper[1];
-                } else {
-                    toObjectSchema[p] = mapper;
-                    fromObjectSchema[p] = null;
-                }
-            }
-        }
-
-        if (arguments.length < 3) {
-            opts = mixins;
-            mixins = undefined;
-        }
-
-        var base = [ _ModelBase ];
-        if (mixins) {
-            if (mixins instanceof Array)
-                base = base.concat(mixins);
-            else
-                base.push(mixins);
-        }
-
-        var model = declare(base, opts);
-
-        model.toObjectMap = new MapSchema(toObjectSchema);
-
-        model.fromObjectMap = new MapSchema(fromObjectSchema);
-
-        model.readData = function(that, data, context) {
-            model.toObjectMap.map(data, that, context);
-        };
-
-        model.writeData = function(that, data, context) {
-            data = data || {};
-            model.fromObjectMap.map(that, data, context);
-        };
-
-        return model;
-    };
-});
\ No newline at end of file
diff --git a/src/amd/js/declare/_load.js b/src/amd/js/declare/_load.js
deleted file mode 100644
--- a/src/amd/js/declare/_load.js
+++ /dev/null
@@ -1,12 +0,0 @@
-define([], function () {
-    'use strict';
-
-    return {
-        load: function (id, require, callback) {
-            require(['dojo/_base/declare'], function (declare) {
-                callback(declare);
-            });
-        }
-    };
-
-});
\ No newline at end of file
diff --git a/src/amd/js/log/trace.js b/src/amd/js/log/trace.js
deleted file mode 100644
--- a/src/amd/js/log/trace.js
+++ /dev/null
@@ -1,52 +0,0 @@
-define(["./TraceSource"], function (TraceSource_1) {
-    'use strict';
-
-    var TraceSource = TraceSource_1.TraceSource;
-
-    return {
-
-        on: function (filter, cb) {
-            if (arguments.length == 1) {
-                cb = filter;
-                filter = undefined;
-            }
-            var test;
-            if (filter instanceof RegExp) {
-                test = function (chId) {
-                    return filter.test(chId);
-                };
-            } else if (filter instanceof Function) {
-                test = filter;
-            } else if (filter) {
-                test = function (chId) {
-                    return chId == filter;
-                };
-            }
-
-            if (test) {
-                TraceSource.on(function (source) {
-                    if (test(source.id))
-                        source.on(cb);
-                });
-            } else {
-                TraceSource.on(function (source) {
-                    source.on(cb);
-                });
-            }
-        },
-
-        load: function (id, require, cb) {
-            if (id) {
-                cb(TraceSource.get(id));
-            } else if (require.module && require.module.mid) {
-                cb(TraceSource.get(require.module.mid));
-            } else {
-                require(['module'], function (module) {
-                    cb(TraceSource.get(module && module.id));
-                });
-            }
-        },
-
-        dynamic: true,
-    };
-});
\ No newline at end of file
diff --git a/src/amd/js/messaging/Session.js b/src/amd/js/messaging/Session.js
--- a/src/amd/js/messaging/Session.js
+++ b/src/amd/js/messaging/Session.js
@@ -1,217 +1,215 @@
-define(
-    [
-        "dojo/_base/declare",
-        "dojo/_base/lang",
-        "dojo/request",
-        "./Destination",
-        "dojo/Evented",
-        "dojo/Deferred",
-        "../log/_LogMixin" ],
-
-    function(declare, lang, request, Destination, Evented, Deferred, _LogMixin) {
+define([
+    "dojo/_base/declare",
+    "dojo/request",
+    "./Destination",
+    "dojo/Evented",
+    "dojo/Deferred",
+    "../log/_LogMixin"
+], function (declare, request, Destination, Evented, Deferred, _LogMixin) {
 
-        var cls = declare(
-            [ Evented, _LogMixin ],
-            {
-                _id : null,
-                _baseUrl : null,
-                _destinations : null,
-                _timeout : 100000,
-                _clients : null,
-                _started : null,
-                _starting : false,
+    var cls = declare(
+        [Evented, _LogMixin], {
+            _id: null,
+            _baseUrl: null,
+            _destinations: null,
+            _timeout: 100000,
+            _clients: null,
+            _started: null,
+            _starting: false,
 
-                constructor : function(baseUrl, options) {
-                    if (!baseUrl)
-                        throw new Error("baseUrl is required");
-                    options = options || {};
+            constructor: function (baseUrl, options) {
+                if (!baseUrl)
+                    throw new Error("baseUrl is required");
+                options = options || {};
 
-                    this._baseUrl = baseUrl.replace(/\/*$/, "");
-                    this._destinations = {};
-                    this._pending = [];
-                    this._clients = {};
-                    if (options.timeout)
-                        this._timeout = options.timeout;
+                this._baseUrl = baseUrl.replace(/\/*$/, "");
+                this._destinations = {};
+                this._pending = [];
+                this._clients = {};
+                if (options.timeout)
+                    this._timeout = options.timeout;
 
-                    this._started = new Deferred();
-                },
-
-                start : function() {
-                    if (this._starting)
-                        return this._started;
-                    this._starting = true;
+                this._started = new Deferred();
+            },
 
-                    var me = this;
-                    me.log("START");
-                    request(this._baseUrl, {
-                        method : "POST",
-                        handleAs : "json"
-                    }).then(function(result) {
-                        me._id = result;
-                        me._emitConnected();
-                        me._poll();
-                        me._started.resolve(me);
-                    }, function(error) {
-                        me._emitError(error);
-                        me._started.reject(me);
-                    });
-                    return me._started.promise;
-                },
-
-                createClient : function(options) {
-                    if (!options || !options.destination || !options.mode)
-                        throw new Error("Invalid argument");
-
-                    var me = this;
-
-                    return me._started
-                        .then(function() {
-                            var url = me._makeUrl(me._id);
-                            me.log(
-                                "CREATE mode=${0}, destination=${1}",
-                                options.mode,
-                                options.destination);
+            start: function () {
+                if (this._starting)
+                    return this._started;
+                this._starting = true;
 
-                            return request(url, {
-                                method : "POST",
-                                data : {
-                                    mode : options.mode,
-                                    destination : options.destination
-                                },
-                                handleAs : 'json'
-                            })
-                                .then(
-                                    function(id) {
-                                        me
-                                            .log(
-                                                "CLIENT id=${0}, mode=${1}, destination=${2}",
-                                                id,
-                                                options.mode,
-                                                options.destination);
-                                        me._clients[id] = options.client
-                                            ? options.client
-                                            : function(msg) {
-                                                me
-                                                    .warn(
-                                                        "The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
-                                                        id,
-                                                        options.mode,
-                                                        options.destination);
-                                            };
-                                        return id;
-                                    });
-                        });
+                var me = this;
+                me.log("START");
+                request(this._baseUrl, {
+                    method: "POST",
+                    handleAs: "json"
+                }).then(function (result) {
+                    me._id = result;
+                    me._emitConnected();
+                    me._poll();
+                    me._started.resolve(me);
+                }, function (error) {
+                    me._emitError(error);
+                    me._started.reject(me);
+                });
+                return me._started.promise;
+            },
 
-                },
+            createClient: function (options) {
+                if (!options || !options.destination || !options.mode)
+                    throw new Error("Invalid argument");
 
-                deleteClient : function(options) {
-                    if (!options || !options.clientId)
-                        throw new Error("Invalid argument");
+                var me = this;
 
-                    var me = this, id = options.clientId;
-
-                    return me._started.then(function() {
-                        var url = me._makeUrl(me._id, options.clientId);
-
-                        me.log("DELETE CLIENT ${0}", options.clientId);
+                return me._started
+                    .then(function () {
+                        var url = me._makeUrl(me._id);
+                        me.log(
+                            "CREATE mode=${0}, destination=${1}",
+                            options.mode,
+                            options.destination);
 
                         return request(url, {
-                            method : "DELETE",
-                            handleAs : 'json'
-                        }).then(function() {
-                            me.log("CLIENT DELETED ${0}", options.clientId);
-                            me._clients[id] = undefined;
-                        });
+                                method: "POST",
+                                data: {
+                                    mode: options.mode,
+                                    destination: options.destination
+                                },
+                                handleAs: 'json'
+                            })
+                            .then(
+                                function (id) {
+                                    me
+                                        .log(
+                                            "CLIENT id=${0}, mode=${1}, destination=${2}",
+                                            id,
+                                            options.mode,
+                                            options.destination);
+                                    me._clients[id] = options.client ?
+                                        options.client :
+                                        function (msg) {
+                                            me
+                                                .warn(
+                                                    "The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
+                                                    id,
+                                                    options.mode,
+                                                    options.destination);
+                                        };
+                                    return id;
+                                });
                     });
-                },
+
+            },
+
+            deleteClient: function (options) {
+                if (!options || !options.clientId)
+                    throw new Error("Invalid argument");
 
-                _poll : function() {
-                    var me = this, url = this._makeUrl(this._id);
-                    me.log("POLL timeout=${0}", me._timeout);
-                    request(url, {
-                        method : "GET",
-                        handleAs : "json",
-                        query : {
-                            timeout : me._timeout
-                        }
-                    }).then(function(response) {
-                        me._handlePoll(response);
-                        me._poll();
-                    }, function(err) {
-                        me.error("POLL faield with ${0}", err);
-                        me._emitError(err);
+                var me = this,
+                    id = options.clientId;
+
+                return me._started.then(function () {
+                    var url = me._makeUrl(me._id, options.clientId);
+
+                    me.log("DELETE CLIENT ${0}", options.clientId);
+
+                    return request(url, {
+                        method: "DELETE",
+                        handleAs: 'json'
+                    }).then(function () {
+                        me.log("CLIENT DELETED ${0}", options.clientId);
+                        me._clients[id] = undefined;
                     });
-                },
+                });
+            },
 
-                _handlePoll : function(response) {
-                    if (!response) {
-                        this.log("POLL response undefined, looks like a bug");
-                        return;
+            _poll: function () {
+                var me = this,
+                    url = this._makeUrl(this._id);
+                me.log("POLL timeout=${0}", me._timeout);
+                request(url, {
+                    method: "GET",
+                    handleAs: "json",
+                    query: {
+                        timeout: me._timeout
                     }
-                    if (!response.results || !response.results.length) {
-                        this.log("POLL response is empty");
-                        return;
-                    }
-
-                    var results = response.results;
-                    this.log("POLL got ${0} results", results.length);
+                }).then(function (response) {
+                    me._handlePoll(response);
+                    me._poll();
+                }, function (err) {
+                    me.error("POLL faield with ${0}", err);
+                    me._emitError(err);
+                });
+            },
 
-                    for (var i = 0; i < results.length; i++) {
-                        var result = results[i];
-                        var client = this._clients[result.clientId];
-                        if (!client) {
-                            // TODO this could happen due to client isn't
-                            // registered yet
-                            this.error("Unknown client ${0}", result.clientId);
-                            continue;
-                        }
-                        client.call(this, result);
-                    }
-                },
+            _handlePoll: function (response) {
+                if (!response) {
+                    this.log("POLL response undefined, looks like a bug");
+                    return;
+                }
+                if (!response.results || !response.results.length) {
+                    this.log("POLL response is empty");
+                    return;
+                }
+
+                var results = response.results;
+                this.log("POLL got ${0} results", results.length);
 
-                _emitError : function(err) {
-                    this.emit("error", err);
-                },
+                for (var i = 0; i < results.length; i++) {
+                    var result = results[i];
+                    var client = this._clients[result.clientId];
+                    if (!client) {
+                        // TODO this could happen due to client isn't
+                        // registered yet
+                        this.error("Unknown client ${0}", result.clientId);
+                        continue;
+                    }
+                    client.call(this, result);
+                }
+            },
 
-                _emitConnected : function() {
-                    var me = this;
-                    me.log("CONNECTED");
-                    me.emit("connected");
-                },
+            _emitError: function (err) {
+                this.emit("error", err);
+            },
 
-                _makeUrl : function() {
-                    var parts = [ this._baseUrl ];
-                    for (var i = 0; i < arguments.length; i++)
-                        parts.push(arguments[i].replace(/\/*$/, ""));
-                    return parts.join('/');
-                },
+            _emitConnected: function () {
+                var me = this;
+                me.log("CONNECTED");
+                me.emit("connected");
+            },
 
-                queue : function(name) {
-                    return this._getDestination("queue://" + name);
-                },
+            _makeUrl: function () {
+                var parts = [this._baseUrl];
+                for (var i = 0; i < arguments.length; i++)
+                    parts.push(arguments[i].replace(/\/*$/, ""));
+                return parts.join('/');
+            },
 
-                topic : function(name) {
-                    return this._getDestination("topic://" + name);
-                },
+            queue: function (name) {
+                return this._getDestination("queue://" + name);
+            },
 
-                _getDestination : function(uri) {
-                    if (uri in this._destinations)
-                        return this._destinations[uri];
+            topic: function (name) {
+                return this._getDestination("topic://" + name);
+            },
 
-                    var dest = new Destination(this, uri);
-                    this._destinations[uri] = dest;
-                    return dest;
-                },
+            _getDestination: function (uri) {
+                if (uri in this._destinations)
+                    return this._destinations[uri];
+
+                var dest = new Destination(this, uri);
+                this._destinations[uri] = dest;
+                return dest;
+            },
 
-                toString : function() {
-                    return [ "[", "SESSION ", this._id, "]" ].join(" ");
-                }
-            });
+            toString: function () {
+                return ["[", "SESSION ", this._id, "]"].join(" ");
+            }
+        });
 
-        cls.connect = function(url, options) {
-            var session = new cls(url, options);
-            return session.start();
-        };
+    cls.connect = function (url, options) {
+        var session = new cls(url, options);
+        return session.start();
+    };
 
-        return cls;
-    });
+    return cls;
+});
\ No newline at end of file
diff --git a/src/amd/ts/di/RequireJsHelper.ts b/src/amd/ts/di/RequireJsHelper.ts
deleted file mode 100644
--- a/src/amd/ts/di/RequireJsHelper.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Uuid } from "../Uuid";
-import { argumentNotEmptyString, argumentNotNull } from "../safe";
-import { TraceSource } from "../log/TraceSource";
-import m = require("module");
-
-const trace = TraceSource.get(m.id);
-
-export async function createContextRequire(moduleName: string): Promise {
-    argumentNotEmptyString(moduleName, "moduleName");
-
-    const parts = moduleName.split("/");
-    if (parts[0] === ".")
-        throw new Error("An absolute module path is required");
-
-    if (parts.length > 1)
-        parts.splice(-1, 1, Uuid());
-    else
-        parts.push(Uuid());
-
-    const shim = parts.join("/");
-
-    trace.debug(`define shim ${shim}`);
-
-    return new Promise(cb => {
-        define(shim, ["require"], r => {
-            trace.debug("shim resolved");
-            return r;
-        });
-        require([shim], cb);
-    });
-}
-
-export function makeResolver(req: Require) {
-    argumentNotNull(req, "req");
-
-    return (name: string) => {
-        return new Promise((cb, eb) => {
-            req([name], cb, eb);
-        });
-    };
-}
diff --git a/src/amd/ts/di/ResolverHelper.ts b/src/amd/ts/di/ResolverHelper.ts
new file mode 100644
--- /dev/null
+++ b/src/amd/ts/di/ResolverHelper.ts
@@ -0,0 +1,66 @@
+import { Uuid } from "../Uuid";
+import { argumentNotEmptyString, getGlobal } from "../safe";
+import { TraceSource, DebugLevel } from "../log/TraceSource";
+import m = require("module");
+
+const sandboxId = Uuid();
+define(sandboxId, ["require"], r => r);
+
+// tslint:disable-next-line:no-var-requires
+const globalRequire = require(sandboxId);
+
+const trace = TraceSource.get(m.id);
+
+export async function createContextRequire(moduleName: string): Promise {
+    argumentNotEmptyString(moduleName, "moduleName");
+
+    const parts = moduleName.split("/");
+    if (parts[0] === ".")
+        throw new Error("An absolute module path is required");
+
+    if (parts.length > 1)
+        parts.splice(-1, 1, Uuid());
+    else
+        parts.push(Uuid());
+
+    const shim = parts.join("/");
+
+    trace.debug(`define shim ${shim}`);
+
+    return new Promise(cb => {
+        define(shim, ["require"], r => {
+            trace.debug("shim resolved");
+            return r;
+        });
+        require([shim], cb);
+    });
+}
+
+class ModuleResolver {
+    _base: string;
+    _require: Require;
+
+    constructor(req: Require, base?: string) {
+        this._base = base;
+        this._require = req || globalRequire;
+    }
+
+    resolve(moduleName: string) {
+        argumentNotEmptyString(moduleName, "moduleName");
+        const resolvedName = moduleName[0] === "." && this._base ? [this._base, moduleName].join("/") : moduleName;
+        trace.debug(`${moduleName} -> ${resolvedName}`);
+
+        const req = this._require;
+
+        return new Promise((cb, eb) => {
+            req([resolvedName], cb, eb);
+        });
+    }
+}
+
+export function makeResolver(moduleName: string, contextRequire: Require) {
+    const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
+
+    const resolver = new ModuleResolver(contextRequire, base);
+    return (id: string) => resolver.resolve(id);
+}
diff --git a/src/amd/ts/log/trace.ts b/src/amd/ts/log/trace.ts
new file mode 100644
--- /dev/null
+++ b/src/amd/ts/log/trace.ts
@@ -0,0 +1,44 @@
+import { TraceSource } from "./TraceSource";
+import { Predicate } from "../interfaces";
+
+export = {
+    on(filter: any , cb: any) {
+        if (arguments.length === 1) {
+            cb = filter;
+            filter = undefined;
+        }
+        let test: Predicate;
+        if (filter instanceof RegExp) {
+            test = chId => filter.test(chId);
+        } else if (filter instanceof Function) {
+            test = filter;
+        } else if (filter) {
+            test = chId => chId === filter;
+        }
+
+        if (test) {
+            TraceSource.on(source => {
+                if (test(source.id))
+                    source.events.on(cb);
+            });
+        } else {
+            TraceSource.on(source => {
+                source.events.on(cb);
+            });
+        }
+    },
+
+    load(id: string, require: any, cb: (trace: TraceSource) => void) {
+        if (id) {
+            cb(TraceSource.get(id));
+        } else if (require.module && require.module.mid) {
+            cb(TraceSource.get(require.module.mid));
+        } else {
+            require(["module"], (module: { id: any; }) => {
+                cb(TraceSource.get(module && module.id));
+            });
+        }
+    },
+
+    dynamic: true
+};
diff --git a/src/amd/ts/text/TemplateCompiler.ts b/src/amd/ts/text/TemplateCompiler.ts
new file mode 100644
--- /dev/null
+++ b/src/amd/ts/text/TemplateCompiler.ts
@@ -0,0 +1,104 @@
+import { format } from "./StringFormat";
+import { TraceSource, DebugLevel } from "../log/TraceSource";
+import { ITemplateParser, TokenType } from "./TemplateParser";
+import m = require("module");
+
+const trace = TraceSource.get(m.id);
+
+type TemplateFn = (obj: object) => string;
+
+export class TemplateCompiler {
+
+    _data: string[];
+    _code: string[];
+    _wrapWith = true;
+
+    constructor() {
+        this._code = [];
+        this._data = [];
+    }
+
+    compile(parser: ITemplateParser): TemplateFn {
+        this.preamble();
+        this.visitTemplate(parser);
+        this.postamble();
+
+        const text = this._code.join("\n");
+
+        try {
+            // tslint:disable-next-line:function-constructor
+            const compiled = new Function("obj, format, $data", text);
+            /**
+             * Функция форматирования по шаблону
+             *
+             * @type{Function}
+             * @param{Object} obj объект с параметрами для подстановки
+             */
+            return (obj: object) => compiled(obj || {}, format, this._data);
+        } catch (e) {
+            trace.traceEvent(DebugLevel, [e, text, this._data]);
+            throw e;
+        }
+    }
+
+    preamble() {
+        this._code.push(
+            "var $p = [];",
+            "var print = function(){",
+            "   $p.push(format.apply(null,arguments));",
+            "};"
+        );
+
+        if (this._wrapWith)
+            this._code.push("with(obj){");
+    }
+
+    postamble() {
+        if (this._wrapWith)
+            this._code.push("}");
+
+        this._code.push("return $p.join('');");
+    }
+
+    visitTemplate(parser: ITemplateParser) {
+        while (parser.next()) {
+            switch (parser.token()) {
+                case TokenType.OpenBlock:
+                    this.visitCode(parser);
+                    break;
+                case TokenType.OpenInlineBlock:
+                    this.visitInline(parser);
+                    break;
+                default:
+                    this.visitTextFragment(parser);
+                    break;
+            }
+        }
+    }
+
+    visitInline(parser: ITemplateParser) {
+        const code = ["$p.push("];
+        while (parser.next()) {
+            if (parser.token() === TokenType.CloseBlock)
+                break;
+            code.push(parser.value());
+        }
+        code.push(");");
+        this._code.push(code.join(""));
+    }
+
+    visitCode(parser: ITemplateParser) {
+        const code = [];
+        while (parser.next()) {
+            if (parser.token() === TokenType.CloseBlock)
+                break;
+            code.push(parser.value());
+        }
+        this._code.push(code.join(""));
+    }
+
+    visitTextFragment(parser: ITemplateParser) {
+        const i = this._data.push(parser.value());
+        this._code.push("$p.push($data[" + i + "]);");
+    }
+}
diff --git a/src/amd/ts/text/TemplateParser.ts b/src/amd/ts/text/TemplateParser.ts
new file mode 100644
--- /dev/null
+++ b/src/amd/ts/text/TemplateParser.ts
@@ -0,0 +1,64 @@
+import { argumentNotEmptyString } from "../safe";
+import { MapOf } from "../interfaces";
+
+const splitRx = /(<%=|\[%=|<%|\[%|%\]|%>)/;
+
+export enum TokenType {
+    None,
+    Text,
+    OpenInlineBlock,
+    OpenBlock,
+    CloseBlock
+}
+
+const tokenMap: MapOf = {
+    "<%": TokenType.OpenBlock,
+    "[%": TokenType.OpenBlock,
+    "<%=": TokenType.OpenInlineBlock,
+    "[%=": TokenType.OpenInlineBlock,
+    "%>": TokenType.CloseBlock,
+    "%]": TokenType.CloseBlock
+};
+
+export interface ITemplateParser {
+    next(): boolean;
+    token(): TokenType;
+    value(): string;
+}
+
+export class TemplateParser implements ITemplateParser {
+
+    _tokens: string[];
+    _pos = -1;
+    _type: TokenType;
+    _value: string;
+
+    constructor(text: string) {
+        argumentNotEmptyString(text, "text");
+
+        this._tokens = text.split(splitRx);
+        this._type = TokenType.None;
+    }
+
+    next() {
+        this._pos++;
+        if (this._pos < this._tokens.length) {
+            this._value = this._tokens[this._pos];
+            this._type = tokenMap[this._value] || TokenType.Text;
+            return true;
+        } else {
+            this._type = TokenType.None;
+            this._value = undefined;
+            return false;
+        }
+    }
+
+    token() {
+        return this._type;
+    }
+
+    value() {
+        return this._value;
+    }
+
+}
diff --git a/src/cjs/ts/di/CommonJsHelper.ts b/src/cjs/ts/di/CommonJsHelper.ts
deleted file mode 100644
--- a/src/cjs/ts/di/CommonJsHelper.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export function createContextResolver(moduleName: string) {
-    return (m: string) => { };
-}
diff --git a/src/cjs/ts/di/ResolverHelper.ts b/src/cjs/ts/di/ResolverHelper.ts
new file mode 100644
--- /dev/null
+++ b/src/cjs/ts/di/ResolverHelper.ts
@@ -0,0 +1,33 @@
+import { argumentNotEmptyString } from "../safe";
+import { TraceSource } from "../log/TraceSource";
+
+const trace = TraceSource.get(module.id);
+
+const mainModule = require.main;
+const mainRequire = (id: string) => mainModule.require(id);
+
+class ModuleResolver {
+    _base: string;
+    _require: NodeRequireFunction;
+
+    constructor(req: NodeRequireFunction, base?: string) {
+        this._base = base;
+        this._require = (req || mainRequire).bind(null);
+    }
+
+    resolve(moduleName: string) {
+        argumentNotEmptyString(moduleName, "moduleName");
+        const resolvedName = moduleName[0] === "." && this._base ? [this._base, moduleName].join("/") : moduleName;
+
+        trace.debug(`${moduleName} -> ${resolvedName}`);
+
+        return this._require(resolvedName);
+    }
+}
+
+export function makeResolver(moduleName: string, contextRequire: NodeRequireFunction) {
+    const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
+
+    const resolver = new ModuleResolver(contextRequire, base);
+    return (id: string) => resolver.resolve(id);
+}
diff --git a/src/cjs/tsconfig.json b/src/cjs/tsconfig.json
--- a/src/cjs/tsconfig.json
+++ b/src/cjs/tsconfig.json
@@ -2,7 +2,12 @@
     "extends": "../tsconfig",
     "compilerOptions": {
         "types": [
-            "@types/node"
+            "node"
+        ],
+        "rootDir": "ts",
+        "rootDirs": [
+            "ts",
+            "../typings/main"
         ]
     },
     "include": [
diff --git a/src/main/ts/components/AsyncComponent.ts b/src/main/ts/components/AsyncComponent.ts
--- a/src/main/ts/components/AsyncComponent.ts
+++ b/src/main/ts/components/AsyncComponent.ts
@@ -3,7 +3,7 @@ import { IAsyncComponent, ICancellation,
 import { destroy } from "../safe";
 
 export class AsyncComponent implements IAsyncComponent, ICancellable {
-    _cancel: (e) => void;
+    _cancel: (e: any) => void;
 
     _completion: Promise = Promise.resolve();
 
@@ -33,7 +33,7 @@ export class AsyncComponent implements I
         return this._completion = guard();
     }
 
-    cancel(reason) {
+    cancel(reason: any) {
         if (this._cancel)
             this._cancel(reason);
     }
diff --git a/src/main/ts/di.ts b/src/main/ts/di.ts
--- a/src/main/ts/di.ts
+++ b/src/main/ts/di.ts
@@ -0,0 +1,1 @@
+export { Container } from "./di/Container";
diff --git a/src/main/ts/di/ConfigError.ts b/src/main/ts/di/ConfigError.ts
--- a/src/main/ts/di/ConfigError.ts
+++ b/src/main/ts/di/ConfigError.ts
@@ -1,11 +1,11 @@
 export class ConfigError extends Error {
-    inner;
+    inner: any;
 
     path: string;
 
     configName: string;
 
-    constructor(message: string, inner?) {
+    constructor(message: string, inner?: any) {
         super(message);
         this.inner = inner;
     }
diff --git a/src/main/ts/di/Configuration.ts b/src/main/ts/di/Configuration.ts
--- a/src/main/ts/di/Configuration.ts
+++ b/src/main/ts/di/Configuration.ts
@@ -23,14 +23,30 @@ import { FactoryServiceDescriptor } from
 import { TraceSource } from "../log/TraceSource";
 import { ConfigError } from "./ConfigError";
 import { Cancellation } from "../Cancellation";
+import { makeResolver } from "./ResolverHelper";
+import { ICancellation } from "../interfaces";
 
 const trace = TraceSource.get("@implab/core/di/Configuration");
 
 declare const define;
 declare const require;
+declare const module;
 
 function hasAmdLoader() {
-    return (typeof define === "function" && define.amd);
+    try {
+        // es6 may throw the exception
+        return (typeof define === "function" && define.amd);
+    } catch {
+        return false;
+    }
+}
+
+function hasNodeJs() {
+    try {
+        return (typeof module !== "undefined" && module.exports);
+    } catch {
+        return false;
+    }
 }
 
 async function mapAll(data: object | any[], map?: (v, k) => any): Promise {
@@ -50,7 +66,7 @@ async function mapAll(data: object | any
     }
 }
 
-type Resolver = (qname: string) => any;
+export type ModuleResolver = (moduleName: string, ct?: ICancellation) => any;
 
 type _key = string | number;
 
@@ -64,7 +80,7 @@ export class Configuration {
 
     _configName: string;
 
-    _require: Resolver;
+    _require: ModuleResolver;
 
     constructor(container: Container) {
         argumentNotNull(container, container);
@@ -72,28 +88,31 @@ export class Configuration {
         this._path = [];
     }
 
-    async loadConfiguration(moduleName: string, ct = Cancellation.none) {
+    async loadConfiguration(moduleName: string, contextRequire?: any, ct = Cancellation.none) {
         argumentNotEmptyString(moduleName, "moduleName");
-        // TODO remove the code below somewehere else
-        if (hasAmdLoader()) {
-            // if we have a requirejs loader, use it directly
-            // don't rely on typescript 'import' function
-            const m = await new Promise(cb => require(["./RequireJsHelper"], cb));
-            const r = m.makeResolver(require);
-            const config = await r(moduleName);
+
+        trace.log("loadConfiguration moduleName={0}", moduleName);
+
+        this._configName = moduleName;
+
+        const r = makeResolver(null, contextRequire);
 
-            return this.applyConfiguration(
-                config,
-                m.makeResolver(await m.createContextRequire(moduleName))
-            );
-        } else {
-            throw new Error("This feature is supported only with the amd loader");
-        }
+        const config = await r(moduleName, ct);
+
+        await this._applyConfiguration(
+            config,
+            makeResolver(moduleName, contextRequire),
+            ct
+        );
     }
 
-    async applyConfiguration(data: object, resolver?: Resolver, ct = Cancellation.none) {
+    applyConfiguration(data: object, contextRequire?: any, ct = Cancellation.none) {
         argumentNotNull(data, "data");
 
+        return this._applyConfiguration(data, makeResolver(void(0), contextRequire), ct);
+    }
+
+    async _applyConfiguration(data: object, resolver?: ModuleResolver, ct = Cancellation.none) {
         trace.log("applyConfiguration");
 
         this._configName = "$";
@@ -140,12 +159,10 @@ export class Configuration {
         }
     }
 
-    async _loadModule(moduleName: string) {
+    _loadModule(moduleName: string) {
         trace.debug("loadModule {0}", moduleName);
 
-        const m = await this._require(moduleName);
-
-        return m;
+        return this._require(moduleName);
     }
 
     async _visitRegistrations(data, name: _key) {
@@ -178,7 +195,7 @@ export class Configuration {
         trace.debug("<{0}", name);
     }
 
-    async _visit(data, name: string): Promise {
+    _visit(data, name: string): Promise {
         if (isPrimitive(data) || isDescriptor(data))
             return data;
 
diff --git a/src/main/ts/di/Container.ts b/src/main/ts/di/Container.ts
--- a/src/main/ts/di/Container.ts
+++ b/src/main/ts/di/Container.ts
@@ -99,11 +99,11 @@ export class Container {
      *  The function which will be used to load a configuration or types for services.
      *
      */
-    async configure(config: string | object, opts?, ct = Cancellation.none) {
+    async configure(config: string | object, opts?: any, ct = Cancellation.none) {
         const c = new Configuration(this);
 
         if (typeof (config) === "string") {
-            return c.loadConfiguration(config, ct);
+            return c.loadConfiguration(config, opts && opts.contextRequire, ct);
         } else {
             return c.applyConfiguration(config, opts && opts.contextRequire, ct);
         }
diff --git a/src/main/ts/di/ResolverHelper.d.ts b/src/main/ts/di/ResolverHelper.d.ts
new file mode 100644
--- /dev/null
+++ b/src/main/ts/di/ResolverHelper.d.ts
@@ -0,0 +1,3 @@
+import { ModuleResolver } from "./Configuration";
+
+export declare function makeResolver(moduleName?: string, contextRequire?: any): ModuleResolver;
\ No newline at end of file
diff --git a/src/main/ts/interfaces.ts b/src/main/ts/interfaces.ts
--- a/src/main/ts/interfaces.ts
+++ b/src/main/ts/interfaces.ts
@@ -2,6 +2,8 @@ export type Constructor = new (.
 
 export type Factory = (...args: any[]) => T;
 
+export type Predicate = (x: T) => boolean;
+
 export interface MapOf {
     [key: string]: T;
 }
diff --git a/src/main/ts/log/TraceSource.ts b/src/main/ts/log/TraceSource.ts
--- a/src/main/ts/log/TraceSource.ts
+++ b/src/main/ts/log/TraceSource.ts
@@ -47,7 +47,7 @@ export class TraceSource {
 
     debug(msg: string, ...args: any[]) {
         if (this.isEnabled(DebugLevel))
-            this.emit(DebugLevel, format(msg, args));
+            this.emit(DebugLevel, format.apply(null, arguments));
     }
 
     isLogEnabled() {
@@ -56,7 +56,7 @@ export class TraceSource {
 
     log(msg: string, ...args: any[]) {
         if (this.isEnabled(LogLevel))
-            this.emit(LogLevel, format(msg, args));
+            this.emit(LogLevel, format.apply(null, arguments));
     }
 
     isWarnEnabled() {
@@ -65,7 +65,7 @@ export class TraceSource {
 
     warn(msg: string, ...args: any[]) {
         if (this.isEnabled(WarnLevel))
-            this.emit(WarnLevel, format(msg, args));
+            this.emit(WarnLevel, format.apply(null, arguments));
     }
 
     /**
diff --git a/src/main/ts/log/writers/ConsoleWriter.ts b/src/main/ts/log/writers/ConsoleWriter.ts
--- a/src/main/ts/log/writers/ConsoleWriter.ts
+++ b/src/main/ts/log/writers/ConsoleWriter.ts
@@ -3,6 +3,15 @@ import { TraceEvent, LogLevel, WarnLevel
 import { Cancellation } from "../../Cancellation";
 import { destroy } from "../../safe";
 
+function hasConsole() {
+    try {
+        // tslint:disable-next-line:no-console
+        return (typeof console !== "undefined" && typeof console.log === "function");
+    } catch {
+        return false;
+    }
+}
+
 export class ConsoleWriter implements IDestroyable {
     readonly _subscriptions = new Array();
 
@@ -15,17 +24,21 @@ export class ConsoleWriter implements ID
     }
 
     writeEvent(next: TraceEvent) {
+        // IE will create console only when devepoler tools are activated
+        if (!hasConsole())
+            return;
+
         if (next.level >= DebugLevel) {
-            // tslint:disable-next-line
+            // tslint:disable-next-line:no-console
             console.debug(next.source.id.toString(), next.arg);
         } else if (next.level >= LogLevel) {
-            // tslint:disable-next-line
+            // tslint:disable-next-line:no-console
             console.log(next.source.id.toString(), next.arg);
         } else if (next.level >= WarnLevel) {
-            // tslint:disable-next-line
+            // tslint:disable-next-line:no-console
             console.warn(next.source.id.toString(), next.arg);
         } else {
-            // tslint:disable-next-line
+            // tslint:disable-next-line:no-console
             console.error(next.source.id.toString(), next.arg);
         }
     }
diff --git a/src/main/ts/messaging/interfaces.ts b/src/main/ts/messaging/interfaces.ts
new file mode 100644
--- /dev/null
+++ b/src/main/ts/messaging/interfaces.ts
@@ -0,0 +1,33 @@
+import { ICancellation } from "../interfaces";
+
+/** interface for message consumers, used to recieve messages from a single endpoint.
+ */
+export interface IConsumer {
+    /** Reads the next message from the destination for which the consumer was created.
+     * @param options A provider specific options.
+     * @param ct The cancellation token for this operation.
+     * @returns A recieved message or a promise. If message is prefetched it will
+     * be returned immediately, otherwise a promise is returned.
+     */
+    read(options?: object, ct?: ICancellation): T | Promise;
+}
+
+/** Interface for message produsers, used to send messages to the endpoints.
+ * The producer can be bound to the particular destination or a destination
+ * can be specified as an additional option during post if supported.
+ */
+export interface IProducer {
+    /** Sends a message
+     * @param msg The message to send.
+     * @param options A provider specific options
+     * @param ct The cancellation token for this operation
+     */
+    post(msg: T, options?: object, ct?: ICancellation): void | Promise;
+}
+
+export interface ISession {
+    start(ct: ICancellation): void;
+
+    createConsumer(destination: string, options?: object): IConsumer;
+    createProducer(destination: string, options?: object): IProducer;
+}
diff --git a/src/main/ts/text/TemplateCompiler.ts b/src/main/ts/text/TemplateCompiler.ts
deleted file mode 100644
--- a/src/main/ts/text/TemplateCompiler.ts
+++ /dev/null
@@ -1,102 +0,0 @@
-import { format } from "./StringFormat";
-import { TraceSource, DebugLevel } from "../log/TraceSource";
-import { ITemplateParser, TokenType } from "./TemplateParser";
-
-const trace = TraceSource.get("@implab/text/TemplateCompiler");
-
-type TemplateFn = (obj: object) => string;
-
-export class TemplateCompiler {
-
-    _data: string[];
-    _code: string[];
-    _wrapWith = true;
-
-    constructor() {
-        this._code = [];
-        this._data = [];
-    }
-
-    compile(parser: ITemplateParser): TemplateFn {
-        this.preamble();
-        this.visitTemplate(parser);
-        this.postamble();
-
-        const text = this._code.join("\n");
-
-        try {
-            const compiled = new Function("obj, format, $data", text);
-            /**
-             * Функция форматирования по шаблону
-             *
-             * @type{Function}
-             * @param{Object} obj объект с параметрами для подстановки
-             */
-            return (obj: object) => compiled(obj || {}, format, this._data);
-        } catch (e) {
-            trace.traceEvent(DebugLevel, [e, text, this._data]);
-            throw e;
-        }
-    }
-
-    preamble() {
-        this._code.push(
-            "var $p = [];",
-            "var print = function(){",
-            "   $p.push(format.apply(null,arguments));",
-            "};"
-        );
-
-        if (this._wrapWith)
-            this._code.push("with(obj){");
-    }
-
-    postamble() {
-        if (this._wrapWith)
-            this._code.push("}");
-
-        this._code.push("return $p.join('');");
-    }
-
-    visitTemplate(parser: ITemplateParser) {
-        while (parser.next()) {
-            switch (parser.token()) {
-                case TokenType.OpenBlock:
-                    this.visitCode(parser);
-                    break;
-                case TokenType.OpenInlineBlock:
-                    this.visitInline(parser);
-                    break;
-                default:
-                    this.visitTextFragment(parser);
-                    break;
-            }
-        }
-    }
-
-    visitInline(parser: ITemplateParser) {
-        const code = ["$p.push("];
-        while (parser.next()) {
-            if (parser.token() === TokenType.CloseBlock)
-                break;
-            code.push(parser.value());
-        }
-        code.push(");");
-        this._code.push(code.join(""));
-    }
-
-    visitCode(parser: ITemplateParser) {
-        const code = [];
-        while (parser.next()) {
-            if (parser.token() === TokenType.CloseBlock)
-                break;
-            code.push(parser.value());
-        }
-        this._code.push(code.join(""));
-    }
-
-    visitTextFragment(parser: ITemplateParser) {
-        const i = this._data.push(parser.value());
-        this._code.push("$p.push($data[" + i + "]);");
-    }
-}
diff --git a/src/main/ts/text/TemplateParser.ts b/src/main/ts/text/TemplateParser.ts
deleted file mode 100644
--- a/src/main/ts/text/TemplateParser.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { argumentNotEmptyString } from "../safe";
-import { MapOf } from "../interfaces";
-
-const splitRx = /(<%=|\[%=|<%|\[%|%\]|%>)/;
-
-export enum TokenType {
-    None,
-    Text,
-    OpenInlineBlock,
-    OpenBlock,
-    CloseBlock
-}
-
-const tokenMap: MapOf = {
-    "<%": TokenType.OpenBlock,
-    "[%": TokenType.OpenBlock,
-    "<%=": TokenType.OpenInlineBlock,
-    "[%=": TokenType.OpenInlineBlock,
-    "%>": TokenType.CloseBlock,
-    "%]": TokenType.CloseBlock
-};
-
-export interface ITemplateParser {
-    next(): boolean;
-    token(): TokenType;
-    value(): string;
-}
-
-export class TemplateParser implements ITemplateParser {
-
-    _tokens: string[];
-    _pos = -1;
-    _type: TokenType;
-    _value: string;
-
-    constructor(text: string) {
-        argumentNotEmptyString(text, "text");
-
-        this._tokens = text.split(splitRx);
-        this._type = TokenType.None;
-    }
-
-    next() {
-        this._pos++;
-        if (this._pos < this._tokens.length) {
-            this._value = this._tokens[this._pos];
-            this._type = tokenMap[this._value] || TokenType.Text;
-            return true;
-        } else {
-            this._type = TokenType.None;
-            this._value = undefined;
-            return false;
-        }
-    }
-
-    token() {
-        return this._type;
-    }
-
-    value() {
-        return this._value;
-    }
-
-}
diff --git a/src/package.amd.tmpl.json b/src/package.amd.tmpl.json
new file mode 100644
--- /dev/null
+++ b/src/package.amd.tmpl.json
@@ -0,0 +1,24 @@
+{
+  "name": "${packageName}",
+  "version": "${version}",
+  "description": "${description}",
+  "main": "main.js",
+  "keywords": [
+    "di",
+    "ioc",
+    "logging",
+    "template engine",
+    "dependency injection"
+  ],
+  "author": "${author}",
+  "license": "${license}",
+  "repository": "$repository",
+  "publishConfig": {
+    "access": "public"
+  },
+  "peerDependencies": {
+    "dojo": "^1.10.0"
+  },
+  "module": "${jsmodule}",
+  "target": "${target}"
+}
\ No newline at end of file
diff --git a/src/package.commonjs.tmpl.json b/src/package.commonjs.tmpl.json
new file mode 100644
--- /dev/null
+++ b/src/package.commonjs.tmpl.json
@@ -0,0 +1,21 @@
+{
+  "name": "${packageName}",
+  "version": "${version}",
+  "description": "${description}",
+  "main": "main.js",
+  "keywords": [
+    "di",
+    "ioc",
+    "logging",
+    "template engine",
+    "dependency injection"
+  ],
+  "author": "${author}",
+  "license": "${license}",
+  "repository": "$repository",
+  "publishConfig": {
+    "access": "public"
+  },
+  "module": "${jsmodule}",
+  "target": "${target}"
+}
\ No newline at end of file
diff --git a/src/package.template.json b/src/package.template.json
deleted file mode 100644
--- a/src/package.template.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "name": "${packageName}",
-    "version": "${version}",
-    "description": "${description}",
-    "main": "main.js",
-    "keywords": [
-      "di",
-      "ioc",
-      "logging",
-      "template engine",
-      "dependency injection"
-    ],
-    "author": "${author}",
-    "license": "${license}",
-    "repository": "$repository",
-    "publishConfig": {
-      "access": "public"
-    },
-    "peerDependencies": {
-      "dojo": "^1.10.0"
-    }
-  }
-  
\ No newline at end of file
diff --git a/src/test/js/example.js b/src/test/js/example.js
deleted file mode 100644
--- a/src/test/js/example.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define(["tape", "core/Uuid"], function(tape, Uuid) {
-    "use strict";
-    tape('uuid', function(t) {
-        t.notEqual(Uuid(),Uuid());
-        t.end();
-    });
-});
\ No newline at end of file
diff --git a/src/test/js/mock/config1.js b/src/test/js/mock/config1.js
deleted file mode 100644
--- a/src/test/js/mock/config1.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define({
-    foo: {
-        $type: "./Foo:Foo"
-    },
-
-    bar: {
-        $type: "./Bar:Bar",
-        params: {
-            db: {
-                provider: {
-                    $dependency: "db"
-                }
-            },
-            foo: {
-                $type: "./Foo:Foo"
-            }
-        }
-    },
-    db: "db://localhost"
-});
\ No newline at end of file
diff --git a/src/test/js/plan.js b/src/test/js/plan.js
deleted file mode 100644
--- a/src/test/js/plan.js
+++ /dev/null
@@ -1,8 +0,0 @@
-define([
-    "./ActivatableTests",
-    "./trace-test",
-    "./TraceSourceTests",
-    "./CancellationTests",
-    "./ObservableTests",
-    "./ContainerTests"
-]);
\ No newline at end of file
diff --git a/src/test/js/run-amd-tests.js b/src/test/js/run-amd-tests.js
deleted file mode 100644
--- a/src/test/js/run-amd-tests.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var requirejs = require('requirejs');
-
-requirejs.config({
-    baseUrl: '.',
-    packages: [{
-            name: "@implab/core",
-            location: "build/dist/amd"
-        },
-        {
-            name: "test",
-            location: "build/test/amd"
-        },
-        {
-            name: "dojo",
-            location: "node_modules/dojo"
-        }
-    ],
-    nodeRequire: require
-});
-
-
-requirejs(['test/plan']);
\ No newline at end of file
diff --git a/src/test/js/trace-test.js b/src/test/js/trace-test.js
deleted file mode 100644
--- a/src/test/js/trace-test.js
+++ /dev/null
@@ -1,30 +0,0 @@
-define(["tape"], function(tape) {
-    "use strict";
-    var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
-    var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
-    tape('Load TraceSource for the module', function(t) {
-        require(["@implab/core/log/trace!" + sourceId, "@implab/core/log/TraceSource"], function(trace, TraceSource_1) {
-            var TraceSource = TraceSource_1.TraceSource;
-            t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
-
-            var count = 0;
-
-            var h = TraceSource.on(function(x) {
-                if(x.id == sourceId || x.id == sourceId2)
-                    count++;
-            });
-
-            t.equal(count, 1, "should see created channel immediatelly");
-            t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
-            t.equal(count, 1);
-
-            TraceSource.get(sourceId2);
-
-            t.equal(count, 2);
-
-            h.destroy();
-
-            t.end();
-        });
-    });
-});
\ No newline at end of file
diff --git a/src/test/ts/ContainerTests.ts b/src/test/ts/ContainerTests.ts
--- a/src/test/ts/ContainerTests.ts
+++ b/src/test/ts/ContainerTests.ts
@@ -1,9 +1,8 @@
-import { test, TapeWriter } from "./TestTraits";
+import { test } from "./TestTraits";
 import { Container } from "@implab/core/di/Container";
 import { ReferenceDescriptor } from "@implab/core/di/ReferenceDescriptor";
 import { AggregateDescriptor } from "@implab/core/di/AggregateDescriptor";
 import { ValueDescriptor } from "@implab/core/di/ValueDescriptor";
-import { TraceSource, DebugLevel } from "@implab/core/log/TraceSource";
 import { Foo } from "./mock/Foo";
 import { Bar } from "./mock/Bar";
 import { isNull } from "@implab/core/safe";
diff --git a/src/test/ts/TestTraits.ts b/src/test/ts/TestTraits.ts
--- a/src/test/ts/TestTraits.ts
+++ b/src/test/ts/TestTraits.ts
@@ -2,7 +2,7 @@ import { IObservable, ICancellation, IDe
 import { Cancellation } from "@implab/core/Cancellation";
 import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource";
 import * as tape from "tape";
-import { argumentNotNull } from "@implab/core/safe";
+import { argumentNotNull, destroy } from "@implab/core/safe";
 
 export class TapeWriter implements IDestroyable {
     readonly _tape: tape.Test;
@@ -35,7 +35,7 @@ export class TapeWriter implements IDest
     }
 
     destroy() {
-        this._subscriptions.forEach(x => x.destroy());
+        this._subscriptions.forEach(destroy);
     }
 }
 
@@ -58,8 +58,7 @@ export async function delay(timeout: num
             }
         });
     } finally {
-        if (un)
-            un.destroy();
+        destroy(un);
     }
 }
 
@@ -83,7 +82,7 @@ export function test(name: string, cb: (
 
         } finally {
             t.end();
-            writer.destroy();
+            destroy(writer);
         }
     });
 }
diff --git a/src/test/tsconfig.json b/src/test/tsconfig.json
--- a/src/test/tsconfig.json
+++ b/src/test/tsconfig.json
@@ -5,7 +5,7 @@
         "baseUrl": ".",
         "paths": {
             "@implab/core/*": [
-                "../../build/dist/amd/*"
+                "../../build/dist/*"
             ]
         }
     },
diff --git a/src/testAmd/js/example.js b/src/testAmd/js/example.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/example.js
@@ -0,0 +1,7 @@
+define(["tape", "core/Uuid"], function(tape, Uuid) {
+    "use strict";
+    tape('uuid', function(t) {
+        t.notEqual(Uuid(),Uuid());
+        t.end();
+    });
+});
\ No newline at end of file
diff --git a/src/testAmd/js/mock/config1.js b/src/testAmd/js/mock/config1.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/mock/config1.js
@@ -0,0 +1,20 @@
+define({
+    foo: {
+        $type: "./Foo:Foo"
+    },
+
+    bar: {
+        $type: "./Bar:Bar",
+        params: {
+            db: {
+                provider: {
+                    $dependency: "db"
+                }
+            },
+            foo: {
+                $type: "./Foo:Foo"
+            }
+        }
+    },
+    db: "db://localhost"
+});
\ No newline at end of file
diff --git a/src/testAmd/js/plan.js b/src/testAmd/js/plan.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/plan.js
@@ -0,0 +1,8 @@
+define([
+    "./ActivatableTests",
+    "./trace-test",
+    "./TraceSourceTests",
+    "./CancellationTests",
+    "./ObservableTests",
+    "./ContainerTests"
+]);
\ No newline at end of file
diff --git a/src/testAmd/js/run-amd-tests.js b/src/testAmd/js/run-amd-tests.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/run-amd-tests.js
@@ -0,0 +1,22 @@
+var rjs = require('requirejs');
+
+rjs.config({
+    baseUrl: '.',
+    packages: [{
+            name: "@implab/core",
+            location: "build/dist"
+        },
+        {
+            name: "test",
+            location: "build/test"
+        },
+        {
+            name: "dojo",
+            location: "node_modules/dojo"
+        }
+    ],
+    nodeRequire: require
+});
+
+
+rjs(['test/plan']);
\ No newline at end of file
diff --git a/src/testAmd/js/trace-test.js b/src/testAmd/js/trace-test.js
new file mode 100644
--- /dev/null
+++ b/src/testAmd/js/trace-test.js
@@ -0,0 +1,30 @@
+define(["tape"], function(tape) {
+    "use strict";
+    var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
+    var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
+    tape('Load TraceSource for the module', function(t) {
+        require(["@implab/core/log/trace!" + sourceId, "@implab/core/log/TraceSource"], function(trace, TraceSource_1) {
+            var TraceSource = TraceSource_1.TraceSource;
+            t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
+
+            var count = 0;
+
+            var h = TraceSource.on(function(x) {
+                if(x.id == sourceId || x.id == sourceId2)
+                    count++;
+            });
+
+            t.equal(count, 1, "should see created channel immediatelly");
+            t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
+            t.equal(count, 1);
+
+            TraceSource.get(sourceId2);
+
+            t.equal(count, 2);
+
+            h.destroy();
+
+            t.end();
+        });
+    });
+});
\ No newline at end of file
diff --git a/src/testAmd/tsconfig.json b/src/testAmd/tsconfig.json
new file mode 100644
--- /dev/null
+++ b/src/testAmd/tsconfig.json
@@ -0,0 +1,22 @@
+{
+    "extends": "../tsconfig",
+    "compilerOptions": {
+        "rootDir": "ts",
+        "baseUrl": ".",
+        "paths": {
+            "@implab/core/*": [
+                "../../build/dist/*"
+            ]
+        },
+        "types": [
+            "requirejs"
+        ],
+        "rootDirs": [
+            "ts",
+            "../typings/test"
+        ]
+    },
+    "include" : [
+        "ts/**/*.ts"
+    ]
+}
\ No newline at end of file
diff --git a/src/tsconfig.json b/src/tsconfig.json
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -1,18 +1,10 @@
 {
     "compilerOptions": {
-        "target": "es3",
-        "sourceMap": true,
-        "declaration": true,
         "moduleResolution": "node",
         "noEmitOnError": true,
         "listFiles": true,
-        "lib": [
-            "es5",
-            "es2015.promise",
-            "es2015.symbol",
-            "dom"
-        ],
-        "types": []
+        "types": [],
+        "lib": ["es5", "es2015.promise", "es2015.symbol", "dom", "scripthost"]
     },
     "files": []
 }
\ No newline at end of file