##// 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 if(!npmName)
5 if(!npmName)
6 npmName = name;
6 npmName = name;
7
7
8 if(!["amd", "cjs"].contains(platform))
8 if(!["amd", "commonjs", "system", "umd", "es6", "esnext"].contains(jsmodule))
9 throw new Exception("Invalid platform specified: $platform");
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 = [
13 def targetLibs = [
12 "amd": "amd",
14 "es3" : "es5,es2015.promise,es2015.symbol,dom,scripthost",
13 "cjs": "commonjs"
15 "es5" : "es5,es2015.promise,es2015.symbol,dom,scripthost"
14 ]
16 ];
15
17
16 ext.packageName="$npmScope/$npmName-$platform";
18 ext.packageName="$npmScope/$npmName";
17
19
18 def srcDir = "$projectDir/src"
20 def srcDir = "$projectDir/src"
19 def typingsDir = "$srcDir/typings"
21 def typingsDir = "$srcDir/typings"
20 def distDir = "$buildDir/dist/$platform"
22 def distDir = "$buildDir/dist"
21 def testDir = "$buildDir/test/$platform"
23 def testDir = "$buildDir/test"
22 def moduleType = moduleTypes[platform]
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 task printVersion {
97 task printVersion {
27 doLast {
98 doLast {
28 println "version: $version"
99 println "version: $version"
29 println "packageName: $packageName"
100 println "packageName: $packageName"
30 println "platform: $platform"
101 println "target: $target"
31 println "module: $moduleType"
102 println "module: $jsmodule"
32 }
103 }
33 }
104 }
34
105
35 task clean {
106 task clean {
36 doLast {
107 doLast {
37 delete buildDir
108 delete buildDir
38 delete "node_modules/$packageName"
39 delete typingsDir
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 task cleanNpm {
130 task cleanNpm {
44 doLast {
131 doLast {
45 delete 'node_modules'
132 delete 'node_modules'
@@ -56,78 +143,55 task _npmInstall() {
56 }
143 }
57 }
144 }
58
145
59 sourceSets.each {
146 beforeBuild {
60 def setName = it.capitalize();
147 dependsOn _initBuild
61
148 dependsOn _npmInstall
62 def destDir = "$buildDir/compile/$it"
149 }
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 }
70
150
71 task "_compileTs$setName"(dependsOn: _npmInstall, type:Exec) {
151 sourceSets.each { createSoursetTasks(it, distDir) }
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)
77
152
78 commandLine 'node_modules/.bin/tsc',
153 testSets.each { createSoursetTasks(it, testDir) }
79 '-p', "$setDir/tsconfig.json",
80 '-m', moduleType,
81 '--outDir', destDir,
82 '--declarationDir', declDir
83 }
84
154
85 task "_buildTs$setName"(dependsOn: "_compileTs$setName", type:Copy) {
155 compileTsAmd {
86 from tasks.getByPath("_compileTs$setName");
156 dependsOn compileTypingsMain
87 into distDir
88 }
89 }
157 }
90
158
91 _compileTsAmd {
159 compileTypingsAmd {
92 dependsOn _buildTsMain
160 dependsOn compileTypingsMain
161 }
162
163 task build(dependsOn: buildMain) {
164 if (jsmodule == "amd")
165 dependsOn buildAmd
93 }
166 }
94
167
95 _buildTsTest {
168 compileTsTest {
96 into testDir
169 dependsOn build
97 }
170 }
98
171
99 _copyJsTest {
172 compileTsTestAmd {
100 into testDir
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 task _packageMeta(type: Copy) {
180 task _packageMeta(type: Copy) {
181 mustRunAfter build
182
104 inputs.property("version", version)
183 inputs.property("version", version)
105 from('.') {
184 from('.') {
106 include '.npmignore', 'readme.md', 'license', 'history.md'
185 include '.npmignore', 'readme.md', 'license', 'history.md'
107 }
186 }
108 from("$srcDir/package.template.json") {
187 from("$srcDir/package.${jsmodule}.tmpl.json") {
109 expand project.properties
188 expand project.properties
110 rename { "package.json" }
189 rename { "package.json" }
111 }
190 }
112 into distDir
191 into distDir
113 }
192 }
114
193
115 task build(dependsOn: [_copyJsMain, _copyJsAmd, _npmInstall, _buildTsMain, _buildTsAmd, _packageMeta]) {
194 task pack(dependsOn: [build, _packageMeta], type: Exec) {
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) {
131 workingDir distDir
195 workingDir distDir
132
196
133 commandLine 'npm', 'pack'
197 commandLine 'npm', 'pack'
@@ -119,18 +119,14 let msg = await pushEvents.next();
119
119
120 class Map {
120 class Map {
121 /**
121 /**
122
123 Получает координаты по щелчку мыши.
122 Получает координаты по щелчку мыши.
124
125 @async
123 @async
126
127 @returns [lon,lat]
124 @returns [lon,lat]
128
129 */
125 */
130 async peekCoordinates(ct: ICancellation = Cancellation.none) {
126 async peekCoordinates(ct: ICancellation = Cancellation.none) {
131 // получаем событие клика
127 // получаем событие клика
132 let evt = this.viewport.click.next(ct);
128 let evt = this.viewport.click.next(ct);
133
129
134 // преобразуем позицию на экране в координаты карты
130 // преобразуем позицию на экране в координаты карты
135 return this.clientToCoodinates([evt.clientx,evt.clientY]);
131 return this.clientToCoodinates([evt.clientx,evt.clientY]);
136 }
132 }
@@ -1,7 +1,8
1 version=1.2.0
1 version=1.2.0
2 release=rc
2 release=rc
3 author=Implab team
3 author=Implab team
4 platform=amd
4 jsmodule=amd
5 target=es5
5 description=Dependency injection, logging, simple and fast text template engine
6 description=Dependency injection, logging, simple and fast text template engine
6 license=BSD-2-Clause
7 license=BSD-2-Clause
7 repository=https://bitbucket.org/implab/implabjs
8 repository=https://bitbucket.org/implab/implabjs
@@ -1,12 +1,20
1 HISTORY
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 1.0.1
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 - `log` - log4 style logging system
18 - `log` - log4 style logging system
11 - `text` - simple and fast text templating and formatting
19 - `text` - simple and fast text templating and formatting
12 - `Uuid` - uuid generation traits No newline at end of file
20 - `Uuid` - uuid generation traits
@@ -5,9 +5,9
5 "requires": true,
5 "requires": true,
6 "dependencies": {
6 "dependencies": {
7 "@types/node": {
7 "@types/node": {
8 "version": "10.12.15",
8 "version": "10.12.18",
9 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz",
9 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
10 "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==",
10 "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
11 "dev": true
11 "dev": true
12 },
12 },
13 "@types/requirejs": {
13 "@types/requirejs": {
@@ -17,9 +17,9
17 "dev": true
17 "dev": true
18 },
18 },
19 "@types/tape": {
19 "@types/tape": {
20 "version": "4.2.32",
20 "version": "4.2.33",
21 "resolved": "http://registry.npmjs.org/@types/tape/-/tape-4.2.32.tgz",
21 "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
22 "integrity": "sha512-xil0KO5wkPoixdBWGIGolPv9dekf6dVkjjJLAFYchfKcd4DICou67rgGCIO7wAh3i5Ff/6j9IDgZz+GU9cMaqQ==",
22 "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
23 "dev": true,
23 "dev": true,
24 "requires": {
24 "requires": {
25 "@types/node": "*"
25 "@types/node": "*"
@@ -95,16 +95,25
95 "dev": true
95 "dev": true
96 },
96 },
97 "es-abstract": {
97 "es-abstract": {
98 "version": "1.12.0",
98 "version": "1.13.0",
99 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
99 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
100 "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
100 "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
101 "dev": true,
101 "dev": true,
102 "requires": {
102 "requires": {
103 "es-to-primitive": "^1.1.1",
103 "es-to-primitive": "^1.2.0",
104 "function-bind": "^1.1.1",
104 "function-bind": "^1.1.1",
105 "has": "^1.0.1",
105 "has": "^1.0.3",
106 "is-callable": "^1.1.3",
106 "is-callable": "^1.1.4",
107 "is-regex": "^1.0.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 "es-to-primitive": {
119 "es-to-primitive": {
@@ -375,9 +384,9
375 }
384 }
376 },
385 },
377 "tape": {
386 "tape": {
378 "version": "4.9.1",
387 "version": "4.9.2",
379 "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz",
388 "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz",
380 "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==",
389 "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==",
381 "dev": true,
390 "dev": true,
382 "requires": {
391 "requires": {
383 "deep-equal": "~1.0.1",
392 "deep-equal": "~1.0.1",
@@ -21,15 +21,15
21 "tslib": "latest"
21 "tslib": "latest"
22 },
22 },
23 "devDependencies": {
23 "devDependencies": {
24 "typescript": "latest",
24 "@types/node": "latest",
25 "tape": "latest",
26 "@types/tape": "latest",
27 "@types/requirejs": "latest",
25 "@types/requirejs": "latest",
28 "@types/node": "latest",
26 "@types/tape": "latest",
29 "requirejs": "latest",
27 "dojo": "^1.10.0",
30 "faucet": "latest",
28 "faucet": "latest",
31 "dojo": "^1.10.0",
29 "requirejs": "latest",
32 "tslib": "latest"
30 "tape": "^4.9.2",
31 "tslib": "latest",
32 "typescript": "latest"
33 },
33 },
34 "types": "main.d.ts"
34 "types": "main.d.ts"
35 }
35 }
@@ -1,95 +1,97
1 define(
1 define(["./declare", "./log/trace!"], function (declare, trace) {
2 [ "./declare" ],
2 trace.warn("THIS MODULE IS DEPRECATED! use uri-js or similar alternatives.");
3 function(declare) {
3
4 function parseURI(uri) {
4 function parseURI(uri) {
5 var schema, host, port, path, query, hash, i;
5 var schema, host, port, path, query, hash, i;
6 if (typeof (uri) == "string") {
6 if (typeof (uri) == "string") {
7 if ((i = uri.indexOf(":")) >= 0 &&
7 if ((i = uri.indexOf(":")) >= 0 &&
8 uri.substr(0, i).match(/^\w+$/)) {
8 uri.substr(0, i).match(/^\w+$/)) {
9 schema = uri.substr(0, i);
9 schema = uri.substr(0, i);
10 uri = uri.substr(i + 1);
10 uri = uri.substr(i + 1);
11 }
11 }
12
12
13 if (uri.indexOf("//") === 0) {
13 if (uri.indexOf("//") === 0) {
14 uri = uri.substr(2);
14 uri = uri.substr(2);
15 if ((i = uri.indexOf("/")) >= 0) {
15 if ((i = uri.indexOf("/")) >= 0) {
16 host = uri.substr(0, i);
16 host = uri.substr(0, i);
17 uri = uri.substr(i);
17 uri = uri.substr(i);
18 } else {
18 } else {
19 host = uri;
19 host = uri;
20 uri = "";
20 uri = "";
21 }
22 }
21 }
23
22 }
24 if ((i = uri.indexOf("?")) >= 0) {
25 path = uri.substr(0, i);
26 uri = uri.substr(i + 1);
27
23
28 } else {
24 if ((i = uri.indexOf("?")) >= 0) {
29 path = uri;
25 path = uri.substr(0, i);
30 uri = "";
26 uri = uri.substr(i + 1);
31
27
32 if ((i = path.indexOf("#")) >= 0) {
28 } else {
33 hash = path.substr(i + 1);
29 path = uri;
34 path = path.substr(0, i);
30 uri = "";
35 }
36 }
37
31
38 if ((i = uri.indexOf("#")) >= 0) {
32 if ((i = path.indexOf("#")) >= 0) {
39 query = uri.substr(0, i);
33 hash = path.substr(i + 1);
40 hash = uri.substr(i + 1);
34 path = path.substr(0, i);
41 } else {
42 query = uri;
43 }
35 }
44 }
36 }
45
37
46 if (host && (i = host.lastIndexOf(":")) >= 0) {
38 if ((i = uri.indexOf("#")) >= 0) {
47 port = host.substr(i + 1);
39 query = uri.substr(0, i);
48 host = host.substr(0, i);
40 hash = uri.substr(i + 1);
41 } else {
42 query = uri;
49 }
43 }
44 }
50
45
51 return {
46 if (host && (i = host.lastIndexOf(":")) >= 0) {
52 schema : schema,
47 port = host.substr(i + 1);
53 host : host,
48 host = host.substr(0, i);
54 port : port,
55 path : path,
56 query : query,
57 hash : hash
58 };
59 }
49 }
60
50
61 function makeURI(options) {
51 return {
62 var uri = [];
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)
61 function makeURI(options) {
65 uri.push(options.schema, ":");
62 var uri = [];
66 if (options.host)
67 uri.push("//", options.host);
68 if (options.host && options.port)
69 uri.push(":", options.port);
70
63
71 if (options.path) {
64 if (options.schema)
72 if (options.host && options.path[0] != "/")
65 uri.push(options.schema, ":");
73 uri.push("/");
66 if (options.host)
74 uri.push(options.path);
67 uri.push("//", options.host);
75 } else if (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 uri.push("/");
73 uri.push("/");
77 }
74 uri.push(options.path);
78
75 } else if (options.host) {
79 if (options.query)
76 uri.push("/");
80 uri.push("?", options.query);
81 if (options.hash)
82 uri.push("#", options.hash);
83
84 return uri.join("");
85 }
77 }
86
78
87 function reducePath(parts) {
79 if (options.query)
88 var balance = 0, result = [], isRoot;
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++) {
87 function reducePath(parts) {
91 var part = parts[i];
88 var balance = 0,
92 switch (part) {
89 result = [],
90 isRoot;
91
92 for (var i = 0; i < parts.length; i++) {
93 var part = parts[i];
94 switch (part) {
93 case "..":
95 case "..":
94 if (balance > 0) {
96 if (balance > 0) {
95 result.pop();
97 result.pop();
@@ -113,120 +115,122 define(
113 result.push(part);
115 result.push(part);
114 balance++;
116 balance++;
115 break;
117 break;
116 }
117 }
118 }
118
119 return result.join("/");
120 }
119 }
121
120
122 var meta = {
121 return result.join("/");
123 schema : null,
122 }
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 },
143
123
144 combine : function(rel) {
124 var meta = {
145 var me = this;
125 schema: null,
146
126 host: null,
147 if (typeof (rel) === "string")
127 port: null,
148 rel = new URI(rel);
128 path: null,
149 else
129 query: null,
150 rel = rel.clone();
130 hash: null
151
131 };
152 // //some.host:123/path?q=a#123
153 if (rel.host)
154 return rel;
155
132
156 // /abs/path?q=a#123
133 var URI = declare(null, {
157 if (rel.path && rel.path[0] == "/") {
134 constructor: function (opts) {
158 if (me.host) {
135 trace.warn("This class is deprecated use uri-js or similar");
159 rel.schema = me.schema;
136 if (typeof (opts) == "string")
160 rel.host = me.host;
137 opts = parseURI(opts);
161 rel.port = me.port;
138 for (var p in meta)
162 }
139 if (p in opts)
163 return rel;
140 this[p] = opts[p];
164 }
141 },
165
166 var base = me.clone();
167
142
168 // rel/path?a=b#cd
143 clone: function () {
169 if (rel.path) {
144 return new URI(this);
170 var segments = base.getSegments();
145 },
171 segments.pop();
172 segments.push.apply(segments, rel.getSegments());
173
174 base.path = reducePath(segments);
175 }
176
146
177 // ?q=a#123
147 combine: function (rel) {
178 if (rel.query)
148 var me = this;
179 base.query = rel.query;
180 if (rel.hash)
181 base.hase = rel.hash;
182
149
183 return base;
150 if (typeof (rel) === "string")
184 },
151 rel = new URI(rel);
185
152 else
186 optimize : function() {
153 rel = rel.clone();
187 this.path = reducePath(this.getSegments());
188 },
189
154
190 getSegments : function() {
155 // //some.host:123/path?q=a#123
191 if (typeof (this.path) === "string")
156 if (rel.host)
192 return this.path.split("/");
157 return rel;
193 else
194 return [];
195 },
196
197 toString : function() {
198 var uri = [], me = this;
199
158
200 if (me.schema)
159 // /abs/path?q=a#123
201 uri.push(me.schema, ":");
160 if (rel.path && rel.path[0] == "/") {
202 if (me.host)
161 if (me.host) {
203 uri.push("//", me.host);
162 rel.schema = me.schema;
204 if (me.host && me.port)
163 rel.host = me.host;
205 uri.push(":", me.port);
164 rel.port = 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("/");
213 }
165 }
214
166 return rel;
215 if (me.query)
216 uri.push("?", me.query);
217 if (me.hash)
218 uri.push("#", me.hash);
219
220 return uri.join("");
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) {
200 toString: function () {
226 if (typeof (base) === "string")
201 var uri = [],
227 base = new URI(base);
202 me = this;
228 return base.combine(rel).toString();
203
229 };
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;
219 if (me.query)
232 }); No newline at end of file
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(
1 define([
2 [
2 "dojo/_base/declare",
3 "dojo/_base/declare",
3 "dojo/request",
4 "dojo/_base/lang",
4 "./Destination",
5 "dojo/request",
5 "dojo/Evented",
6 "./Destination",
6 "dojo/Deferred",
7 "dojo/Evented",
7 "../log/_LogMixin"
8 "dojo/Deferred",
8 ], function (declare, request, Destination, Evented, Deferred, _LogMixin) {
9 "../log/_LogMixin" ],
10
11 function(declare, lang, request, Destination, Evented, Deferred, _LogMixin) {
12
9
13 var cls = declare(
10 var cls = declare(
14 [ Evented, _LogMixin ],
11 [Evented, _LogMixin], {
15 {
12 _id: null,
16 _id : null,
13 _baseUrl: null,
17 _baseUrl : null,
14 _destinations: null,
18 _destinations : null,
15 _timeout: 100000,
19 _timeout : 100000,
16 _clients: null,
20 _clients : null,
17 _started: null,
21 _started : null,
18 _starting: false,
22 _starting : false,
23
19
24 constructor : function(baseUrl, options) {
20 constructor: function (baseUrl, options) {
25 if (!baseUrl)
21 if (!baseUrl)
26 throw new Error("baseUrl is required");
22 throw new Error("baseUrl is required");
27 options = options || {};
23 options = options || {};
28
24
29 this._baseUrl = baseUrl.replace(/\/*$/, "");
25 this._baseUrl = baseUrl.replace(/\/*$/, "");
30 this._destinations = {};
26 this._destinations = {};
31 this._pending = [];
27 this._pending = [];
32 this._clients = {};
28 this._clients = {};
33 if (options.timeout)
29 if (options.timeout)
34 this._timeout = options.timeout;
30 this._timeout = options.timeout;
35
31
36 this._started = new Deferred();
32 this._started = new Deferred();
37 },
33 },
38
39 start : function() {
40 if (this._starting)
41 return this._started;
42 this._starting = true;
43
34
44 var me = this;
35 start: function () {
45 me.log("START");
36 if (this._starting)
46 request(this._baseUrl, {
37 return this._started;
47 method : "POST",
38 this._starting = true;
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);
74
39
75 return request(url, {
40 var me = this;
76 method : "POST",
41 me.log("START");
77 data : {
42 request(this._baseUrl, {
78 mode : options.mode,
43 method: "POST",
79 destination : options.destination
44 handleAs: "json"
80 },
45 }).then(function (result) {
81 handleAs : 'json'
46 me._id = result;
82 })
47 me._emitConnected();
83 .then(
48 me._poll();
84 function(id) {
49 me._started.resolve(me);
85 me
50 }, function (error) {
86 .log(
51 me._emitError(error);
87 "CLIENT id=${0}, mode=${1}, destination=${2}",
52 me._started.reject(me);
88 id,
53 });
89 options.mode,
54 return me._started.promise;
90 options.destination);
55 },
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 });
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) {
61 var me = this;
108 if (!options || !options.clientId)
109 throw new Error("Invalid argument");
110
62
111 var me = this, id = options.clientId;
63 return me._started
112
64 .then(function () {
113 return me._started.then(function() {
65 var url = me._makeUrl(me._id);
114 var url = me._makeUrl(me._id, options.clientId);
66 me.log(
115
67 "CREATE mode=${0}, destination=${1}",
116 me.log("DELETE CLIENT ${0}", options.clientId);
68 options.mode,
69 options.destination);
117
70
118 return request(url, {
71 return request(url, {
119 method : "DELETE",
72 method: "POST",
120 handleAs : 'json'
73 data: {
121 }).then(function() {
74 mode: options.mode,
122 me.log("CLIENT DELETED ${0}", options.clientId);
75 destination: options.destination
123 me._clients[id] = undefined;
76 },
124 });
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() {
107 var me = this,
129 var me = this, url = this._makeUrl(this._id);
108 id = options.clientId;
130 me.log("POLL timeout=${0}", me._timeout);
109
131 request(url, {
110 return me._started.then(function () {
132 method : "GET",
111 var url = me._makeUrl(me._id, options.clientId);
133 handleAs : "json",
112
134 query : {
113 me.log("DELETE CLIENT ${0}", options.clientId);
135 timeout : me._timeout
114
136 }
115 return request(url, {
137 }).then(function(response) {
116 method: "DELETE",
138 me._handlePoll(response);
117 handleAs: 'json'
139 me._poll();
118 }).then(function () {
140 }, function(err) {
119 me.log("CLIENT DELETED ${0}", options.clientId);
141 me.error("POLL faield with ${0}", err);
120 me._clients[id] = undefined;
142 me._emitError(err);
143 });
121 });
144 },
122 });
123 },
145
124
146 _handlePoll : function(response) {
125 _poll: function () {
147 if (!response) {
126 var me = this,
148 this.log("POLL response undefined, looks like a bug");
127 url = this._makeUrl(this._id);
149 return;
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) {
135 }).then(function (response) {
152 this.log("POLL response is empty");
136 me._handlePoll(response);
153 return;
137 me._poll();
154 }
138 }, function (err) {
155
139 me.error("POLL faield with ${0}", err);
156 var results = response.results;
140 me._emitError(err);
157 this.log("POLL got ${0} results", results.length);
141 });
142 },
158
143
159 for (var i = 0; i < results.length; i++) {
144 _handlePoll: function (response) {
160 var result = results[i];
145 if (!response) {
161 var client = this._clients[result.clientId];
146 this.log("POLL response undefined, looks like a bug");
162 if (!client) {
147 return;
163 // TODO this could happen due to client isn't
148 }
164 // registered yet
149 if (!response.results || !response.results.length) {
165 this.error("Unknown client ${0}", result.clientId);
150 this.log("POLL response is empty");
166 continue;
151 return;
167 }
152 }
168 client.call(this, result);
153
169 }
154 var results = response.results;
170 },
155 this.log("POLL got ${0} results", results.length);
171
156
172 _emitError : function(err) {
157 for (var i = 0; i < results.length; i++) {
173 this.emit("error", err);
158 var result = results[i];
174 },
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() {
170 _emitError: function (err) {
177 var me = this;
171 this.emit("error", err);
178 me.log("CONNECTED");
172 },
179 me.emit("connected");
180 },
181
173
182 _makeUrl : function() {
174 _emitConnected: function () {
183 var parts = [ this._baseUrl ];
175 var me = this;
184 for (var i = 0; i < arguments.length; i++)
176 me.log("CONNECTED");
185 parts.push(arguments[i].replace(/\/*$/, ""));
177 me.emit("connected");
186 return parts.join('/');
178 },
187 },
188
179
189 queue : function(name) {
180 _makeUrl: function () {
190 return this._getDestination("queue://" + name);
181 var parts = [this._baseUrl];
191 },
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) {
187 queue: function (name) {
194 return this._getDestination("topic://" + name);
188 return this._getDestination("queue://" + name);
195 },
189 },
196
190
197 _getDestination : function(uri) {
191 topic: function (name) {
198 if (uri in this._destinations)
192 return this._getDestination("topic://" + name);
199 return this._destinations[uri];
193 },
200
194
201 var dest = new Destination(this, uri);
195 _getDestination: function (uri) {
202 this._destinations[uri] = dest;
196 if (uri in this._destinations)
203 return dest;
197 return this._destinations[uri];
204 },
198
199 var dest = new Destination(this, uri);
200 this._destinations[uri] = dest;
201 return dest;
202 },
205
203
206 toString : function() {
204 toString: function () {
207 return [ "[", "SESSION ", this._id, "]" ].join(" ");
205 return ["[", "SESSION ", this._id, "]"].join(" ");
208 }
206 }
209 });
207 });
210
208
211 cls.connect = function(url, options) {
209 cls.connect = function (url, options) {
212 var session = new cls(url, options);
210 var session = new cls(url, options);
213 return session.start();
211 return session.start();
214 };
212 };
215
213
216 return cls;
214 return cls;
217 });
215 }); No newline at end of file
@@ -2,7 +2,12
2 "extends": "../tsconfig",
2 "extends": "../tsconfig",
3 "compilerOptions": {
3 "compilerOptions": {
4 "types": [
4 "types": [
5 "@types/node"
5 "node"
6 ],
7 "rootDir": "ts",
8 "rootDirs": [
9 "ts",
10 "../typings/main"
6 ]
11 ]
7 },
12 },
8 "include": [
13 "include": [
@@ -3,7 +3,7 import { IAsyncComponent, ICancellation,
3 import { destroy } from "../safe";
3 import { destroy } from "../safe";
4
4
5 export class AsyncComponent implements IAsyncComponent, ICancellable {
5 export class AsyncComponent implements IAsyncComponent, ICancellable {
6 _cancel: (e) => void;
6 _cancel: (e: any) => void;
7
7
8 _completion: Promise<void> = Promise.resolve();
8 _completion: Promise<void> = Promise.resolve();
9
9
@@ -33,7 +33,7 export class AsyncComponent implements I
33 return this._completion = guard();
33 return this._completion = guard();
34 }
34 }
35
35
36 cancel(reason) {
36 cancel(reason: any) {
37 if (this._cancel)
37 if (this._cancel)
38 this._cancel(reason);
38 this._cancel(reason);
39 }
39 }
@@ -0,0 +1,1
1 export { Container } from "./di/Container";
@@ -1,11 +1,11
1 export class ConfigError extends Error {
1 export class ConfigError extends Error {
2 inner;
2 inner: any;
3
3
4 path: string;
4 path: string;
5
5
6 configName: string;
6 configName: string;
7
7
8 constructor(message: string, inner?) {
8 constructor(message: string, inner?: any) {
9 super(message);
9 super(message);
10 this.inner = inner;
10 this.inner = inner;
11 }
11 }
@@ -23,14 +23,30 import { FactoryServiceDescriptor } from
23 import { TraceSource } from "../log/TraceSource";
23 import { TraceSource } from "../log/TraceSource";
24 import { ConfigError } from "./ConfigError";
24 import { ConfigError } from "./ConfigError";
25 import { Cancellation } from "../Cancellation";
25 import { Cancellation } from "../Cancellation";
26 import { makeResolver } from "./ResolverHelper";
27 import { ICancellation } from "../interfaces";
26
28
27 const trace = TraceSource.get("@implab/core/di/Configuration");
29 const trace = TraceSource.get("@implab/core/di/Configuration");
28
30
29 declare const define;
31 declare const define;
30 declare const require;
32 declare const require;
33 declare const module;
31
34
32 function hasAmdLoader() {
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 async function mapAll(data: object | any[], map?: (v, k) => any): Promise<any> {
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 type _key = string | number;
71 type _key = string | number;
56
72
@@ -64,7 +80,7 export class Configuration {
64
80
65 _configName: string;
81 _configName: string;
66
82
67 _require: Resolver;
83 _require: ModuleResolver;
68
84
69 constructor(container: Container) {
85 constructor(container: Container) {
70 argumentNotNull(container, container);
86 argumentNotNull(container, container);
@@ -72,28 +88,31 export class Configuration {
72 this._path = [];
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 argumentNotEmptyString(moduleName, "moduleName");
92 argumentNotEmptyString(moduleName, "moduleName");
77 // TODO remove the code below somewehere else
93
78 if (hasAmdLoader()) {
94 trace.log("loadConfiguration moduleName={0}", moduleName);
79 // if we have a requirejs loader, use it directly
95
80 // don't rely on typescript 'import' function
96 this._configName = moduleName;
81 const m = await new Promise<any>(cb => require(["./RequireJsHelper"], cb));
97
82 const r = m.makeResolver(require);
98 const r = makeResolver(null, contextRequire);
83 const config = await r(moduleName);
84
99
85 return this.applyConfiguration(
100 const config = await r(moduleName, ct);
86 config,
101
87 m.makeResolver(await m.createContextRequire(moduleName))
102 await this._applyConfiguration(
88 );
103 config,
89 } else {
104 makeResolver(moduleName, contextRequire),
90 throw new Error("This feature is supported only with the amd loader");
105 ct
91 }
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 argumentNotNull(data, "data");
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 trace.log("applyConfiguration");
116 trace.log("applyConfiguration");
98
117
99 this._configName = "$";
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 trace.debug("loadModule {0}", moduleName);
163 trace.debug("loadModule {0}", moduleName);
145
164
146 const m = await this._require(moduleName);
165 return this._require(moduleName);
147
148 return m;
149 }
166 }
150
167
151 async _visitRegistrations(data, name: _key) {
168 async _visitRegistrations(data, name: _key) {
@@ -178,7 +195,7 export class Configuration {
178 trace.debug("<{0}", name);
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 if (isPrimitive(data) || isDescriptor(data))
199 if (isPrimitive(data) || isDescriptor(data))
183 return data;
200 return data;
184
201
@@ -99,11 +99,11 export class Container {
99 * The function which will be used to load a configuration or types for services.
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 const c = new Configuration(this);
103 const c = new Configuration(this);
104
104
105 if (typeof (config) === "string") {
105 if (typeof (config) === "string") {
106 return c.loadConfiguration(config, ct);
106 return c.loadConfiguration(config, opts && opts.contextRequire, ct);
107 } else {
107 } else {
108 return c.applyConfiguration(config, opts && opts.contextRequire, ct);
108 return c.applyConfiguration(config, opts && opts.contextRequire, ct);
109 }
109 }
@@ -2,6 +2,8 export type Constructor<T = {}> = new (.
2
2
3 export type Factory<T = {}> = (...args: any[]) => T;
3 export type Factory<T = {}> = (...args: any[]) => T;
4
4
5 export type Predicate<T = any> = (x: T) => boolean;
6
5 export interface MapOf<T> {
7 export interface MapOf<T> {
6 [key: string]: T;
8 [key: string]: T;
7 }
9 }
@@ -47,7 +47,7 export class TraceSource {
47
47
48 debug(msg: string, ...args: any[]) {
48 debug(msg: string, ...args: any[]) {
49 if (this.isEnabled(DebugLevel))
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 isLogEnabled() {
53 isLogEnabled() {
@@ -56,7 +56,7 export class TraceSource {
56
56
57 log(msg: string, ...args: any[]) {
57 log(msg: string, ...args: any[]) {
58 if (this.isEnabled(LogLevel))
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 isWarnEnabled() {
62 isWarnEnabled() {
@@ -65,7 +65,7 export class TraceSource {
65
65
66 warn(msg: string, ...args: any[]) {
66 warn(msg: string, ...args: any[]) {
67 if (this.isEnabled(WarnLevel))
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 import { Cancellation } from "../../Cancellation";
3 import { Cancellation } from "../../Cancellation";
4 import { destroy } from "../../safe";
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 export class ConsoleWriter implements IDestroyable {
15 export class ConsoleWriter implements IDestroyable {
7 readonly _subscriptions = new Array<IDestroyable>();
16 readonly _subscriptions = new Array<IDestroyable>();
8
17
@@ -15,17 +24,21 export class ConsoleWriter implements ID
15 }
24 }
16
25
17 writeEvent(next: TraceEvent) {
26 writeEvent(next: TraceEvent) {
27 // IE will create console only when devepoler tools are activated
28 if (!hasConsole())
29 return;
30
18 if (next.level >= DebugLevel) {
31 if (next.level >= DebugLevel) {
19 // tslint:disable-next-line
32 // tslint:disable-next-line:no-console
20 console.debug(next.source.id.toString(), next.arg);
33 console.debug(next.source.id.toString(), next.arg);
21 } else if (next.level >= LogLevel) {
34 } else if (next.level >= LogLevel) {
22 // tslint:disable-next-line
35 // tslint:disable-next-line:no-console
23 console.log(next.source.id.toString(), next.arg);
36 console.log(next.source.id.toString(), next.arg);
24 } else if (next.level >= WarnLevel) {
37 } else if (next.level >= WarnLevel) {
25 // tslint:disable-next-line
38 // tslint:disable-next-line:no-console
26 console.warn(next.source.id.toString(), next.arg);
39 console.warn(next.source.id.toString(), next.arg);
27 } else {
40 } else {
28 // tslint:disable-next-line
41 // tslint:disable-next-line:no-console
29 console.error(next.source.id.toString(), next.arg);
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 import { Container } from "@implab/core/di/Container";
2 import { Container } from "@implab/core/di/Container";
3 import { ReferenceDescriptor } from "@implab/core/di/ReferenceDescriptor";
3 import { ReferenceDescriptor } from "@implab/core/di/ReferenceDescriptor";
4 import { AggregateDescriptor } from "@implab/core/di/AggregateDescriptor";
4 import { AggregateDescriptor } from "@implab/core/di/AggregateDescriptor";
5 import { ValueDescriptor } from "@implab/core/di/ValueDescriptor";
5 import { ValueDescriptor } from "@implab/core/di/ValueDescriptor";
6 import { TraceSource, DebugLevel } from "@implab/core/log/TraceSource";
7 import { Foo } from "./mock/Foo";
6 import { Foo } from "./mock/Foo";
8 import { Bar } from "./mock/Bar";
7 import { Bar } from "./mock/Bar";
9 import { isNull } from "@implab/core/safe";
8 import { isNull } from "@implab/core/safe";
@@ -2,7 +2,7 import { IObservable, ICancellation, IDe
2 import { Cancellation } from "@implab/core/Cancellation";
2 import { Cancellation } from "@implab/core/Cancellation";
3 import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource";
3 import { TraceEvent, LogLevel, WarnLevel, DebugLevel, TraceSource } from "@implab/core/log/TraceSource";
4 import * as tape from "tape";
4 import * as tape from "tape";
5 import { argumentNotNull } from "@implab/core/safe";
5 import { argumentNotNull, destroy } from "@implab/core/safe";
6
6
7 export class TapeWriter implements IDestroyable {
7 export class TapeWriter implements IDestroyable {
8 readonly _tape: tape.Test;
8 readonly _tape: tape.Test;
@@ -35,7 +35,7 export class TapeWriter implements IDest
35 }
35 }
36
36
37 destroy() {
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 } finally {
60 } finally {
61 if (un)
61 destroy(un);
62 un.destroy();
63 }
62 }
64 }
63 }
65
64
@@ -83,7 +82,7 export function test(name: string, cb: (
83
82
84 } finally {
83 } finally {
85 t.end();
84 t.end();
86 writer.destroy();
85 destroy(writer);
87 }
86 }
88 });
87 });
89 }
88 }
@@ -5,7 +5,7
5 "baseUrl": ".",
5 "baseUrl": ".",
6 "paths": {
6 "paths": {
7 "@implab/core/*": [
7 "@implab/core/*": [
8 "../../build/dist/amd/*"
8 "../../build/dist/*"
9 ]
9 ]
10 }
10 }
11 },
11 },
@@ -1,18 +1,10
1 {
1 {
2 "compilerOptions": {
2 "compilerOptions": {
3 "target": "es3",
4 "sourceMap": true,
5 "declaration": true,
6 "moduleResolution": "node",
3 "moduleResolution": "node",
7 "noEmitOnError": true,
4 "noEmitOnError": true,
8 "listFiles": true,
5 "listFiles": true,
9 "lib": [
6 "types": [],
10 "es5",
7 "lib": ["es5", "es2015.promise", "es2015.symbol", "dom", "scripthost"]
11 "es2015.promise",
12 "es2015.symbol",
13 "dom"
14 ],
15 "types": []
16 },
8 },
17 "files": []
9 "files": []
18 } No newline at end of file
10 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now