##// END OF EJS Templates
Initial work on typescript support for the container configuration
cin -
r107:3725cefc8f98 ioc ts support
parent child
Show More
@@ -0,0 +1,11
1 import { Constructor } from "../interfaces";
2
3 export interface InjectOptions {
4 lazy?: boolean;
5 }
6
7 export function inject<I extends { [name in keyof I]: (v: any) => void } >(dependency: string) {
8 return <M extends keyof I>(target: any, memberName: M, descriptor: TypedPropertyDescriptor<I[M]> ) => {
9
10 };
11 }
@@ -0,0 +1,18
1 import { inject } from "../di/Annotations";
2
3 export interface Injector<T> {
4 setValue(value: T);
5 }
6
7 export class Box<T> implements Injector<T> {
8 private _value: T;
9
10 @inject<Injector<T>>("bar")
11 setValue(value: T) {
12 this._value = value;
13 }
14
15 getValue() {
16 return this._value;
17 }
18 }
@@ -0,0 +1,36
1 import { Constructor } from "../interfaces";
2 import { ActivationType } from "../di/interfaces";
3
4 namespace MyLib {
5 interface Resolver<S> {
6 <K extends keyof S>(name: K): S[K];
7 <K extends keyof S>(lazy: K): (overrides?: {}) => S[K];
8 }
9
10 interface RegistrationOptions<S> {
11 activation?: ActivationType;
12 services?: BuilderContext<S>;
13 }
14
15 interface BuilderContext<S> {
16 registerType<T extends Constructor, K extends string>(
17 name: K,
18 constructor: T,
19 options?: RegistrationOptions<S>
20 ): BuilderContext<S & { K: T }>;
21
22 registerFactory<T, K extends string>(
23 name: K,
24 factory: (resolver: Resolver<S>) => T,
25 options?: RegistrationOptions<S>
26 ): BuilderContext<S & { K: T }>;
27
28 registerInstance<T, K extends string>(
29 name: K,
30 instance: T,
31 ownership?: boolean
32 ): BuilderContext<S & { K: T }>;
33 }
34 }
35
36 export = MyLib;
@@ -1,2 +1,13
1 arguments=
2 auto.sync=false
3 build.scans.enabled=false
4 connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
1 connection.project.dir=
5 connection.project.dir=
2 eclipse.preferences.version=1
6 eclipse.preferences.version=1
7 gradle.user.home=
8 java.home=/usr/lib64/jvm/java
9 jvm.arguments=
10 offline.mode=false
11 override.workspace.settings=true
12 show.console.view=true
13 show.executions.view=true
@@ -1,234 +1,234
1 plugins {
1 plugins {
2 id "org.implab.gradle-typescript" version "1.3.0"
2 id "org.implab.gradle-typescript" version "1.3.3"
3 id "org.implab.gradle-hg"
3 id "org.implab.gradle-hg"
4 id "ivy-publish"
4 id "ivy-publish"
5 }
5 }
6
6
7 if (!symbols in ['local', 'pack', 'none'])
7 if (!symbols in ['local', 'pack', 'none'])
8 throw new Exception("The symbols property value is invalid: $symbols");
8 throw new Exception("The symbols property value is invalid: $symbols");
9
9
10 if (!flavour in ['browser', 'node'])
10 if (!flavour in ['browser', 'node'])
11 throw new Exception("The flavour property value is invalid: $flavour");
11 throw new Exception("The flavour property value is invalid: $flavour");
12
12
13 ext {
13 ext {
14 packageName = flavour == 'browser' ? "@$npmScope/$name-amd" : "@$npmScope/$name"
14 packageName = flavour == 'browser' ? "@$npmScope/$name-amd" : "@$npmScope/$name"
15 lint = project.hasProperty('lint') ? project.lint ?: true : false
15 lint = project.hasProperty('lint') ? project.lint ?: true : false
16 }
16 }
17
17
18 sources {
18 sources {
19 amd {
19 amd {
20 typings {
20 typings {
21 srcDir main.output.typingsDir
21 srcDir main.output.typingsDir
22 }
22 }
23 }
23 }
24
24
25 cjs {
25 cjs {
26 typings {
26 typings {
27 srcDir main.output.typingsDir
27 srcDir main.output.typingsDir
28 }
28 }
29 }
29 }
30
30
31 testAmd {
31 testAmd {
32 typings {
32 typings {
33 srcDir main.output.typingsDir
33 srcDir main.output.typingsDir
34 srcDir amd.output.typingsDir
34 srcDir amd.output.typingsDir
35 srcDir test.output.typingsDir
35 srcDir test.output.typingsDir
36 }
36 }
37 }
37 }
38
38
39 testCjs {
39 testCjs {
40 typings {
40 typings {
41 srcDir main.output.typingsDir
41 srcDir main.output.typingsDir
42 srcDir cjs.output.typingsDir
42 srcDir cjs.output.typingsDir
43 srcDir test.output.typingsDir
43 srcDir test.output.typingsDir
44 }
44 }
45 }
45 }
46 }
46 }
47
47
48 typescript {
48 typescript {
49 compilerOptions {
49 compilerOptions {
50 types = []
50 types = []
51 declaration = true
51 declaration = true
52
52
53 if(symbols != 'none') {
53 if(symbols != 'none') {
54 sourceMap = true
54 sourceMap = true
55 sourceRoot = "_src"
55 sourceRoot = packageName
56 }
56 }
57
57
58 if (flavour == 'node') {
58 if (flavour == 'node') {
59 module = "commonjs"
59 module = "commonjs"
60 target = "es2017"
60 target = "es2017"
61 lib = ["es2017", "dom", "scripthost"]
61 lib = ["es2017", "dom", "scripthost"]
62 } else if (flavour == 'browser') {
62 } else if (flavour == 'browser') {
63 module = "amd"
63 module = "amd"
64 target = "es5"
64 target = "es5"
65 lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable" ]
65 lib = ["es5", "dom", "scripthost", "es2015.promise", "es2015.symbol", "es2015.iterable" ]
66 }
66 }
67 }
67 }
68 tscCmd = "$projectDir/node_modules/.bin/tsc"
68 tscCmd = "$projectDir/node_modules/.bin/tsc"
69 tsLintCmd = "$projectDir/node_modules/.bin/tslint"
69 tsLintCmd = "$projectDir/node_modules/.bin/tslint"
70 esLintCmd = "$projectDir/node_modules/.bin/eslint"
70 esLintCmd = "$projectDir/node_modules/.bin/eslint"
71 }
71 }
72
72
73 tasks.matching{ it.name =~ /^lint/ }.configureEach {
73 tasks.matching{ it.name =~ /^lint/ }.configureEach {
74 onlyIf { lint }
74 onlyIf { lint }
75 }
75 }
76
76
77 if (symbols == 'local') {
77 if (symbols == 'local') {
78 tasks.matching{ it.name =~ /^configureTs/ }.configureEach {
78 tasks.matching{ it.name =~ /^configureTs/ }.configureEach {
79 compilerOptions {
79 compilerOptions {
80 sourceRoot = "file://" + it.rootDir
80 sourceRoot = "file://" + it.rootDir
81 }
81 }
82 }
82 }
83 }
83 }
84
84
85 task printVersion {
85 task printVersion {
86 doLast {
86 doLast {
87 println "packageName: $packageName";
87 println "packageName: $packageName";
88 println "version: $version";
88 println "version: $version";
89 println "flavour: $flavour";
89 println "flavour: $flavour";
90 println "target: $typescript.compilerOptions.target";
90 println "target: $typescript.compilerOptions.target";
91 println "module: $typescript.compilerOptions.module";
91 println "module: $typescript.compilerOptions.module";
92 println "lint: $lint";
92 println "lint: $lint";
93 println "symbols: $symbols";
93 println "symbols: $symbols";
94 }
94 }
95 }
95 }
96
96
97 npmPackMeta {
97 npmPackMeta {
98 meta {
98 meta {
99 name = packageName
99 name = packageName
100 }
100 }
101 }
101 }
102
102
103 configureTsCjs {
103 configureTsCjs {
104 dependsOn sources.main.output
104 dependsOn sources.main.output
105 compilerOptions {
105 compilerOptions {
106 types += [ "node" ]
106 types += [ "node" ]
107 }
107 }
108 }
108 }
109
109
110 configureTsAmd {
110 configureTsAmd {
111 dependsOn sources.main.output
111 dependsOn sources.main.output
112 compilerOptions {
112 compilerOptions {
113 types += [ "requirejs", "dojo-typings" ]
113 types += [ "requirejs", "dojo-typings" ]
114 }
114 }
115 }
115 }
116
116
117 test {
117 test {
118 workingDir layout.buildDirectory.dir("test");
118 workingDir layout.buildDirectory.dir("test");
119 commandLine "node", "tests/index.js"
119 commandLine "node", "tests/index.js"
120 }
120 }
121
121
122 assemble {
122 assemble {
123 if (flavour == 'browser') {
123 if (flavour == 'browser') {
124 dependsOn sources.amd.output
124 dependsOn sources.amd.output
125 from sources.amd.output.compiledDir
125 from sources.amd.output.compiledDir
126 from sources.amd.resources
126 from sources.amd.resources
127 }
127 }
128 if (flavour == 'node') {
128 if (flavour == 'node') {
129 dependsOn sources.cjs.output
129 dependsOn sources.cjs.output
130 from sources.cjs.output.compiledDir
130 from sources.cjs.output.compiledDir
131 from sources.cjs.resources
131 from sources.cjs.resources
132 }
132 }
133 }
133 }
134
134
135 assembleTest {
135 assembleTest {
136 if (flavour == 'browser') {
136 if (flavour == 'browser') {
137 dependsOn sources.amd.output, sources.testAmd.output
137 dependsOn sources.amd.output, sources.testAmd.output
138
138
139 from sources.amd.output.compiledDir
139 from sources.amd.output.compiledDir
140 from sources.testAmd.output.compiledDir
140 from sources.testAmd.output.compiledDir
141 from sources.amd.resources
141 from sources.amd.resources
142 from sources.testAmd.resources
142 from sources.testAmd.resources
143 }
143 }
144 if (flavour == 'node') {
144 if (flavour == 'node') {
145 dependsOn sources.cjs.output, sources.testCjs.output
145 dependsOn sources.cjs.output, sources.testCjs.output
146
146
147 from sources.cjs.output.compiledDir
147 from sources.cjs.output.compiledDir
148 from sources.testCjs.output.compiledDir
148 from sources.testCjs.output.compiledDir
149 from sources.cjs.resources
149 from sources.cjs.resources
150 from sources.testCjs.resources
150 from sources.testCjs.resources
151 }
151 }
152 }
152 }
153
153
154 typings {
154 typings {
155 if (flavour == 'browser') {
155 if (flavour == 'browser') {
156 dependsOn sources.amd.output
156 dependsOn sources.amd.output
157 from sources.amd.output.typingsDir
157 from sources.amd.output.typingsDir
158 }
158 }
159 if (flavour == 'node') {
159 if (flavour == 'node') {
160 dependsOn sources.cjs.output
160 dependsOn sources.cjs.output
161 from sources.cjs.output.typingsDir
161 from sources.cjs.output.typingsDir
162 }
162 }
163 }
163 }
164
164
165 task npmPackTypings(type: Copy) {
165 task npmPackTypings(type: Copy) {
166 npmPackContents.dependsOn it
166 npmPackContents.dependsOn it
167 dependsOn sources.main.output
167 dependsOn sources.main.output
168
168
169 from sources.main.output.typingsDir
169 from sources.main.output.typingsDir
170
170
171 if (flavour == 'browser') {
171 if (flavour == 'browser') {
172 dependsOn sources.amd.output
172 dependsOn sources.amd.output
173 from sources.amd.output.typingsDir
173 from sources.amd.output.typingsDir
174 }
174 }
175 if (flavour == 'node') {
175 if (flavour == 'node') {
176 dependsOn sources.cjs.output
176 dependsOn sources.cjs.output
177 from sources.cjs.output.typingsDir
177 from sources.cjs.output.typingsDir
178 }
178 }
179
179
180 into npm.packageDir
180 into npm.packageDir
181 }
181 }
182
182
183 task npmPackSources(type: Copy) {
183 task npmPackSources(type: Copy) {
184 from sources.main.ts
184 from sources.main.ts
185 if (symbols == 'pack') {
185 if (symbols == 'pack') {
186 npmPackContents.dependsOn npmPackSources
186 npmPackContents.dependsOn npmPackSources
187 }
187 }
188
188
189 if (flavour == 'browser') {
189 if (flavour == 'browser') {
190 from sources.amd.ts
190 from sources.amd.ts
191 }
191 }
192 if (flavour == 'node') {
192 if (flavour == 'node') {
193 from sources.cjs.ts
193 from sources.cjs.ts
194 }
194 }
195
195
196 into npm.packageDir.dir("_src")
196 into npm.packageDir.dir("_src")
197 }
197 }
198
198
199
199
200
200
201 task packJsTar(type: Tar) {
201 task packJsTar(type: Tar) {
202 dependsOn assemble;
202 dependsOn assemble;
203
203
204 archiveBaseName = provider { packageName }
204 archiveBaseName = provider { packageName }
205
205
206 destinationDirectory = buildDir
206 destinationDirectory = buildDir
207 archiveClassifier = provider { typescript.compilerOptions.module }
207 archiveClassifier = provider { typescript.compilerOptions.module }
208 compression = Compression.GZIP
208 compression = Compression.GZIP
209
209
210 from(assemble.outputs)
210 from(assemble.outputs)
211
211
212 doLast {
212 doLast {
213 println archiveName;
213 println archiveName;
214 }
214 }
215 }
215 }
216
216
217 task packTypingsTar(type: Tar) {
217 task packTypingsTar(type: Tar) {
218 }
218 }
219
219
220 publishing {
220 publishing {
221 publications {
221 publications {
222 local(IvyPublication) {
222 local(IvyPublication) {
223 artifact(packJsTar) {
223 artifact(packJsTar) {
224 type = "js"
224 type = "js"
225 }
225 }
226 }
226 }
227 }
227 }
228
228
229 repositories {
229 repositories {
230 ivy {
230 ivy {
231 url "ivy-repo"
231 url "ivy-repo"
232 }
232 }
233 }
233 }
234 } No newline at end of file
234 }
@@ -1,128 +1,128
1 import { ActivationContext } from "./ActivationContext";
1 import { ActivationContext } from "./ActivationContext";
2 import { ValueDescriptor } from "./ValueDescriptor";
2 import { ValueDescriptor } from "./ValueDescriptor";
3 import { ActivationError } from "./ActivationError";
3 import { ActivationError } from "./ActivationError";
4 import { isDescriptor, ServiceMap } from "./interfaces";
4 import { isDescriptor, ServiceMap } from "./interfaces";
5 import { TraceSource } from "../log/TraceSource";
5 import { TraceSource } from "../log/TraceSource";
6 import { Configuration } from "./Configuration";
6 import { Configuration } from "./Configuration";
7 import { Cancellation } from "../Cancellation";
7 import { Cancellation } from "../Cancellation";
8
8
9 const trace = TraceSource.get("@implab/core/di/ActivationContext");
9 const trace = TraceSource.get("@implab/core/di/ActivationContext");
10
10
11 export class Container {
11 export class Container {
12 _services: ServiceMap;
12 _services: ServiceMap;
13
13
14 _cache: object;
14 _cache: object;
15
15
16 _cleanup: (() => void)[];
16 _cleanup: (() => void)[];
17
17
18 _root: Container;
18 _root: Container;
19
19
20 _parent: Container;
20 _parent: Container;
21
21
22 constructor(parent?: Container) {
22 constructor(parent?: Container) {
23 this._parent = parent;
23 this._parent = parent;
24 this._services = parent ? Object.create(parent._services) : {};
24 this._services = parent ? Object.create(parent._services) : {};
25 this._cache = {};
25 this._cache = {};
26 this._cleanup = [];
26 this._cleanup = [];
27 this._root = parent ? parent.getRootContainer() : this;
27 this._root = parent ? parent.getRootContainer() : this;
28 this._services.container = new ValueDescriptor(this);
28 this._services.container = new ValueDescriptor(this);
29 }
29 }
30
30
31 getRootContainer() {
31 getRootContainer() {
32 return this._root;
32 return this._root;
33 }
33 }
34
34
35 getParent() {
35 getParent() {
36 return this._parent;
36 return this._parent;
37 }
37 }
38
38
39 resolve(name: string, def?) {
39 resolve(name: string, def?) {
40 trace.debug("resolve {0}", name);
40 trace.debug("resolve {0}", name);
41 const d = this._services[name];
41 const d = this._services[name];
42 if (d === undefined) {
42 if (d === undefined) {
43 if (arguments.length > 1)
43 if (arguments.length > 1)
44 return def;
44 return def;
45 else
45 else
46 throw new Error("Service '" + name + "' isn't found");
46 throw new Error("Service '" + name + "' isn't found");
47 }
47 }
48
48
49 const context = new ActivationContext(this, this._services);
49 const context = new ActivationContext(this, this._services);
50 try {
50 try {
51 return context.activate(d, name);
51 return context.activate(d, name);
52 } catch (error) {
52 } catch (error) {
53 throw new ActivationError(name, context.getStack(), error);
53 throw new ActivationError(name, context.getStack(), error);
54 }
54 }
55 }
55 }
56
56
57 /**
57 /**
58 * @deprecated use resolve() method
58 * @deprecated use resolve() method
59 */
59 */
60 getService() {
60 getService() {
61 return this.resolve.apply(this, arguments);
61 return this.resolve.apply(this, arguments);
62 }
62 }
63
63
64 register(nameOrCollection, service?) {
64 register(nameOrCollection, service?) {
65 if (arguments.length === 1) {
65 if (arguments.length === 1) {
66 const data = nameOrCollection;
66 const data = nameOrCollection;
67 for (const name in data)
67 for (const name in data)
68 this.register(name, data[name]);
68 this.register(name, data[name]);
69 } else {
69 } else {
70 if (!isDescriptor(service))
70 if (!isDescriptor(service))
71 throw new Error("The service parameter must be a descriptor");
71 throw new Error("The service parameter must be a descriptor");
72
72
73 this._services[nameOrCollection] = service;
73 this._services[nameOrCollection] = service;
74 }
74 }
75 return this;
75 return this;
76 }
76 }
77
77
78 onDispose(callback) {
78 onDispose(callback) {
79 if (!(callback instanceof Function))
79 if (!(callback instanceof Function))
80 throw new Error("The callback must be a function");
80 throw new Error("The callback must be a function");
81 this._cleanup.push(callback);
81 this._cleanup.push(callback);
82 }
82 }
83
83
84 dispose() {
84 dispose() {
85 if (this._cleanup) {
85 if (this._cleanup) {
86 for (const f of this._cleanup)
86 for (const f of this._cleanup)
87 f();
87 f();
88 this._cleanup = null;
88 this._cleanup = null;
89 }
89 }
90 }
90 }
91
91
92 /**
92 /**
93 * @param{String|Object} config
93 * @param{String|Object} config
94 * The configuration of the contaier. Can be either a string or an object,
94 * The configuration of the contaier. Can be either a string or an object,
95 * if the configuration is an object it's treated as a collection of
95 * if the configuration is an object it's treated as a collection of
96 * services which will be registed in the contaier.
96 * services which will be registed in the contaier.
97 *
97 *
98 * @param{Function} opts.contextRequire
98 * @param{Function} opts.contextRequire
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?: any, 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, opts && opts.contextRequire, 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 }
110 }
110 }
111
111
112 createChildContainer() {
112 createChildContainer() {
113 return new Container(this);
113 return new Container(this);
114 }
114 }
115
115
116 has(id) {
116 has(id: string | number) {
117 return id in this._cache;
117 return id in this._cache;
118 }
118 }
119
119
120 get(id) {
120 get(id: string | number) {
121 return this._cache[id];
121 return this._cache[id];
122 }
122 }
123
123
124 store(id, value) {
124 store(id: string | number, value: any) {
125 return (this._cache[id] = value);
125 return (this._cache[id] = value);
126 }
126 }
127
127
128 }
128 }
@@ -1,9 +1,11
1 {
1 {
2 "compilerOptions": {
2 "compilerOptions": {
3 "moduleResolution": "node",
3 "moduleResolution": "node",
4 "experimentalDecorators": true,
4 "noEmitOnError": true,
5 "noEmitOnError": true,
5 "listFiles": true,
6 "listFiles": true,
6 "types": [],
7 "types": [],
8 "target": "ES5",
7 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
9 "lib": ["es5", "es2015.promise", "es2015.symbol", "es2015.iterable", "dom", "scripthost"]
8 }
10 }
9 } No newline at end of file
11 }
General Comments 0
You need to be logged in to leave comments. Login now