##// END OF EJS Templates
working on support commonjs modules format
cin -
r59:ba3ff79c2832 default
parent child
Show More
@@ -0,0 +1,13
1 # Сборка проекта
2
3 Проект представляет собой сложную структуру, которая делится на несколько наборов, которые используются при условной сборке.
4 Каждый набор сожержит в себе множество артефактов, которые класифицируются по способу сборки, например, исходные тексты js и ts и набор файлов, которые будут просто скопированы без изменений.
5
6 Такая структура позволяет сочитать в проекте несколько языков, а также делать сборки с разными параметрами для разных платформ.
7
8 ## NPM
9
10 Довольно ограниченная среда, поскольку может быть опубликован только один вариант библиотеки, можно конечно использовать разные версии, чтобы публиковать разные сборки, но это приведет к определенным сложностям, по крайней мере при использовании зависимостей, уже не говоря о том, что это будет путать разработчиков.
11 Использование суффиксов в имени пакета только частично решает задачу, поскольку не все системы могут использовать указание путей при настройке загрузчиков. RequireJS позволяет указывать месторасположение пакета, commonJs не позволяет это сделать без использования специальных средств.
12
13 npm позволяет устанавливать библиотеку используя ссылку, что дает возможность ее устанавки из произвольных мест. например, можно установить нужный вариант библиотеки по ссылке <https://implab.org/pub/js/implab/core-es2017-commonjs-1.2.0-rc1.tgz> . No newline at end of file
@@ -0,0 +1,56
1 # Обмен сообщениями
2
3 ## Session
4
5 Контекст обмена сообщениями, отвечает за создание конечных точек для получения и отправки сообщений, а также инкапсулирует в себе работу с провайдером системы обмена сообщениями.
6
7 Сессия позволяет выполнить конфигурацию компонент обработки сообщений, до начала реального обмена и после окончания конфигурации выполнить метод `start` после которого начнется реальная обработка. Такой способ позволяет избежать ошибки и потерю сообщений по причине того, что часть компонент готова к работе и уже получает и отправляет сообщения, а часть еще не настроена.
8
9 ```ts
10
11 // some provider related code
12 const connection = new StompService("ws://broker.329broker.com:15674/ws", { user: "user", pass: "secret" });
13 const session = connection.createSession();
14
15 // create and configure consumers and producers
16 const consumer = session.createConsumer("topic://notify");
17
18 // make event driven consumer
19 consumer.observe().on(msg => {
20 // do something
21
22 // mark the message as processed
23 msg.ack();
24 });
25
26 const producer = session.createProducer("queue://requests");
27
28 // signal the session to start
29 session.start();
30
31 // await the session is started
32 await session.getCompletion();
33
34 ```
35
36 ### start
37
38 Начинает сессию
39
40 ### createConsumer
41
42 ### createProducer
43
44 ## Consumer
45
46 ### Push-consumer
47
48 #### messages
49
50 ### Pull-consumer
51
52 #### read
53
54 ## Producer
55
56 ### post No newline at end of file
@@ -0,0 +1,66
1 import { Uuid } from "../Uuid";
2 import { argumentNotEmptyString, getGlobal } from "../safe";
3 import { TraceSource, DebugLevel } from "../log/TraceSource";
4 import m = require("module");
5
6 const sandboxId = Uuid();
7 define(sandboxId, ["require"], r => r);
8
9 // tslint:disable-next-line:no-var-requires
10 const globalRequire = require(sandboxId);
11
12 const trace = TraceSource.get(m.id);
13
14 export async function createContextRequire(moduleName: string): Promise<Require> {
15 argumentNotEmptyString(moduleName, "moduleName");
16
17 const parts = moduleName.split("/");
18 if (parts[0] === ".")
19 throw new Error("An absolute module path is required");
20
21 if (parts.length > 1)
22 parts.splice(-1, 1, Uuid());
23 else
24 parts.push(Uuid());
25
26 const shim = parts.join("/");
27
28 trace.debug(`define shim ${shim}`);
29
30 return new Promise<Require>(cb => {
31 define(shim, ["require"], r => {
32 trace.debug("shim resolved");
33 return r;
34 });
35 require([shim], cb);
36 });
37 }
38
39 class ModuleResolver {
40 _base: string;
41 _require: Require;
42
43 constructor(req: Require, base?: string) {
44 this._base = base;
45 this._require = req || globalRequire;
46 }
47
48 resolve(moduleName: string) {
49 argumentNotEmptyString(moduleName, "moduleName");
50 const resolvedName = moduleName[0] === "." && this._base ? [this._base, moduleName].join("/") : moduleName;
51 trace.debug(`${moduleName} -> ${resolvedName}`);
52
53 const req = this._require;
54
55 return new Promise<any>((cb, eb) => {
56 req([resolvedName], cb, eb);
57 });
58 }
59 }
60
61 export function makeResolver(moduleName: string, contextRequire: Require) {
62 const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
63
64 const resolver = new ModuleResolver(contextRequire, base);
65 return (id: string) => resolver.resolve(id);
66 }
@@ -0,0 +1,44
1 import { TraceSource } from "./TraceSource";
2 import { Predicate } from "../interfaces";
3
4 export = {
5 on(filter: any , cb: any) {
6 if (arguments.length === 1) {
7 cb = filter;
8 filter = undefined;
9 }
10 let test: Predicate<string>;
11 if (filter instanceof RegExp) {
12 test = chId => filter.test(chId);
13 } else if (filter instanceof Function) {
14 test = filter;
15 } else if (filter) {
16 test = chId => chId === filter;
17 }
18
19 if (test) {
20 TraceSource.on(source => {
21 if (test(source.id))
22 source.events.on(cb);
23 });
24 } else {
25 TraceSource.on(source => {
26 source.events.on(cb);
27 });
28 }
29 },
30
31 load(id: string, require: any, cb: (trace: TraceSource) => void) {
32 if (id) {
33 cb(TraceSource.get(id));
34 } else if (require.module && require.module.mid) {
35 cb(TraceSource.get(require.module.mid));
36 } else {
37 require(["module"], (module: { id: any; }) => {
38 cb(TraceSource.get(module && module.id));
39 });
40 }
41 },
42
43 dynamic: true
44 };
@@ -0,0 +1,104
1 import { format } from "./StringFormat";
2 import { TraceSource, DebugLevel } from "../log/TraceSource";
3 import { ITemplateParser, TokenType } from "./TemplateParser";
4 import m = require("module");
5
6 const trace = TraceSource.get(m.id);
7
8 type TemplateFn = (obj: object) => string;
9
10 export class TemplateCompiler {
11
12 _data: string[];
13 _code: string[];
14 _wrapWith = true;
15
16 constructor() {
17 this._code = [];
18 this._data = [];
19 }
20
21 compile(parser: ITemplateParser): TemplateFn {
22 this.preamble();
23 this.visitTemplate(parser);
24 this.postamble();
25
26 const text = this._code.join("\n");
27
28 try {
29 // tslint:disable-next-line:function-constructor
30 const compiled = new Function("obj, format, $data", text);
31 /**
32 * Функция форматирования по шаблону
33 *
34 * @type{Function}
35 * @param{Object} obj объект с параметрами для подстановки
36 */
37 return (obj: object) => compiled(obj || {}, format, this._data);
38 } catch (e) {
39 trace.traceEvent(DebugLevel, [e, text, this._data]);
40 throw e;
41 }
42 }
43
44 preamble() {
45 this._code.push(
46 "var $p = [];",
47 "var print = function(){",
48 " $p.push(format.apply(null,arguments));",
49 "};"
50 );
51
52 if (this._wrapWith)
53 this._code.push("with(obj){");
54 }
55
56 postamble() {
57 if (this._wrapWith)
58 this._code.push("}");
59
60 this._code.push("return $p.join('');");
61 }
62
63 visitTemplate(parser: ITemplateParser) {
64 while (parser.next()) {
65 switch (parser.token()) {
66 case TokenType.OpenBlock:
67 this.visitCode(parser);
68 break;
69 case TokenType.OpenInlineBlock:
70 this.visitInline(parser);
71 break;
72 default:
73 this.visitTextFragment(parser);
74 break;
75 }
76 }
77 }
78
79 visitInline(parser: ITemplateParser) {
80 const code = ["$p.push("];
81 while (parser.next()) {
82 if (parser.token() === TokenType.CloseBlock)
83 break;
84 code.push(parser.value());
85 }
86 code.push(");");
87 this._code.push(code.join(""));
88 }
89
90 visitCode(parser: ITemplateParser) {
91 const code = [];
92 while (parser.next()) {
93 if (parser.token() === TokenType.CloseBlock)
94 break;
95 code.push(parser.value());
96 }
97 this._code.push(code.join(""));
98 }
99
100 visitTextFragment(parser: ITemplateParser) {
101 const i = this._data.push(parser.value());
102 this._code.push("$p.push($data[" + i + "]);");
103 }
104 }
@@ -0,0 +1,64
1 import { argumentNotEmptyString } from "../safe";
2 import { MapOf } from "../interfaces";
3
4 const splitRx = /(<%=|\[%=|<%|\[%|%\]|%>)/;
5
6 export enum TokenType {
7 None,
8 Text,
9 OpenInlineBlock,
10 OpenBlock,
11 CloseBlock
12 }
13
14 const tokenMap: MapOf<TokenType> = {
15 "<%": TokenType.OpenBlock,
16 "[%": TokenType.OpenBlock,
17 "<%=": TokenType.OpenInlineBlock,
18 "[%=": TokenType.OpenInlineBlock,
19 "%>": TokenType.CloseBlock,
20 "%]": TokenType.CloseBlock
21 };
22
23 export interface ITemplateParser {
24 next(): boolean;
25 token(): TokenType;
26 value(): string;
27 }
28
29 export class TemplateParser implements ITemplateParser {
30
31 _tokens: string[];
32 _pos = -1;
33 _type: TokenType;
34 _value: string;
35
36 constructor(text: string) {
37 argumentNotEmptyString(text, "text");
38
39 this._tokens = text.split(splitRx);
40 this._type = TokenType.None;
41 }
42
43 next() {
44 this._pos++;
45 if (this._pos < this._tokens.length) {
46 this._value = this._tokens[this._pos];
47 this._type = tokenMap[this._value] || TokenType.Text;
48 return true;
49 } else {
50 this._type = TokenType.None;
51 this._value = undefined;
52 return false;
53 }
54 }
55
56 token() {
57 return this._type;
58 }
59
60 value() {
61 return this._value;
62 }
63
64 }
@@ -0,0 +1,33
1 import { argumentNotEmptyString } from "../safe";
2 import { TraceSource } from "../log/TraceSource";
3
4 const trace = TraceSource.get(module.id);
5
6 const mainModule = require.main;
7 const mainRequire = (id: string) => mainModule.require(id);
8
9 class ModuleResolver {
10 _base: string;
11 _require: NodeRequireFunction;
12
13 constructor(req: NodeRequireFunction, base?: string) {
14 this._base = base;
15 this._require = (req || mainRequire).bind(null);
16 }
17
18 resolve(moduleName: string) {
19 argumentNotEmptyString(moduleName, "moduleName");
20 const resolvedName = moduleName[0] === "." && this._base ? [this._base, moduleName].join("/") : moduleName;
21
22 trace.debug(`${moduleName} -> ${resolvedName}`);
23
24 return this._require(resolvedName);
25 }
26 }
27
28 export function makeResolver(moduleName: string, contextRequire: NodeRequireFunction) {
29 const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
30
31 const resolver = new ModuleResolver(contextRequire, base);
32 return (id: string) => resolver.resolve(id);
33 }
@@ -0,0 +1,3
1 import { ModuleResolver } from "./Configuration";
2
3 export declare function makeResolver(moduleName?: string, contextRequire?: any): ModuleResolver; No newline at end of file
@@ -0,0 +1,33
1 import { ICancellation } from "../interfaces";
2
3 /** interface for message consumers, used to recieve messages from a single endpoint.
4 */
5 export interface IConsumer<T> {
6 /** Reads the next message from the destination for which the consumer was created.
7 * @param options A provider specific options.
8 * @param ct The cancellation token for this operation.
9 * @returns A recieved message or a promise. If message is prefetched it will
10 * be returned immediately, otherwise a promise is returned.
11 */
12 read(options?: object, ct?: ICancellation): T | Promise<T>;
13 }
14
15 /** Interface for message produsers, used to send messages to the endpoints.
16 * The producer can be bound to the particular destination or a destination
17 * can be specified as an additional option during post if supported.
18 */
19 export interface IProducer<T> {
20 /** Sends a message
21 * @param msg The message to send.
22 * @param options A provider specific options
23 * @param ct The cancellation token for this operation
24 */
25 post(msg: T, options?: object, ct?: ICancellation): void | Promise<void>;
26 }
27
28 export interface ISession {
29 start(ct: ICancellation): void;
30
31 createConsumer<T = any>(destination: string, options?: object): IConsumer<T>;
32 createProducer<T = any>(destination: string, options?: object): IProducer<T>;
33 }
@@ -0,0 +1,24
1 {
2 "name": "${packageName}",
3 "version": "${version}",
4 "description": "${description}",
5 "main": "main.js",
6 "keywords": [
7 "di",
8 "ioc",
9 "logging",
10 "template engine",
11 "dependency injection"
12 ],
13 "author": "${author}",
14 "license": "${license}",
15 "repository": "$repository",
16 "publishConfig": {
17 "access": "public"
18 },
19 "peerDependencies": {
20 "dojo": "^1.10.0"
21 },
22 "module": "${jsmodule}",
23 "target": "${target}"
24 } No newline at end of file
@@ -0,0 +1,21
1 {
2 "name": "${packageName}",
3 "version": "${version}",
4 "description": "${description}",
5 "main": "main.js",
6 "keywords": [
7 "di",
8 "ioc",
9 "logging",
10 "template engine",
11 "dependency injection"
12 ],
13 "author": "${author}",
14 "license": "${license}",
15 "repository": "$repository",
16 "publishConfig": {
17 "access": "public"
18 },
19 "module": "${jsmodule}",
20 "target": "${target}"
21 } No newline at end of file
@@ -0,0 +1,7
1 define(["tape", "core/Uuid"], function(tape, Uuid) {
2 "use strict";
3 tape('uuid', function(t) {
4 t.notEqual(Uuid(),Uuid());
5 t.end();
6 });
7 }); No newline at end of file
@@ -0,0 +1,20
1 define({
2 foo: {
3 $type: "./Foo:Foo"
4 },
5
6 bar: {
7 $type: "./Bar:Bar",
8 params: {
9 db: {
10 provider: {
11 $dependency: "db"
12 }
13 },
14 foo: {
15 $type: "./Foo:Foo"
16 }
17 }
18 },
19 db: "db://localhost"
20 }); No newline at end of file
@@ -0,0 +1,8
1 define([
2 "./ActivatableTests",
3 "./trace-test",
4 "./TraceSourceTests",
5 "./CancellationTests",
6 "./ObservableTests",
7 "./ContainerTests"
8 ]); No newline at end of file
@@ -0,0 +1,22
1 var rjs = require('requirejs');
2
3 rjs.config({
4 baseUrl: '.',
5 packages: [{
6 name: "@implab/core",
7 location: "build/dist"
8 },
9 {
10 name: "test",
11 location: "build/test"
12 },
13 {
14 name: "dojo",
15 location: "node_modules/dojo"
16 }
17 ],
18 nodeRequire: require
19 });
20
21
22 rjs(['test/plan']); No newline at end of file
@@ -0,0 +1,30
1 define(["tape"], function(tape) {
2 "use strict";
3 var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
4 var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
5 tape('Load TraceSource for the module', function(t) {
6 require(["@implab/core/log/trace!" + sourceId, "@implab/core/log/TraceSource"], function(trace, TraceSource_1) {
7 var TraceSource = TraceSource_1.TraceSource;
8 t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
9
10 var count = 0;
11
12 var h = TraceSource.on(function(x) {
13 if(x.id == sourceId || x.id == sourceId2)
14 count++;
15 });
16
17 t.equal(count, 1, "should see created channel immediatelly");
18 t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
19 t.equal(count, 1);
20
21 TraceSource.get(sourceId2);
22
23 t.equal(count, 2);
24
25 h.destroy();
26
27 t.end();
28 });
29 });
30 }); No newline at end of file
@@ -0,0 +1,22
1 {
2 "extends": "../tsconfig",
3 "compilerOptions": {
4 "rootDir": "ts",
5 "baseUrl": ".",
6 "paths": {
7 "@implab/core/*": [
8 "../../build/dist/*"
9 ]
10 },
11 "types": [
12 "requirejs"
13 ],
14 "rootDirs": [
15 "ts",
16 "../typings/test"
17 ]
18 },
19 "include" : [
20 "ts/**/*.ts"
21 ]
22 } No newline at end of file
@@ -5,41 +5,128 if (release != 'rtm') {
5 5 if(!npmName)
6 6 npmName = name;
7 7
8 if(!["amd", "cjs"].contains(platform))
9 throw new Exception("Invalid platform specified: $platform");
8 if(!["amd", "commonjs", "system", "umd", "es6", "esnext"].contains(jsmodule))
9 throw new Exception("Invalid jsmodule specified: $jsmodule");
10 if(!["es3", "es5", "es6", "es2016", "es2017", "esnext"].contains(target))
11 throw new Exception("Invalid target specified: $target")
10 12
11 def moduleTypes = [
12 "amd": "amd",
13 "cjs": "commonjs"
14 ]
13 def targetLibs = [
14 "es3" : "es5,es2015.promise,es2015.symbol,dom,scripthost",
15 "es5" : "es5,es2015.promise,es2015.symbol,dom,scripthost"
16 ];
15 17
16 ext.packageName="$npmScope/$npmName-$platform";
18 ext.packageName="$npmScope/$npmName";
17 19
18 20 def srcDir = "$projectDir/src"
19 21 def typingsDir = "$srcDir/typings"
20 def distDir = "$buildDir/dist/$platform"
21 def testDir = "$buildDir/test/$platform"
22 def moduleType = moduleTypes[platform]
22 def distDir = "$buildDir/dist"
23 def testDir = "$buildDir/test"
24 def lib = targetLibs[target] ?: "${target},dom";
25
26 println "lib: $lib";
27
28 def sourceSets = ["main", "amd", "cjs"];
29 def testSets = ["test", "testAmd", "testCjs"];
30
31 task beforeBuild {
32 }
33
34 def createSoursetTasks = { String name, String outDir ->
35 def setName = name.capitalize();
36
37 def destDir = "$buildDir/compile/$name"
38 def declDir = "$typingsDir/$name"
39 def setDir = "$projectDir/src/$name"
40
41 def beforeBuildTask = task "beforeBuild$setName"(dependsOn: beforeBuild) {
42 }
43
44 def copyJsTask = task "copyJs$setName"(dependsOn: beforeBuildTask, type: Copy) {
45 from "$setDir/js"
46 into outDir
47 }
48
49 def compileTypingsTask = task "compileTypings$setName"(dependsOn: beforeBuildTask, type: Exec) {
50 inputs.dir("$setDir/ts")
51 inputs.file("$srcDir/tsconfig.json")
52 inputs.file("$setDir/tsconfig.json")
53 outputs.dir(declDir)
23 54
24 def sourceSets = ["main", "amd", "cjs", "test"];
55 commandLine 'node_modules/.bin/tsc',
56 '-p', "$setDir/tsconfig.json",
57 '-t', target,
58 '-m', jsmodule,
59 '-d',
60 '--emitDeclarationOnly',
61 '--declarationDir', declDir
62
63 if (lib)
64 args '--lib', lib
65 }
66
67 def compileTsTask = task "compileTs$setName"(dependsOn: beforeBuildTask, type: Exec) {
68 inputs.dir("$setDir/ts")
69 inputs.file("$srcDir/tsconfig.json")
70 inputs.file("$setDir/tsconfig.json")
71 outputs.dir(destDir)
72
73 commandLine 'node_modules/.bin/tsc',
74 '-p', "$setDir/tsconfig.json",
75 '-t', target,
76 '-m', jsmodule,
77 '--outDir', destDir
78
79 if (lib)
80 args '--lib', lib
81 }
82
83 def copyTsOutputTask = task "copyTsOutput$setName"(dependsOn: compileTsTask, type: Copy) {
84 from compileTsTask
85 into outDir
86 }
87
88 def copyTypingsTask = task "copyTypings$setName"(dependsOn: compileTypingsTask, type: Copy) {
89 from compileTypingsTask
90 into outDir
91 }
92
93 task "build$setName"(dependsOn: [copyTypingsTask, copyTsOutputTask, copyJsTask]) {
94 }
95 }
25 96
26 97 task printVersion {
27 98 doLast {
28 99 println "version: $version"
29 100 println "packageName: $packageName"
30 println "platform: $platform"
31 println "module: $moduleType"
101 println "target: $target"
102 println "module: $jsmodule"
32 103 }
33 104 }
34 105
35 106 task clean {
36 107 doLast {
37 108 delete buildDir
38 delete "node_modules/$packageName"
39 109 delete typingsDir
40 110 }
41 111 }
42 112
113 task _initBuild {
114 mustRunAfter clean
115
116 def buildInfoFile = "$buildDir/platform";
117 inputs.property('target',target);
118 inputs.property('jsmodule',jsmodule);
119 outputs.file(buildInfoFile);
120
121 doLast {
122 delete buildDir
123 mkdir buildDir
124
125 def f = new File(buildInfoFile);
126 f << "$target-$jsmodule";
127 }
128 }
129
43 130 task cleanNpm {
44 131 doLast {
45 132 delete 'node_modules'
@@ -56,78 +143,55 task _npmInstall() {
56 143 }
57 144 }
58 145
59 sourceSets.each {
60 def setName = it.capitalize();
61
62 def destDir = "$buildDir/compile/$it"
63 def declDir = "$typingsDir/$it"
64 def setDir = "$projectDir/src/$it"
65
66 task "_copyJs$setName"(type:Copy) {
67 from "$setDir/js"
68 into distDir
69 }
146 beforeBuild {
147 dependsOn _initBuild
148 dependsOn _npmInstall
149 }
70 150
71 task "_compileTs$setName"(dependsOn: _npmInstall, type:Exec) {
72 inputs.dir("$setDir/ts")
73 inputs.file("$srcDir/tsconfig.json")
74 inputs.file("$setDir/tsconfig.json")
75 outputs.dir(destDir)
76 outputs.dir(declDir)
151 sourceSets.each { createSoursetTasks(it, distDir) }
77 152
78 commandLine 'node_modules/.bin/tsc',
79 '-p', "$setDir/tsconfig.json",
80 '-m', moduleType,
81 '--outDir', destDir,
82 '--declarationDir', declDir
83 }
153 testSets.each { createSoursetTasks(it, testDir) }
84 154
85 task "_buildTs$setName"(dependsOn: "_compileTs$setName", type:Copy) {
86 from tasks.getByPath("_compileTs$setName");
87 into distDir
88 }
155 compileTsAmd {
156 dependsOn compileTypingsMain
89 157 }
90 158
91 _compileTsAmd {
92 dependsOn _buildTsMain
159 compileTypingsAmd {
160 dependsOn compileTypingsMain
161 }
162
163 task build(dependsOn: buildMain) {
164 if (jsmodule == "amd")
165 dependsOn buildAmd
93 166 }
94 167
95 _buildTsTest {
96 into testDir
168 compileTsTest {
169 dependsOn build
97 170 }
98 171
99 _copyJsTest {
100 into testDir
172 compileTsTestAmd {
173 dependsOn compileTypingsTestAmd
174 }
175
176 task test(dependsOn: [buildTest, buildTestAmd], type: Exec) {
177 commandLine 'node', "$testDir/run-amd-tests.js"
101 178 }
102 179
103 180 task _packageMeta(type: Copy) {
181 mustRunAfter build
182
104 183 inputs.property("version", version)
105 184 from('.') {
106 185 include '.npmignore', 'readme.md', 'license', 'history.md'
107 186 }
108 from("$srcDir/package.template.json") {
187 from("$srcDir/package.${jsmodule}.tmpl.json") {
109 188 expand project.properties
110 189 rename { "package.json" }
111 190 }
112 191 into distDir
113 192 }
114 193
115 task build(dependsOn: [_copyJsMain, _copyJsAmd, _npmInstall, _buildTsMain, _buildTsAmd, _packageMeta]) {
116
117 }
118
119 _compileTsTest {
120 dependsOn build
121 }
122
123 task buildTests(dependsOn: [_copyJsTest, _buildTsTest]) {
124 }
125
126 task test(dependsOn: buildTests, type: Exec) {
127 commandLine 'node', "$testDir/run-amd-tests.js"
128 }
129
130 task pack(dependsOn: build, type: Exec) {
194 task pack(dependsOn: [build, _packageMeta], type: Exec) {
131 195 workingDir distDir
132 196
133 197 commandLine 'npm', 'pack'
@@ -119,18 +119,14 let msg = await pushEvents.next();
119 119
120 120 class Map {
121 121 /**
122
123 122 Получает координаты по щелчку мыши.
124
125 123 @async
126
127 124 @returns [lon,lat]
128
129 125 */
130 126 async peekCoordinates(ct: ICancellation = Cancellation.none) {
131 127 // получаем событие клика
132 128 let evt = this.viewport.click.next(ct);
133
129
134 130 // преобразуем позицию на экране в координаты карты
135 131 return this.clientToCoodinates([evt.clientx,evt.clientY]);
136 132 }
@@ -1,7 +1,8
1 1 version=1.2.0
2 2 release=rc
3 3 author=Implab team
4 platform=amd
4 jsmodule=amd
5 target=es5
5 6 description=Dependency injection, logging, simple and fast text template engine
6 7 license=BSD-2-Clause
7 8 repository=https://bitbucket.org/implab/implabjs
@@ -1,12 +1,20
1 1 HISTORY
2 2 =======
3 3
4 1.2.0
5 -----
6
7 Major rafactoring, moving to support browser (rjs) and server (cjs) environments.
8
9 - dependency injection container ported to typescript
10 - sources are split to several sets to provide the ability for the conditional build of the project.
11
4 12 1.0.1
5 13 -----
6 14
7 First release, intorduces the followinf features
15 First release, intorduces the following features
8 16
9 - `di` - dependency injection conyainer
17 - `di` - dependency injection container
10 18 - `log` - log4 style logging system
11 19 - `text` - simple and fast text templating and formatting
12 20 - `Uuid` - uuid generation traits No newline at end of file
@@ -5,9 +5,9
5 5 "requires": true,
6 6 "dependencies": {
7 7 "@types/node": {
8 "version": "10.12.15",
9 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz",
10 "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==",
8 "version": "10.12.18",
9 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
10 "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
11 11 "dev": true
12 12 },
13 13 "@types/requirejs": {
@@ -17,9 +17,9
17 17 "dev": true
18 18 },
19 19 "@types/tape": {
20 "version": "4.2.32",
21 "resolved": "http://registry.npmjs.org/@types/tape/-/tape-4.2.32.tgz",
22 "integrity": "sha512-xil0KO5wkPoixdBWGIGolPv9dekf6dVkjjJLAFYchfKcd4DICou67rgGCIO7wAh3i5Ff/6j9IDgZz+GU9cMaqQ==",
20 "version": "4.2.33",
21 "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
22 "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
23 23 "dev": true,
24 24 "requires": {
25 25 "@types/node": "*"
@@ -95,16 +95,25
95 95 "dev": true
96 96 },
97 97 "es-abstract": {
98 "version": "1.12.0",
99 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
100 "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
98 "version": "1.13.0",
99 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
100 "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
101 101 "dev": true,
102 102 "requires": {
103 "es-to-primitive": "^1.1.1",
103 "es-to-primitive": "^1.2.0",
104 104 "function-bind": "^1.1.1",
105 "has": "^1.0.1",
106 "is-callable": "^1.1.3",
107 "is-regex": "^1.0.4"
105 "has": "^1.0.3",
106 "is-callable": "^1.1.4",
107 "is-regex": "^1.0.4",
108 "object-keys": "^1.0.12"
109 },
110 "dependencies": {
111 "object-keys": {
112 "version": "1.0.12",
113 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
114 "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
115 "dev": true
116 }
108 117 }
109 118 },
110 119 "es-to-primitive": {
@@ -375,9 +384,9
375 384 }
376 385 },
377 386 "tape": {
378 "version": "4.9.1",
379 "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz",
380 "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==",
387 "version": "4.9.2",
388 "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz",
389 "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==",
381 390 "dev": true,
382 391 "requires": {
383 392 "deep-equal": "~1.0.1",
@@ -21,15 +21,15
21 21 "tslib": "latest"
22 22 },
23 23 "devDependencies": {
24 "typescript": "latest",
25 "tape": "latest",
26 "@types/tape": "latest",
24 "@types/node": "latest",
27 25 "@types/requirejs": "latest",
28 "@types/node": "latest",
29 "requirejs": "latest",
26 "@types/tape": "latest",
27 "dojo": "^1.10.0",
30 28 "faucet": "latest",
31 "dojo": "^1.10.0",
32 "tslib": "latest"
29 "requirejs": "latest",
30 "tape": "^4.9.2",
31 "tslib": "latest",
32 "typescript": "latest"
33 33 },
34 34 "types": "main.d.ts"
35 35 }
@@ -1,95 +1,97
1 define(
2 [ "./declare" ],
3 function(declare) {
4 function parseURI(uri) {
5 var schema, host, port, path, query, hash, i;
6 if (typeof (uri) == "string") {
7 if ((i = uri.indexOf(":")) >= 0 &&
8 uri.substr(0, i).match(/^\w+$/)) {
9 schema = uri.substr(0, i);
10 uri = uri.substr(i + 1);
11 }
1 define(["./declare", "./log/trace!"], function (declare, trace) {
2 trace.warn("THIS MODULE IS DEPRECATED! use uri-js or similar alternatives.");
3
4 function parseURI(uri) {
5 var schema, host, port, path, query, hash, i;
6 if (typeof (uri) == "string") {
7 if ((i = uri.indexOf(":")) >= 0 &&
8 uri.substr(0, i).match(/^\w+$/)) {
9 schema = uri.substr(0, i);
10 uri = uri.substr(i + 1);
11 }
12 12
13 if (uri.indexOf("//") === 0) {
14 uri = uri.substr(2);
15 if ((i = uri.indexOf("/")) >= 0) {
16 host = uri.substr(0, i);
17 uri = uri.substr(i);
18 } else {
19 host = uri;
20 uri = "";
21 }
13 if (uri.indexOf("//") === 0) {
14 uri = uri.substr(2);
15 if ((i = uri.indexOf("/")) >= 0) {
16 host = uri.substr(0, i);
17 uri = uri.substr(i);
18 } else {
19 host = uri;
20 uri = "";
22 21 }
23
24 if ((i = uri.indexOf("?")) >= 0) {
25 path = uri.substr(0, i);
26 uri = uri.substr(i + 1);
22 }
27 23
28 } else {
29 path = uri;
30 uri = "";
24 if ((i = uri.indexOf("?")) >= 0) {
25 path = uri.substr(0, i);
26 uri = uri.substr(i + 1);
31 27
32 if ((i = path.indexOf("#")) >= 0) {
33 hash = path.substr(i + 1);
34 path = path.substr(0, i);
35 }
36 }
28 } else {
29 path = uri;
30 uri = "";
37 31
38 if ((i = uri.indexOf("#")) >= 0) {
39 query = uri.substr(0, i);
40 hash = uri.substr(i + 1);
41 } else {
42 query = uri;
32 if ((i = path.indexOf("#")) >= 0) {
33 hash = path.substr(i + 1);
34 path = path.substr(0, i);
43 35 }
44 36 }
45 37
46 if (host && (i = host.lastIndexOf(":")) >= 0) {
47 port = host.substr(i + 1);
48 host = host.substr(0, i);
38 if ((i = uri.indexOf("#")) >= 0) {
39 query = uri.substr(0, i);
40 hash = uri.substr(i + 1);
41 } else {
42 query = uri;
49 43 }
44 }
50 45
51 return {
52 schema : schema,
53 host : host,
54 port : port,
55 path : path,
56 query : query,
57 hash : hash
58 };
46 if (host && (i = host.lastIndexOf(":")) >= 0) {
47 port = host.substr(i + 1);
48 host = host.substr(0, i);
59 49 }
60 50
61 function makeURI(options) {
62 var uri = [];
51 return {
52 schema: schema,
53 host: host,
54 port: port,
55 path: path,
56 query: query,
57 hash: hash
58 };
59 }
63 60
64 if (options.schema)
65 uri.push(options.schema, ":");
66 if (options.host)
67 uri.push("//", options.host);
68 if (options.host && options.port)
69 uri.push(":", options.port);
61 function makeURI(options) {
62 var uri = [];
70 63
71 if (options.path) {
72 if (options.host && options.path[0] != "/")
73 uri.push("/");
74 uri.push(options.path);
75 } else if (options.host) {
64 if (options.schema)
65 uri.push(options.schema, ":");
66 if (options.host)
67 uri.push("//", options.host);
68 if (options.host && options.port)
69 uri.push(":", options.port);
70
71 if (options.path) {
72 if (options.host && options.path[0] != "/")
76 73 uri.push("/");
77 }
78
79 if (options.query)
80 uri.push("?", options.query);
81 if (options.hash)
82 uri.push("#", options.hash);
83
84 return uri.join("");
74 uri.push(options.path);
75 } else if (options.host) {
76 uri.push("/");
85 77 }
86 78
87 function reducePath(parts) {
88 var balance = 0, result = [], isRoot;
79 if (options.query)
80 uri.push("?", options.query);
81 if (options.hash)
82 uri.push("#", options.hash);
83
84 return uri.join("");
85 }
89 86
90 for (var i = 0; i < parts.length; i++) {
91 var part = parts[i];
92 switch (part) {
87 function reducePath(parts) {
88 var balance = 0,
89 result = [],
90 isRoot;
91
92 for (var i = 0; i < parts.length; i++) {
93 var part = parts[i];
94 switch (part) {
93 95 case "..":
94 96 if (balance > 0) {
95 97 result.pop();
@@ -113,120 +115,122 define(
113 115 result.push(part);
114 116 balance++;
115 117 break;
116 }
117 118 }
118
119 return result.join("/");
120 119 }
121 120
122 var meta = {
123 schema : null,
124 host : null,
125 port : null,
126 path : null,
127 query : null,
128 hash : null
129 };
130
131 var URI = declare(null, {
132 constructor : function(opts) {
133 if (typeof (opts) == "string")
134 opts = parseURI(opts);
135 for ( var p in meta)
136 if (p in opts)
137 this[p] = opts[p];
138 },
139
140 clone : function() {
141 return new URI(this);
142 },
121 return result.join("/");
122 }
143 123
144 combine : function(rel) {
145 var me = this;
146
147 if (typeof (rel) === "string")
148 rel = new URI(rel);
149 else
150 rel = rel.clone();
151
152 // //some.host:123/path?q=a#123
153 if (rel.host)
154 return rel;
124 var meta = {
125 schema: null,
126 host: null,
127 port: null,
128 path: null,
129 query: null,
130 hash: null
131 };
155 132
156 // /abs/path?q=a#123
157 if (rel.path && rel.path[0] == "/") {
158 if (me.host) {
159 rel.schema = me.schema;
160 rel.host = me.host;
161 rel.port = me.port;
162 }
163 return rel;
164 }
165
166 var base = me.clone();
133 var URI = declare(null, {
134 constructor: function (opts) {
135 trace.warn("This class is deprecated use uri-js or similar");
136 if (typeof (opts) == "string")
137 opts = parseURI(opts);
138 for (var p in meta)
139 if (p in opts)
140 this[p] = opts[p];
141 },
167 142
168 // rel/path?a=b#cd
169 if (rel.path) {
170 var segments = base.getSegments();
171 segments.pop();
172 segments.push.apply(segments, rel.getSegments());
173
174 base.path = reducePath(segments);
175 }
143 clone: function () {
144 return new URI(this);
145 },
176 146
177 // ?q=a#123
178 if (rel.query)
179 base.query = rel.query;
180 if (rel.hash)
181 base.hase = rel.hash;
147 combine: function (rel) {
148 var me = this;
182 149
183 return base;
184 },
185
186 optimize : function() {
187 this.path = reducePath(this.getSegments());
188 },
150 if (typeof (rel) === "string")
151 rel = new URI(rel);
152 else
153 rel = rel.clone();
189 154
190 getSegments : function() {
191 if (typeof (this.path) === "string")
192 return this.path.split("/");
193 else
194 return [];
195 },
196
197 toString : function() {
198 var uri = [], me = this;
155 // //some.host:123/path?q=a#123
156 if (rel.host)
157 return rel;
199 158
200 if (me.schema)
201 uri.push(me.schema, ":");
202 if (me.host)
203 uri.push("//", me.host);
204 if (me.host && me.port)
205 uri.push(":", me.port);
206
207 if (me.path) {
208 if (me.host && me.path[0] != "/")
209 uri.push("/");
210 uri.push(me.path);
211 } else if (me.host) {
212 uri.push("/");
159 // /abs/path?q=a#123
160 if (rel.path && rel.path[0] == "/") {
161 if (me.host) {
162 rel.schema = me.schema;
163 rel.host = me.host;
164 rel.port = me.port;
213 165 }
214
215 if (me.query)
216 uri.push("?", me.query);
217 if (me.hash)
218 uri.push("#", me.hash);
219
220 return uri.join("");
166 return rel;
221 167 }
222 168
223 });
169 var base = me.clone();
170
171 // rel/path?a=b#cd
172 if (rel.path) {
173 var segments = base.getSegments();
174 segments.pop();
175 segments.push.apply(segments, rel.getSegments());
176
177 base.path = reducePath(segments);
178 }
179
180 // ?q=a#123
181 if (rel.query)
182 base.query = rel.query;
183 if (rel.hash)
184 base.hase = rel.hash;
185
186 return base;
187 },
188
189 optimize: function () {
190 this.path = reducePath(this.getSegments());
191 },
192
193 getSegments: function () {
194 if (typeof (this.path) === "string")
195 return this.path.split("/");
196 else
197 return [];
198 },
224 199
225 URI.combine = function(base, rel) {
226 if (typeof (base) === "string")
227 base = new URI(base);
228 return base.combine(rel).toString();
229 };
200 toString: function () {
201 var uri = [],
202 me = this;
203
204 if (me.schema)
205 uri.push(me.schema, ":");
206 if (me.host)
207 uri.push("//", me.host);
208 if (me.host && me.port)
209 uri.push(":", me.port);
210
211 if (me.path) {
212 if (me.host && me.path[0] != "/")
213 uri.push("/");
214 uri.push(me.path);
215 } else if (me.host) {
216 uri.push("/");
217 }
230 218
231 return URI;
232 }); No newline at end of file
219 if (me.query)
220 uri.push("?", me.query);
221 if (me.hash)
222 uri.push("#", me.hash);
223
224 return uri.join("");
225 }
226
227 });
228
229 URI.combine = function (base, rel) {
230 if (typeof (base) === "string")
231 base = new URI(base);
232 return base.combine(rel).toString();
233 };
234
235 return URI;
236 }); No newline at end of file
@@ -1,217 +1,215
1 define(
2 [
3 "dojo/_base/declare",
4 "dojo/_base/lang",
5 "dojo/request",
6 "./Destination",
7 "dojo/Evented",
8 "dojo/Deferred",
9 "../log/_LogMixin" ],
10
11 function(declare, lang, request, Destination, Evented, Deferred, _LogMixin) {
1 define([
2 "dojo/_base/declare",
3 "dojo/request",
4 "./Destination",
5 "dojo/Evented",
6 "dojo/Deferred",
7 "../log/_LogMixin"
8 ], function (declare, request, Destination, Evented, Deferred, _LogMixin) {
12 9
13 var cls = declare(
14 [ Evented, _LogMixin ],
15 {
16 _id : null,
17 _baseUrl : null,
18 _destinations : null,
19 _timeout : 100000,
20 _clients : null,
21 _started : null,
22 _starting : false,
10 var cls = declare(
11 [Evented, _LogMixin], {
12 _id: null,
13 _baseUrl: null,
14 _destinations: null,
15 _timeout: 100000,
16 _clients: null,
17 _started: null,
18 _starting: false,
23 19
24 constructor : function(baseUrl, options) {
25 if (!baseUrl)
26 throw new Error("baseUrl is required");
27 options = options || {};
20 constructor: function (baseUrl, options) {
21 if (!baseUrl)
22 throw new Error("baseUrl is required");
23 options = options || {};
28 24
29 this._baseUrl = baseUrl.replace(/\/*$/, "");
30 this._destinations = {};
31 this._pending = [];
32 this._clients = {};
33 if (options.timeout)
34 this._timeout = options.timeout;
25 this._baseUrl = baseUrl.replace(/\/*$/, "");
26 this._destinations = {};
27 this._pending = [];
28 this._clients = {};
29 if (options.timeout)
30 this._timeout = options.timeout;
35 31
36 this._started = new Deferred();
37 },
38
39 start : function() {
40 if (this._starting)
41 return this._started;
42 this._starting = true;
32 this._started = new Deferred();
33 },
43 34
44 var me = this;
45 me.log("START");
46 request(this._baseUrl, {
47 method : "POST",
48 handleAs : "json"
49 }).then(function(result) {
50 me._id = result;
51 me._emitConnected();
52 me._poll();
53 me._started.resolve(me);
54 }, function(error) {
55 me._emitError(error);
56 me._started.reject(me);
57 });
58 return me._started.promise;
59 },
60
61 createClient : function(options) {
62 if (!options || !options.destination || !options.mode)
63 throw new Error("Invalid argument");
64
65 var me = this;
66
67 return me._started
68 .then(function() {
69 var url = me._makeUrl(me._id);
70 me.log(
71 "CREATE mode=${0}, destination=${1}",
72 options.mode,
73 options.destination);
35 start: function () {
36 if (this._starting)
37 return this._started;
38 this._starting = true;
74 39
75 return request(url, {
76 method : "POST",
77 data : {
78 mode : options.mode,
79 destination : options.destination
80 },
81 handleAs : 'json'
82 })
83 .then(
84 function(id) {
85 me
86 .log(
87 "CLIENT id=${0}, mode=${1}, destination=${2}",
88 id,
89 options.mode,
90 options.destination);
91 me._clients[id] = options.client
92 ? options.client
93 : function(msg) {
94 me
95 .warn(
96 "The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
97 id,
98 options.mode,
99 options.destination);
100 };
101 return id;
102 });
103 });
40 var me = this;
41 me.log("START");
42 request(this._baseUrl, {
43 method: "POST",
44 handleAs: "json"
45 }).then(function (result) {
46 me._id = result;
47 me._emitConnected();
48 me._poll();
49 me._started.resolve(me);
50 }, function (error) {
51 me._emitError(error);
52 me._started.reject(me);
53 });
54 return me._started.promise;
55 },
104 56
105 },
57 createClient: function (options) {
58 if (!options || !options.destination || !options.mode)
59 throw new Error("Invalid argument");
106 60
107 deleteClient : function(options) {
108 if (!options || !options.clientId)
109 throw new Error("Invalid argument");
61 var me = this;
110 62
111 var me = this, id = options.clientId;
112
113 return me._started.then(function() {
114 var url = me._makeUrl(me._id, options.clientId);
115
116 me.log("DELETE CLIENT ${0}", options.clientId);
63 return me._started
64 .then(function () {
65 var url = me._makeUrl(me._id);
66 me.log(
67 "CREATE mode=${0}, destination=${1}",
68 options.mode,
69 options.destination);
117 70
118 71 return request(url, {
119 method : "DELETE",
120 handleAs : 'json'
121 }).then(function() {
122 me.log("CLIENT DELETED ${0}", options.clientId);
123 me._clients[id] = undefined;
124 });
72 method: "POST",
73 data: {
74 mode: options.mode,
75 destination: options.destination
76 },
77 handleAs: 'json'
78 })
79 .then(
80 function (id) {
81 me
82 .log(
83 "CLIENT id=${0}, mode=${1}, destination=${2}",
84 id,
85 options.mode,
86 options.destination);
87 me._clients[id] = options.client ?
88 options.client :
89 function (msg) {
90 me
91 .warn(
92 "The client id=${0}, mode=${1}, destination=${2} isn't accepting mesages",
93 id,
94 options.mode,
95 options.destination);
96 };
97 return id;
98 });
125 99 });
126 },
100
101 },
102
103 deleteClient: function (options) {
104 if (!options || !options.clientId)
105 throw new Error("Invalid argument");
127 106
128 _poll : function() {
129 var me = this, url = this._makeUrl(this._id);
130 me.log("POLL timeout=${0}", me._timeout);
131 request(url, {
132 method : "GET",
133 handleAs : "json",
134 query : {
135 timeout : me._timeout
136 }
137 }).then(function(response) {
138 me._handlePoll(response);
139 me._poll();
140 }, function(err) {
141 me.error("POLL faield with ${0}", err);
142 me._emitError(err);
107 var me = this,
108 id = options.clientId;
109
110 return me._started.then(function () {
111 var url = me._makeUrl(me._id, options.clientId);
112
113 me.log("DELETE CLIENT ${0}", options.clientId);
114
115 return request(url, {
116 method: "DELETE",
117 handleAs: 'json'
118 }).then(function () {
119 me.log("CLIENT DELETED ${0}", options.clientId);
120 me._clients[id] = undefined;
143 121 });
144 },
122 });
123 },
145 124
146 _handlePoll : function(response) {
147 if (!response) {
148 this.log("POLL response undefined, looks like a bug");
149 return;
125 _poll: function () {
126 var me = this,
127 url = this._makeUrl(this._id);
128 me.log("POLL timeout=${0}", me._timeout);
129 request(url, {
130 method: "GET",
131 handleAs: "json",
132 query: {
133 timeout: me._timeout
150 134 }
151 if (!response.results || !response.results.length) {
152 this.log("POLL response is empty");
153 return;
154 }
155
156 var results = response.results;
157 this.log("POLL got ${0} results", results.length);
135 }).then(function (response) {
136 me._handlePoll(response);
137 me._poll();
138 }, function (err) {
139 me.error("POLL faield with ${0}", err);
140 me._emitError(err);
141 });
142 },
158 143
159 for (var i = 0; i < results.length; i++) {
160 var result = results[i];
161 var client = this._clients[result.clientId];
162 if (!client) {
163 // TODO this could happen due to client isn't
164 // registered yet
165 this.error("Unknown client ${0}", result.clientId);
166 continue;
167 }
168 client.call(this, result);
169 }
170 },
144 _handlePoll: function (response) {
145 if (!response) {
146 this.log("POLL response undefined, looks like a bug");
147 return;
148 }
149 if (!response.results || !response.results.length) {
150 this.log("POLL response is empty");
151 return;
152 }
153
154 var results = response.results;
155 this.log("POLL got ${0} results", results.length);
171 156
172 _emitError : function(err) {
173 this.emit("error", err);
174 },
157 for (var i = 0; i < results.length; i++) {
158 var result = results[i];
159 var client = this._clients[result.clientId];
160 if (!client) {
161 // TODO this could happen due to client isn't
162 // registered yet
163 this.error("Unknown client ${0}", result.clientId);
164 continue;
165 }
166 client.call(this, result);
167 }
168 },
175 169
176 _emitConnected : function() {
177 var me = this;
178 me.log("CONNECTED");
179 me.emit("connected");
180 },
170 _emitError: function (err) {
171 this.emit("error", err);
172 },
181 173
182 _makeUrl : function() {
183 var parts = [ this._baseUrl ];
184 for (var i = 0; i < arguments.length; i++)
185 parts.push(arguments[i].replace(/\/*$/, ""));
186 return parts.join('/');
187 },
174 _emitConnected: function () {
175 var me = this;
176 me.log("CONNECTED");
177 me.emit("connected");
178 },
188 179
189 queue : function(name) {
190 return this._getDestination("queue://" + name);
191 },
180 _makeUrl: function () {
181 var parts = [this._baseUrl];
182 for (var i = 0; i < arguments.length; i++)
183 parts.push(arguments[i].replace(/\/*$/, ""));
184 return parts.join('/');
185 },
192 186
193 topic : function(name) {
194 return this._getDestination("topic://" + name);
195 },
187 queue: function (name) {
188 return this._getDestination("queue://" + name);
189 },
196 190
197 _getDestination : function(uri) {
198 if (uri in this._destinations)
199 return this._destinations[uri];
191 topic: function (name) {
192 return this._getDestination("topic://" + name);
193 },
200 194
201 var dest = new Destination(this, uri);
202 this._destinations[uri] = dest;
203 return dest;
204 },
195 _getDestination: function (uri) {
196 if (uri in this._destinations)
197 return this._destinations[uri];
198
199 var dest = new Destination(this, uri);
200 this._destinations[uri] = dest;
201 return dest;
202 },
205 203
206 toString : function() {
207 return [ "[", "SESSION ", this._id, "]" ].join(" ");
208 }
209 });
204 toString: function () {
205 return ["[", "SESSION ", this._id, "]"].join(" ");
206 }
207 });
210 208
211 cls.connect = function(url, options) {
212 var session = new cls(url, options);
213 return session.start();
214 };
209 cls.connect = function (url, options) {
210 var session = new cls(url, options);
211 return session.start();
212 };
215 213
216 return cls;
217 });
214 return cls;
215 }); No newline at end of file
@@ -2,7 +2,12
2 2 "extends": "../tsconfig",
3 3 "compilerOptions": {
4 4 "types": [
5 "@types/node"
5 "node"
6 ],
7 "rootDir": "ts",
8 "rootDirs": [
9 "ts",
10 "../typings/main"
6 11 ]
7 12 },
8 13 "include": [
@@ -3,7 +3,7 import { IAsyncComponent, ICancellation,
3 3 import { destroy } from "../safe";
4 4
5 5 export class AsyncComponent implements IAsyncComponent, ICancellable {
6 _cancel: (e) => void;
6 _cancel: (e: any) => void;
7 7
8 8 _completion: Promise<void> = Promise.resolve();
9 9
@@ -33,7 +33,7 export class AsyncComponent implements I
33 33 return this._completion = guard();
34 34 }
35 35
36 cancel(reason) {
36 cancel(reason: any) {
37 37 if (this._cancel)
38 38 this._cancel(reason);
39 39 }
@@ -0,0 +1,1
1 export { Container } from "./di/Container";
@@ -1,11 +1,11
1 1 export class ConfigError extends Error {
2 inner;
2 inner: any;
3 3
4 4 path: string;
5 5
6 6 configName: string;
7 7
8 constructor(message: string, inner?) {
8 constructor(message: string, inner?: any) {
9 9 super(message);
10 10 this.inner = inner;
11 11 }
@@ -23,14 +23,30 import { FactoryServiceDescriptor } from
23 23 import { TraceSource } from "../log/TraceSource";
24 24 import { ConfigError } from "./ConfigError";
25 25 import { Cancellation } from "../Cancellation";
26 import { makeResolver } from "./ResolverHelper";
27 import { ICancellation } from "../interfaces";
26 28
27 29 const trace = TraceSource.get("@implab/core/di/Configuration");
28 30
29 31 declare const define;
30 32 declare const require;
33 declare const module;
31 34
32 35 function hasAmdLoader() {
33 return (typeof define === "function" && define.amd);
36 try {
37 // es6 may throw the exception
38 return (typeof define === "function" && define.amd);
39 } catch {
40 return false;
41 }
42 }
43
44 function hasNodeJs() {
45 try {
46 return (typeof module !== "undefined" && module.exports);
47 } catch {
48 return false;
49 }
34 50 }
35 51
36 52 async function mapAll(data: object | any[], map?: (v, k) => any): Promise<any> {
@@ -50,7 +66,7 async function mapAll(data: object | any
50 66 }
51 67 }
52 68
53 type Resolver = (qname: string) => any;
69 export type ModuleResolver = (moduleName: string, ct?: ICancellation) => any;
54 70
55 71 type _key = string | number;
56 72
@@ -64,7 +80,7 export class Configuration {
64 80
65 81 _configName: string;
66 82
67 _require: Resolver;
83 _require: ModuleResolver;
68 84
69 85 constructor(container: Container) {
70 86 argumentNotNull(container, container);
@@ -72,28 +88,31 export class Configuration {
72 88 this._path = [];
73 89 }
74 90
75 async loadConfiguration(moduleName: string, ct = Cancellation.none) {
91 async loadConfiguration(moduleName: string, contextRequire?: any, ct = Cancellation.none) {
76 92 argumentNotEmptyString(moduleName, "moduleName");
77 // TODO remove the code below somewehere else
78 if (hasAmdLoader()) {
79 // if we have a requirejs loader, use it directly
80 // don't rely on typescript 'import' function
81 const m = await new Promise<any>(cb => require(["./RequireJsHelper"], cb));
82 const r = m.makeResolver(require);
83 const config = await r(moduleName);
93
94 trace.log("loadConfiguration moduleName={0}", moduleName);
95
96 this._configName = moduleName;
97
98 const r = makeResolver(null, contextRequire);
84 99
85 return this.applyConfiguration(
86 config,
87 m.makeResolver(await m.createContextRequire(moduleName))
88 );
89 } else {
90 throw new Error("This feature is supported only with the amd loader");
91 }
100 const config = await r(moduleName, ct);
101
102 await this._applyConfiguration(
103 config,
104 makeResolver(moduleName, contextRequire),
105 ct
106 );
92 107 }
93 108
94 async applyConfiguration(data: object, resolver?: Resolver, ct = Cancellation.none) {
109 applyConfiguration(data: object, contextRequire?: any, ct = Cancellation.none) {
95 110 argumentNotNull(data, "data");
96 111
112 return this._applyConfiguration(data, makeResolver(void(0), contextRequire), ct);
113 }
114
115 async _applyConfiguration(data: object, resolver?: ModuleResolver, ct = Cancellation.none) {
97 116 trace.log("applyConfiguration");
98 117
99 118 this._configName = "$";
@@ -140,12 +159,10 export class Configuration {
140 159 }
141 160 }
142 161
143 async _loadModule(moduleName: string) {
162 _loadModule(moduleName: string) {
144 163 trace.debug("loadModule {0}", moduleName);
145 164
146 const m = await this._require(moduleName);
147
148 return m;
165 return this._require(moduleName);
149 166 }
150 167
151 168 async _visitRegistrations(data, name: _key) {
@@ -178,7 +195,7 export class Configuration {
178 195 trace.debug("<{0}", name);
179 196 }
180 197
181 async _visit(data, name: string): Promise<any> {
198 _visit(data, name: string): Promise<any> {
182 199 if (isPrimitive(data) || isDescriptor(data))
183 200 return data;
184 201
@@ -99,11 +99,11 export class Container {
99 99 * The function which will be used to load a configuration or types for services.
100 100 *
101 101 */
102 async configure(config: string | object, opts?, ct = Cancellation.none) {
102 async configure(config: string | object, opts?: any, ct = Cancellation.none) {
103 103 const c = new Configuration(this);
104 104
105 105 if (typeof (config) === "string") {
106 return c.loadConfiguration(config, ct);
106 return c.loadConfiguration(config, opts && opts.contextRequire, ct);
107 107 } else {
108 108 return c.applyConfiguration(config, opts && opts.contextRequire, ct);
109 109 }
@@ -2,6 +2,8 export type Constructor<T = {}> = new (.
2 2
3 3 export type Factory<T = {}> = (...args: any[]) => T;
4 4
5 export type Predicate<T = any> = (x: T) => boolean;
6
5 7 export interface MapOf<T> {
6 8 [key: string]: T;
7 9 }
@@ -47,7 +47,7 export class TraceSource {
47 47
48 48 debug(msg: string, ...args: any[]) {
49 49 if (this.isEnabled(DebugLevel))
50 this.emit(DebugLevel, format(msg, args));
50 this.emit(DebugLevel, format.apply(null, arguments));
51 51 }
52 52
53 53 isLogEnabled() {
@@ -56,7 +56,7 export class TraceSource {
56 56
57 57 log(msg: string, ...args: any[]) {
58 58 if (this.isEnabled(LogLevel))
59 this.emit(LogLevel, format(msg, args));
59 this.emit(LogLevel, format.apply(null, arguments));
60 60 }
61 61
62 62 isWarnEnabled() {
@@ -65,7 +65,7 export class TraceSource {
65 65
66 66 warn(msg: string, ...args: any[]) {
67 67 if (this.isEnabled(WarnLevel))
68 this.emit(WarnLevel, format(msg, args));
68 this.emit(WarnLevel, format.apply(null, arguments));
69 69 }
70 70
71 71 /**
@@ -3,6 +3,15 import { TraceEvent, LogLevel, WarnLevel
3 3 import { Cancellation } from "../../Cancellation";
4 4 import { destroy } from "../../safe";
5 5
6 function hasConsole() {
7 try {
8 // tslint:disable-next-line:no-console
9 return (typeof console !== "undefined" && typeof console.log === "function");
10 } catch {
11 return false;
12 }
13 }
14
6 15 export class ConsoleWriter implements IDestroyable {
7 16 readonly _subscriptions = new Array<IDestroyable>();
8 17
@@ -15,17 +24,21 export class ConsoleWriter implements ID
15 24 }
16 25
17 26 writeEvent(next: TraceEvent) {
27 // IE will create console only when devepoler tools are activated
28 if (!hasConsole())
29 return;
30
18 31 if (next.level >= DebugLevel) {
19 // tslint:disable-next-line
32 // tslint:disable-next-line:no-console
20 33 console.debug(next.source.id.toString(), next.arg);
21 34 } else if (next.level >= LogLevel) {
22 // tslint:disable-next-line
35 // tslint:disable-next-line:no-console
23 36 console.log(next.source.id.toString(), next.arg);
24 37 } else if (next.level >= WarnLevel) {
25 // tslint:disable-next-line
38 // tslint:disable-next-line:no-console
26 39 console.warn(next.source.id.toString(), next.arg);
27 40 } else {
28 // tslint:disable-next-line
41 // tslint:disable-next-line:no-console
29 42 console.error(next.source.id.toString(), next.arg);
30 43 }
31 44 }
@@ -1,9 +1,8
1 import { test, TapeWriter } from "./TestTraits";
1 import { test } from "./TestTraits";
2 2 import { Container } from "@implab/core/di/Container";
3 3 import { ReferenceDescriptor } from "@implab/core/di/ReferenceDescriptor";
4 4 import { AggregateDescriptor } from "@implab/core/di/AggregateDescriptor";
5 5 import { ValueDescriptor } from "@implab/core/di/ValueDescriptor";
6 import { TraceSource, DebugLevel } from "@implab/core/log/TraceSource";
7 6 import { Foo } from "./mock/Foo";
8 7 import { Bar } from "./mock/Bar";
9 8 import { isNull } from "@implab/core/safe";
@@ -2,7 +2,7 import { IObservable, ICancellation, IDe
2 2 import { Cancellation } from "@implab/core/Cancellation";
3 3 import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource";
4 4 import * as tape from "tape";
5 import { argumentNotNull } from "@implab/core/safe";
5 import { argumentNotNull, destroy } from "@implab/core/safe";
6 6
7 7 export class TapeWriter implements IDestroyable {
8 8 readonly _tape: tape.Test;
@@ -35,7 +35,7 export class TapeWriter implements IDest
35 35 }
36 36
37 37 destroy() {
38 this._subscriptions.forEach(x => x.destroy());
38 this._subscriptions.forEach(destroy);
39 39 }
40 40 }
41 41
@@ -58,8 +58,7 export async function delay(timeout: num
58 58 }
59 59 });
60 60 } finally {
61 if (un)
62 un.destroy();
61 destroy(un);
63 62 }
64 63 }
65 64
@@ -83,7 +82,7 export function test(name: string, cb: (
83 82
84 83 } finally {
85 84 t.end();
86 writer.destroy();
85 destroy(writer);
87 86 }
88 87 });
89 88 }
@@ -5,7 +5,7
5 5 "baseUrl": ".",
6 6 "paths": {
7 7 "@implab/core/*": [
8 "../../build/dist/amd/*"
8 "../../build/dist/*"
9 9 ]
10 10 }
11 11 },
@@ -1,18 +1,10
1 1 {
2 2 "compilerOptions": {
3 "target": "es3",
4 "sourceMap": true,
5 "declaration": true,
6 3 "moduleResolution": "node",
7 4 "noEmitOnError": true,
8 5 "listFiles": true,
9 "lib": [
10 "es5",
11 "es2015.promise",
12 "es2015.symbol",
13 "dom"
14 ],
15 "types": []
6 "types": [],
7 "lib": ["es5", "es2015.promise", "es2015.symbol", "dom", "scripthost"]
16 8 },
17 9 "files": []
18 10 } No newline at end of file
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now