##// END OF EJS Templates
Minor fixes and improvements...
cin -
r71:600f0201c4ba v1.2.16 default
parent child
Show More
@@ -1,20 +1,28
1 1 HISTORY
2 2 =======
3 3
4 1.2.16
5 ------
6
7 Minor fixes and improvements
8
9 - added `isCancellable` type predicate function to `safe` module
10 - `isString, isNumber, isInteger, isPrimitive` are now type predicates
11
4 12 1.2.0
5 13 -----
6 14
7 15 Major rafactoring, moving to support both browser (rjs) and server (cjs) environments.
8 16
9 17 - dependency injection container ported to typescript
10 18 - sources are split to several sets to provide the ability for the conditional build of the project.
11 19
12 20 1.0.1
13 21 -----
14 22
15 23 First release, intorduces the following features
16 24
17 25 - `di` - dependency injection container
18 26 - `log` - log4 style logging system
19 27 - `text` - simple and fast text templating and formatting
20 28 - `Uuid` - uuid generation traits No newline at end of file
@@ -1,471 +1,471
1 1 {
2 2 "name": "@implab/core",
3 3 "version": "0.0.1-dev",
4 4 "lockfileVersion": 1,
5 5 "requires": true,
6 6 "dependencies": {
7 7 "@types/node": {
8 8 "version": "10.12.18",
9 9 "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
10 10 "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
11 11 "dev": true
12 12 },
13 13 "@types/requirejs": {
14 14 "version": "2.1.31",
15 15 "resolved": "https://registry.npmjs.org/@types/requirejs/-/requirejs-2.1.31.tgz",
16 16 "integrity": "sha512-b2soeyuU76rMbcRJ4e0hEl0tbMhFwZeTC0VZnfuWlfGlk6BwWNsev6kFu/twKABPX29wkX84wU2o+cEJoXsiTw==",
17 17 "dev": true
18 18 },
19 19 "@types/tape": {
20 20 "version": "4.2.33",
21 21 "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz",
22 22 "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==",
23 23 "dev": true,
24 24 "requires": {
25 25 "@types/node": "*"
26 26 }
27 27 },
28 28 "balanced-match": {
29 29 "version": "1.0.0",
30 30 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
31 31 "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
32 32 "dev": true
33 33 },
34 34 "brace-expansion": {
35 35 "version": "1.1.11",
36 36 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
37 37 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
38 38 "dev": true,
39 39 "requires": {
40 40 "balanced-match": "^1.0.0",
41 41 "concat-map": "0.0.1"
42 42 }
43 43 },
44 44 "concat-map": {
45 45 "version": "0.0.1",
46 46 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
47 47 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
48 48 "dev": true
49 49 },
50 50 "core-util-is": {
51 51 "version": "1.0.2",
52 52 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
53 53 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
54 54 "dev": true
55 55 },
56 56 "deep-equal": {
57 57 "version": "0.1.2",
58 58 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.1.2.tgz",
59 59 "integrity": "sha1-skbCuApXCkfBG+HZvRBw7IeLh84=",
60 60 "dev": true
61 61 },
62 62 "define-properties": {
63 63 "version": "1.1.3",
64 64 "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
65 65 "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
66 66 "dev": true,
67 67 "requires": {
68 68 "object-keys": "^1.0.12"
69 69 },
70 70 "dependencies": {
71 71 "object-keys": {
72 72 "version": "1.0.12",
73 73 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
74 74 "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
75 75 "dev": true
76 76 }
77 77 }
78 78 },
79 79 "defined": {
80 80 "version": "0.0.0",
81 81 "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz",
82 82 "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=",
83 83 "dev": true
84 84 },
85 85 "dojo": {
86 86 "version": "1.14.2",
87 87 "resolved": "https://registry.npmjs.org/dojo/-/dojo-1.14.2.tgz",
88 88 "integrity": "sha512-TI+Ytgfh/VfmHWERp45Jte6NFMdoJTPsvUP/uzJUvAXET8FP2h442LePWWJ/q/xZ4V0V8OtdJhx8It/GB+Zbxg==",
89 89 "dev": true
90 90 },
91 91 "duplexer": {
92 92 "version": "0.1.1",
93 "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
93 "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
94 94 "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
95 95 "dev": true
96 96 },
97 97 "es-abstract": {
98 98 "version": "1.13.0",
99 99 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
100 100 "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
101 101 "dev": true,
102 102 "requires": {
103 103 "es-to-primitive": "^1.2.0",
104 104 "function-bind": "^1.1.1",
105 105 "has": "^1.0.3",
106 106 "is-callable": "^1.1.4",
107 107 "is-regex": "^1.0.4",
108 108 "object-keys": "^1.0.12"
109 109 },
110 110 "dependencies": {
111 111 "object-keys": {
112 112 "version": "1.0.12",
113 113 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
114 114 "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
115 115 "dev": true
116 116 }
117 117 }
118 118 },
119 119 "es-to-primitive": {
120 120 "version": "1.2.0",
121 121 "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
122 122 "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
123 123 "dev": true,
124 124 "requires": {
125 125 "is-callable": "^1.1.4",
126 126 "is-date-object": "^1.0.1",
127 127 "is-symbol": "^1.0.2"
128 128 }
129 129 },
130 130 "faucet": {
131 131 "version": "0.0.1",
132 132 "resolved": "https://registry.npmjs.org/faucet/-/faucet-0.0.1.tgz",
133 133 "integrity": "sha1-WX3PHSGJosBiMhtZHo8VHtIDnZw=",
134 134 "dev": true,
135 135 "requires": {
136 136 "defined": "0.0.0",
137 137 "duplexer": "~0.1.1",
138 138 "minimist": "0.0.5",
139 139 "sprintf": "~0.1.3",
140 140 "tap-parser": "~0.4.0",
141 141 "tape": "~2.3.2",
142 142 "through2": "~0.2.3"
143 143 },
144 144 "dependencies": {
145 145 "tape": {
146 146 "version": "2.3.3",
147 "resolved": "http://registry.npmjs.org/tape/-/tape-2.3.3.tgz",
147 "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz",
148 148 "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=",
149 149 "dev": true,
150 150 "requires": {
151 151 "deep-equal": "~0.1.0",
152 152 "defined": "~0.0.0",
153 153 "inherits": "~2.0.1",
154 154 "jsonify": "~0.0.0",
155 155 "resumer": "~0.0.0",
156 156 "through": "~2.3.4"
157 157 }
158 158 }
159 159 }
160 160 },
161 161 "for-each": {
162 162 "version": "0.3.3",
163 163 "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
164 164 "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
165 165 "dev": true,
166 166 "requires": {
167 167 "is-callable": "^1.1.3"
168 168 }
169 169 },
170 170 "fs.realpath": {
171 171 "version": "1.0.0",
172 172 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
173 173 "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
174 174 "dev": true
175 175 },
176 176 "function-bind": {
177 177 "version": "1.1.1",
178 178 "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
179 179 "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
180 180 "dev": true
181 181 },
182 182 "glob": {
183 183 "version": "7.1.3",
184 184 "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
185 185 "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
186 186 "dev": true,
187 187 "requires": {
188 188 "fs.realpath": "^1.0.0",
189 189 "inflight": "^1.0.4",
190 190 "inherits": "2",
191 191 "minimatch": "^3.0.4",
192 192 "once": "^1.3.0",
193 193 "path-is-absolute": "^1.0.0"
194 194 }
195 195 },
196 196 "has": {
197 197 "version": "1.0.3",
198 198 "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
199 199 "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
200 200 "dev": true,
201 201 "requires": {
202 202 "function-bind": "^1.1.1"
203 203 }
204 204 },
205 205 "has-symbols": {
206 206 "version": "1.0.0",
207 207 "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
208 208 "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
209 209 "dev": true
210 210 },
211 211 "inflight": {
212 212 "version": "1.0.6",
213 213 "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
214 214 "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
215 215 "dev": true,
216 216 "requires": {
217 217 "once": "^1.3.0",
218 218 "wrappy": "1"
219 219 }
220 220 },
221 221 "inherits": {
222 222 "version": "2.0.3",
223 223 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
224 224 "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
225 225 "dev": true
226 226 },
227 227 "is-callable": {
228 228 "version": "1.1.4",
229 229 "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
230 230 "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
231 231 "dev": true
232 232 },
233 233 "is-date-object": {
234 234 "version": "1.0.1",
235 235 "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
236 236 "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
237 237 "dev": true
238 238 },
239 239 "is-regex": {
240 240 "version": "1.0.4",
241 241 "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
242 242 "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
243 243 "dev": true,
244 244 "requires": {
245 245 "has": "^1.0.1"
246 246 }
247 247 },
248 248 "is-symbol": {
249 249 "version": "1.0.2",
250 250 "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
251 251 "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
252 252 "dev": true,
253 253 "requires": {
254 254 "has-symbols": "^1.0.0"
255 255 }
256 256 },
257 257 "isarray": {
258 258 "version": "0.0.1",
259 259 "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
260 260 "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
261 261 "dev": true
262 262 },
263 263 "jsonify": {
264 264 "version": "0.0.0",
265 265 "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
266 266 "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
267 267 "dev": true
268 268 },
269 269 "minimatch": {
270 270 "version": "3.0.4",
271 271 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
272 272 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
273 273 "dev": true,
274 274 "requires": {
275 275 "brace-expansion": "^1.1.7"
276 276 }
277 277 },
278 278 "minimist": {
279 279 "version": "0.0.5",
280 "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
280 "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
281 281 "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=",
282 282 "dev": true
283 283 },
284 284 "object-inspect": {
285 285 "version": "1.6.0",
286 286 "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
287 287 "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==",
288 288 "dev": true
289 289 },
290 290 "object-keys": {
291 291 "version": "0.4.0",
292 292 "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
293 293 "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
294 294 "dev": true
295 295 },
296 296 "once": {
297 297 "version": "1.4.0",
298 298 "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
299 299 "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
300 300 "dev": true,
301 301 "requires": {
302 302 "wrappy": "1"
303 303 }
304 304 },
305 305 "path-is-absolute": {
306 306 "version": "1.0.1",
307 307 "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
308 308 "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
309 309 "dev": true
310 310 },
311 311 "path-parse": {
312 312 "version": "1.0.6",
313 313 "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
314 314 "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
315 315 "dev": true
316 316 },
317 317 "readable-stream": {
318 318 "version": "1.1.14",
319 "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
319 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
320 320 "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
321 321 "dev": true,
322 322 "requires": {
323 323 "core-util-is": "~1.0.0",
324 324 "inherits": "~2.0.1",
325 325 "isarray": "0.0.1",
326 326 "string_decoder": "~0.10.x"
327 327 }
328 328 },
329 329 "requirejs": {
330 330 "version": "2.3.6",
331 331 "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
332 332 "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
333 333 "dev": true
334 334 },
335 335 "resolve": {
336 336 "version": "1.7.1",
337 337 "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
338 338 "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
339 339 "dev": true,
340 340 "requires": {
341 341 "path-parse": "^1.0.5"
342 342 }
343 343 },
344 344 "resumer": {
345 345 "version": "0.0.0",
346 346 "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
347 347 "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
348 348 "dev": true,
349 349 "requires": {
350 350 "through": "~2.3.4"
351 351 }
352 352 },
353 353 "sprintf": {
354 354 "version": "0.1.5",
355 355 "resolved": "https://registry.npmjs.org/sprintf/-/sprintf-0.1.5.tgz",
356 356 "integrity": "sha1-j4PjmpMXwaUCy324BQ5Rxnn27c8=",
357 357 "dev": true
358 358 },
359 359 "string.prototype.trim": {
360 360 "version": "1.1.2",
361 361 "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
362 362 "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
363 363 "dev": true,
364 364 "requires": {
365 365 "define-properties": "^1.1.2",
366 366 "es-abstract": "^1.5.0",
367 367 "function-bind": "^1.0.2"
368 368 }
369 369 },
370 370 "string_decoder": {
371 371 "version": "0.10.31",
372 "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
372 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
373 373 "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
374 374 "dev": true
375 375 },
376 376 "tap-parser": {
377 377 "version": "0.4.3",
378 378 "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-0.4.3.tgz",
379 379 "integrity": "sha1-pOrhkMENdsehEZIf84u+TVjwnuo=",
380 380 "dev": true,
381 381 "requires": {
382 382 "inherits": "~2.0.1",
383 383 "readable-stream": "~1.1.11"
384 384 }
385 385 },
386 386 "tape": {
387 387 "version": "4.9.2",
388 388 "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.2.tgz",
389 389 "integrity": "sha512-lPXKRKILZ1kZaUy5ynWKs8ATGSUO7HAFHCFnBam6FaGSqPdOwMWbxXHq4EXFLE8WRTleo/YOMXkaUTRmTB1Fiw==",
390 390 "dev": true,
391 391 "requires": {
392 392 "deep-equal": "~1.0.1",
393 393 "defined": "~1.0.0",
394 394 "for-each": "~0.3.3",
395 395 "function-bind": "~1.1.1",
396 396 "glob": "~7.1.2",
397 397 "has": "~1.0.3",
398 398 "inherits": "~2.0.3",
399 399 "minimist": "~1.2.0",
400 400 "object-inspect": "~1.6.0",
401 401 "resolve": "~1.7.1",
402 402 "resumer": "~0.0.0",
403 403 "string.prototype.trim": "~1.1.2",
404 404 "through": "~2.3.8"
405 405 },
406 406 "dependencies": {
407 407 "deep-equal": {
408 408 "version": "1.0.1",
409 409 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
410 410 "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
411 411 "dev": true
412 412 },
413 413 "defined": {
414 414 "version": "1.0.0",
415 415 "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
416 416 "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
417 417 "dev": true
418 418 },
419 419 "minimist": {
420 420 "version": "1.2.0",
421 421 "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
422 422 "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
423 423 "dev": true
424 424 }
425 425 }
426 426 },
427 427 "through": {
428 428 "version": "2.3.8",
429 429 "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
430 430 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
431 431 "dev": true
432 432 },
433 433 "through2": {
434 434 "version": "0.2.3",
435 "resolved": "http://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
435 "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
436 436 "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
437 437 "dev": true,
438 438 "requires": {
439 439 "readable-stream": "~1.1.9",
440 440 "xtend": "~2.1.1"
441 441 }
442 442 },
443 443 "tslib": {
444 444 "version": "1.9.3",
445 445 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
446 446 "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
447 447 "dev": true
448 448 },
449 449 "typescript": {
450 450 "version": "3.2.2",
451 451 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
452 452 "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==",
453 453 "dev": true
454 454 },
455 455 "wrappy": {
456 456 "version": "1.0.2",
457 457 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
458 458 "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
459 459 "dev": true
460 460 },
461 461 "xtend": {
462 462 "version": "2.1.2",
463 463 "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
464 464 "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
465 465 "dev": true,
466 466 "requires": {
467 467 "object-keys": "~0.4.0"
468 468 }
469 469 }
470 470 }
471 471 }
@@ -1,74 +1,41
1 1 import { Uuid } from "../Uuid";
2 2 import { argumentNotEmptyString, getGlobal, isNullOrEmptyString } from "../safe";
3 import { TraceSource, DebugLevel } from "../log/TraceSource";
3 import { TraceSource } from "../log/TraceSource";
4 4 import m = require("module");
5 5
6 6 const sandboxId = Uuid();
7 7 define(sandboxId, ["require"], r => r);
8 8
9 9 // tslint:disable-next-line:no-var-requires
10 10 const globalRequire = getGlobal().require as Require;
11 11
12 12 const trace = TraceSource.get(m.id);
13 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 14 class ModuleResolver {
40 15 _base: string;
41 16 _require: Require;
42 17
43 18 constructor(req: Require, base?: string) {
44 19 this._base = base;
45 this._require = req || globalRequire;
20 this._require = req;
46 21 }
47 22
48 23 resolve(moduleName: string) {
49 24 argumentNotEmptyString(moduleName, "moduleName");
50 25 const resolvedName = moduleName[0] === "." && this._base ? [this._base, moduleName].join("/") : moduleName;
51 26 trace.debug(`${moduleName} -> ${resolvedName}`);
52 27
53 28 const req = this._require;
54 29
55 30 return new Promise<any>((cb, eb) => {
56 31 req([resolvedName], cb, eb);
57 32 });
58 33 }
59 34 }
60 35
61 export async function makeResolver(moduleName: string, contextRequire: Require) {
62 trace.debug(
63 "makeResolver moduleName={0}, contextRequire={1}",
64 moduleName || "<nil>",
65 contextRequire ? typeof (contextRequire) : "<nil>"
66 );
36 export function makeResolver(moduleName: string, contextRequire: Require) {
37 const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
67 38
68 const nestedRequire = isNullOrEmptyString(moduleName) ? null : await createContextRequire(moduleName);
69
70 // const base = moduleName && moduleName.split("/").slice(0, -1).join("/");
71
72 const resolver = new ModuleResolver(nestedRequire, null);
39 const resolver = new ModuleResolver(contextRequire, base);
73 40 return (id: string) => resolver.resolve(id);
74 41 }
@@ -1,348 +1,348
1 1 import {
2 2 ServiceRegistration,
3 3 TypeRegistration,
4 4 FactoryRegistration,
5 5 ServiceMap,
6 6 isDescriptor,
7 7 isDependencyRegistration,
8 8 DependencyRegistration,
9 9 ValueRegistration,
10 10 ActivationType,
11 11 isValueRegistration,
12 12 isTypeRegistration,
13 13 isFactoryRegistration
14 14 } from "./interfaces";
15 15
16 16 import { argumentNotEmptyString, isPrimitive, isPromise, delegate, argumentOfType, argumentNotNull, get } from "../safe";
17 17 import { AggregateDescriptor } from "./AggregateDescriptor";
18 18 import { ValueDescriptor } from "./ValueDescriptor";
19 19 import { Container } from "./Container";
20 20 import { ReferenceDescriptor } from "./ReferenceDescriptor";
21 21 import { TypeServiceDescriptor } from "./TypeServiceDescriptor";
22 22 import { FactoryServiceDescriptor } from "./FactoryServiceDescriptor";
23 23 import { TraceSource } from "../log/TraceSource";
24 24 import { ConfigError } from "./ConfigError";
25 25 import { Cancellation } from "../Cancellation";
26 26 import { makeResolver } from "./ResolverHelper";
27 27 import { ICancellation } from "../interfaces";
28 28
29 29 const trace = TraceSource.get("@implab/core/di/Configuration");
30 30
31 31 async function mapAll(data: object | any[], map?: (v, k) => any): Promise<any> {
32 32 if (data instanceof Array) {
33 33 return Promise.all(map ? data.map(map) : data);
34 34 } else {
35 35 const keys = Object.keys(data);
36 36
37 37 const o: any = {};
38 38
39 39 await Promise.all(keys.map(async k => {
40 40 const v = map ? map(data[k], k) : data[k];
41 41 o[k] = isPromise(v) ? await v : v;
42 42 }));
43 43
44 44 return o;
45 45 }
46 46 }
47 47
48 48 export type ModuleResolver = (moduleName: string, ct?: ICancellation) => any;
49 49
50 50 type _key = string | number;
51 51
52 52 export class Configuration {
53 53
54 54 _hasInnerDescriptors = false;
55 55
56 56 _container: Container;
57 57
58 58 _path: Array<_key>;
59 59
60 60 _configName: string;
61 61
62 62 _require: ModuleResolver;
63 63
64 64 constructor(container: Container) {
65 65 argumentNotNull(container, container);
66 66 this._container = container;
67 67 this._path = [];
68 68 }
69 69
70 70 async loadConfiguration(moduleName: string, contextRequire?: any, ct = Cancellation.none) {
71 71 argumentNotEmptyString(moduleName, "moduleName");
72 72
73 73 trace.log(
74 74 "loadConfiguration moduleName={0}, contextRequire={1}",
75 75 moduleName,
76 76 contextRequire ? typeof (contextRequire) : "<nil>"
77 77 );
78 78
79 79 this._configName = moduleName;
80 80
81 81 const r = await makeResolver(null, contextRequire);
82 82
83 83 const config = await r(moduleName, ct);
84 84
85 85 await this._applyConfiguration(
86 86 config,
87 87 await makeResolver(moduleName, contextRequire),
88 88 ct
89 89 );
90 90 }
91 91
92 92 async applyConfiguration(data: object, contextRequire?: any, ct = Cancellation.none) {
93 93 argumentNotNull(data, "data");
94 94
95 95 await this._applyConfiguration(data, await makeResolver(void (0), contextRequire), ct);
96 96 }
97 97
98 98 async _applyConfiguration(data: object, resolver?: ModuleResolver, ct = Cancellation.none) {
99 99 trace.log("applyConfiguration");
100 100
101 101 this._configName = "$";
102 102
103 103 if (resolver)
104 104 this._require = resolver;
105 105
106 106 let services: ServiceMap;
107 107
108 108 try {
109 109 services = await this._visitRegistrations(data, "$");
110 110 } catch (e) {
111 111 throw this._makeError(e);
112 112 }
113 113
114 114 this._container.register(services);
115 115 }
116 116
117 117 _makeError(inner) {
118 118 const e = new ConfigError("Failed to load configuration", inner);
119 119 e.configName = this._configName;
120 120 e.path = this._makePath();
121 121 return e;
122 122 }
123 123
124 124 _makePath() {
125 125 return this._path
126 126 .reduce(
127 127 (prev, cur) => typeof cur === "number" ?
128 128 `${prev}[${cur}]` :
129 129 `${prev}.${cur}`
130 130 )
131 131 .toString();
132 132 }
133 133
134 134 async _resolveType(moduleName: string, localName: string) {
135 135 trace.log("resolveType moduleName={0}, localName={1}", moduleName, localName);
136 136 try {
137 137 const m = await this._loadModule(moduleName);
138 138 return localName ? get(localName, m) : m;
139 139 } catch (e) {
140 140 trace.error("Failed to resolve type moduleName={0}, localName={1}", moduleName, localName);
141 141 throw e;
142 142 }
143 143 }
144 144
145 145 _loadModule(moduleName: string) {
146 146 trace.debug("loadModule {0}", moduleName);
147 147
148 148 return this._require(moduleName);
149 149 }
150 150
151 151 async _visitRegistrations(data, name: _key) {
152 152 this._enter(name);
153 153
154 154 if (data.constructor &&
155 155 data.constructor.prototype !== Object.prototype)
156 156 throw new Error("Configuration must be a simple object");
157 157
158 158 const o: ServiceMap = {};
159 159 const keys = Object.keys(data);
160 160
161 161 const services = await mapAll(data, async (v, k) => {
162 162 const d = await this._visit(v, k);
163 163 return isDescriptor(d) ? d : new AggregateDescriptor(d);
164 164 }) as ServiceMap;
165 165
166 166 this._leave();
167 167
168 168 return services;
169 169 }
170 170
171 171 _enter(name: _key) {
172 172 this._path.push(name);
173 173 trace.debug(">{0}", name);
174 174 }
175 175
176 176 _leave() {
177 177 const name = this._path.pop();
178 178 trace.debug("<{0}", name);
179 179 }
180 180
181 _visit(data, name: string): Promise<any> {
181 async _visit(data, name: string) {
182 182 if (isPrimitive(data) || isDescriptor(data))
183 183 return data;
184 184
185 185 if (isDependencyRegistration(data)) {
186 186 return this._visitDependencyRegistration(data, name);
187 187 } else if (isValueRegistration(data)) {
188 188 return this._visitValueRegistration(data, name);
189 189 } else if (isTypeRegistration(data)) {
190 190 return this._visitTypeRegistration(data, name);
191 191 } else if (isFactoryRegistration(data)) {
192 192 return this._visitFactoryRegistration(data, name);
193 193 } else if (data instanceof Array) {
194 194 return this._visitArray(data, name);
195 195 }
196 196
197 197 return this._visitObject(data, name);
198 198 }
199 199
200 200 async _visitObject(data: object, name: _key) {
201 201 if (data.constructor &&
202 202 data.constructor.prototype !== Object.prototype)
203 203 return new ValueDescriptor(data);
204 204
205 205 this._enter(name);
206 206
207 207 const v = await mapAll(data, delegate(this, "_visit"));
208 208
209 209 // TODO: handle inline descriptors properly
210 210 // const ex = {
211 211 // activate(ctx) {
212 212 // const value = ctx.activate(this.prop, "prop");
213 213 // // some code
214 214 // },
215 215 // // will be turned to ReferenceDescriptor
216 216 // prop: { $dependency: "depName" }
217 217 // };
218 218
219 219 this._leave();
220 220 return v;
221 221 }
222 222
223 223 async _visitArray(data: any[], name: _key) {
224 224 if (data.constructor &&
225 225 data.constructor.prototype !== Array.prototype)
226 226 return new ValueDescriptor(data);
227 227
228 228 this._enter(name);
229 229
230 230 const v = await mapAll(data, delegate(this, "_visit"));
231 231 this._leave();
232 232
233 233 return v;
234 234 }
235 235
236 236 _makeServiceParams(data: ServiceRegistration) {
237 237 const opts: any = {
238 238 owner: this._container
239 239 };
240 240 if (data.services)
241 241 opts.services = this._visitRegistrations(data.services, "services");
242 242
243 243 if (data.inject) {
244 244 this._enter("inject");
245 245 opts.inject = mapAll(
246 246 data.inject instanceof Array ?
247 247 data.inject :
248 248 [data.inject],
249 249 delegate(this, "_visitObject")
250 250 );
251 251 this._leave();
252 252 }
253 253
254 254 if ("params" in data)
255 255 opts.params = data.params instanceof Array ?
256 256 this._visitArray(data.params, "params") :
257 257 this._visit(data.params, "params");
258 258
259 259 if (data.activation) {
260 260 if (typeof (data.activation) === "string") {
261 261 switch (data.activation.toLowerCase()) {
262 262 case "singleton":
263 263 opts.activation = ActivationType.Singleton;
264 264 break;
265 265 case "container":
266 266 opts.activation = ActivationType.Container;
267 267 break;
268 268 case "hierarchy":
269 269 opts.activation = ActivationType.Hierarchy;
270 270 break;
271 271 case "context":
272 272 opts.activation = ActivationType.Context;
273 273 break;
274 274 case "call":
275 275 opts.activation = ActivationType.Call;
276 276 break;
277 277 default:
278 278 throw new Error("Unknown activation type: " +
279 279 data.activation);
280 280 }
281 281 } else {
282 282 opts.activation = Number(data.activation);
283 283 }
284 284 }
285 285
286 286 if (data.cleanup)
287 287 opts.cleanup = data.cleanup;
288 288
289 289 return opts;
290 290 }
291 291
292 292 async _visitValueRegistration(data: ValueRegistration, name: _key) {
293 293 this._enter(name);
294 294 const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value);
295 295 this._leave();
296 296 return d;
297 297 }
298 298
299 299 async _visitDependencyRegistration(data: DependencyRegistration, name: _key) {
300 300 argumentNotEmptyString(data && data.$dependency, "data.$dependency");
301 301 this._enter(name);
302 302 const d = new ReferenceDescriptor({
303 303 name: data.$dependency,
304 304 lazy: data.lazy,
305 305 optional: data.optional,
306 306 default: data.default,
307 307 services: data.services && await this._visitRegistrations(data.services, "services")
308 308 });
309 309 this._leave();
310 310 return d;
311 311 }
312 312
313 313 async _visitTypeRegistration(data: TypeRegistration, name: _key) {
314 314 argumentNotNull(data.$type, "data.$type");
315 315 this._enter(name);
316 316
317 317 const opts = this._makeServiceParams(data);
318 318 if (data.$type instanceof Function) {
319 319 opts.type = data.$type;
320 320 } else {
321 321 const [moduleName, typeName] = data.$type.split(":", 2);
322 322 opts.type = this._resolveType(moduleName, typeName);
323 323 }
324 324
325 325 const d = new TypeServiceDescriptor(
326 326 await mapAll(opts)
327 327 );
328 328
329 329 this._leave();
330 330
331 331 return d;
332 332 }
333 333
334 334 async _visitFactoryRegistration(data: FactoryRegistration, name: _key) {
335 335 argumentOfType(data.$factory, Function, "data.$factory");
336 336 this._enter(name);
337 337
338 338 const opts = this._makeServiceParams(data);
339 339 opts.factory = data.$factory;
340 340
341 341 const d = new FactoryServiceDescriptor(
342 342 await mapAll(opts)
343 343 );
344 344
345 345 this._leave();
346 346 return d;
347 347 }
348 348 }
@@ -1,354 +1,360
1 import { ICancellable } from "./interfaces";
2
1 3 let _nextOid = 0;
2 4 const _oid = typeof Symbol === "function" ?
3 5 Symbol("__implab__oid__") :
4 6 "__implab__oid__";
5 7
6 8 declare const window: any;
7 9 declare const global: any;
8 10
9 11 export function oid(instance: object): string {
10 12 if (isNull(instance))
11 13 return null;
12 14
13 15 if (_oid in instance)
14 16 return instance[_oid];
15 17 else
16 18 return (instance[_oid] = "oid_" + (++_nextOid));
17 19 }
18 20
19 21 export function argumentNotNull(arg, name) {
20 22 if (arg === null || arg === undefined)
21 23 throw new Error("The argument " + name + " can't be null or undefined");
22 24 }
23 25
24 26 export function argumentNotEmptyString(arg, name) {
25 27 if (typeof (arg) !== "string" || !arg.length)
26 28 throw new Error("The argument '" + name + "' must be a not empty string");
27 29 }
28 30
29 31 export function argumentNotEmptyArray(arg, name) {
30 32 if (!(arg instanceof Array) || !arg.length)
31 33 throw new Error("The argument '" + name + "' must be a not empty array");
32 34 }
33 35
34 36 export function argumentOfType(arg, type, name) {
35 37 if (!(arg instanceof type))
36 38 throw new Error("The argument '" + name + "' type doesn't match");
37 39 }
38 40
39 41 export function isNull(arg) {
40 42 return (arg === null || arg === undefined);
41 43 }
42 44
43 export function isPrimitive(arg) {
45 export function isPrimitive(arg): arg is string | number | boolean | undefined | null {
44 46 return (arg === null || arg === undefined || typeof (arg) === "string" ||
45 47 typeof (arg) === "number" || typeof (arg) === "boolean");
46 48 }
47 49
48 export function isInteger(arg) {
50 export function isInteger(arg): arg is number {
49 51 return parseInt(arg, 10) === arg;
50 52 }
51 53
52 export function isNumber(arg) {
54 export function isNumber(arg): arg is number {
53 55 return parseFloat(arg) === arg;
54 56 }
55 57
56 export function isString(val) {
58 export function isString(val): val is string {
57 59 return typeof (val) === "string" || val instanceof String;
58 60 }
59 61
60 62 export function isPromise(val): val is PromiseLike<any> {
61 63 return val && typeof val.then === "function";
62 64 }
63 65
66 export function isCancellable(val): val is ICancellable {
67 return val && typeof val.cancel === "function";
68 }
69
64 70 export function isNullOrEmptyString(str) {
65 71 if (str === null || str === undefined ||
66 72 ((typeof (str) === "string" || str instanceof String) && str.length === 0))
67 73 return true;
68 74 }
69 75
70 76 export function isNotEmptyArray(arg): arg is Array<any> {
71 77 return (arg instanceof Array && arg.length > 0);
72 78 }
73 79
74 80 function _isStrictMode() {
75 81 return !this;
76 82 }
77 83
78 84 function _getNonStrictGlobal() {
79 85 return this;
80 86 }
81 87
82 88 export function getGlobal() {
83 89 // in es3 we can't use indirect call to eval, since it will
84 90 // be executed in the current call context.
85 91 if (!_isStrictMode()) {
86 92 return _getNonStrictGlobal();
87 93 } else {
88 94 // tslint:disable-next-line:no-eval
89 95 return eval.call(null, "this");
90 96 }
91 97 }
92 98
93 99 export function get(member: string, context?: object) {
94 100 argumentNotEmptyString(member, "member");
95 101 let that = context || getGlobal();
96 102 const parts = member.split(".");
97 103 for (const m of parts) {
98 104 if (!m)
99 105 continue;
100 106 if (isNull(that = that[m]))
101 107 break;
102 108 }
103 109 return that;
104 110 }
105 111
106 112 /**
107 113 * Выполняет метод для каждого элемента массива, останавливается, когда
108 114 * либо достигнут конец массива, либо функция <c>cb</c> вернула
109 115 * значение.
110 116 *
111 117 * @param {Array | Object} obj массив элементов для просмотра
112 118 * @param {Function} cb функция, вызываемая для каждого элемента
113 119 * @param {Object} thisArg значение, которое будет передано в качестве
114 120 * <c>this</c> в <c>cb</c>.
115 121 * @returns Результат вызова функции <c>cb</c>, либо <c>undefined</c>
116 122 * если достигнут конец массива.
117 123 */
118 124 export function each(obj, cb, thisArg?) {
119 125 argumentNotNull(cb, "cb");
120 126 if (obj instanceof Array) {
121 127 for (let i = 0; i < obj.length; i++) {
122 128 const x = cb.call(thisArg, obj[i], i);
123 129 if (x !== undefined)
124 130 return x;
125 131 }
126 132 } else {
127 133 const keys = Object.keys(obj);
128 134 for (const k of keys) {
129 135 const x = cb.call(thisArg, obj[k], k);
130 136 if (x !== undefined)
131 137 return x;
132 138 }
133 139 }
134 140 }
135 141
136 142 /** Copies property values from a source object to the destination and returns
137 143 * the destination onject.
138 144 *
139 145 * @param dest The destination object into which properties from the source
140 146 * object will be copied.
141 147 * @param source The source of values which will be copied to the destination
142 148 * object.
143 149 * @param template An optional parameter specifies which properties should be
144 150 * copied from the source and how to map them to the destination. If the
145 151 * template is an array it contains the list of property names to copy from the
146 152 * source to the destination. In case of object the templates contains the map
147 153 * where keys are property names in the source and the values are property
148 154 * names in the destination object. If the template isn't specified then the
149 155 * own properties of the source are entirely copied to the destination.
150 156 *
151 157 */
152 158 export function mixin<T, S>(dest: T, source: S, template?: string[] | object): T & S {
153 159 argumentNotNull(dest, "to");
154 160 const _res = dest as T & S;
155 161
156 162 if (isPrimitive(source))
157 163 return _res;
158 164
159 165 if (template instanceof Array) {
160 166 for (const p of template) {
161 167 if (p in source)
162 168 _res[p] = source[p];
163 169 }
164 170 } else if (template) {
165 171 const keys = Object.keys(source);
166 172 for (const p of keys) {
167 173 if (p in template)
168 174 _res[template[p]] = source[p];
169 175 }
170 176 } else {
171 177 const keys = Object.keys(source);
172 178 for (const p of keys)
173 179 _res[p] = source[p];
174 180 }
175 181
176 182 return _res;
177 183 }
178 184
179 185 /** Wraps the specified function to emulate an asynchronous execution.
180 186 * @param{Object} thisArg [Optional] Object which will be passed as 'this' to the function.
181 187 * @param{Function|String} fn [Required] Function wich will be wrapped.
182 188 */
183 189 export function async(_fn: (...args: any[]) => any, thisArg): (...args: any[]) => PromiseLike<any> {
184 190 let fn = _fn;
185 191
186 192 if (arguments.length === 2 && !(fn instanceof Function))
187 193 fn = thisArg[fn];
188 194
189 195 if (fn == null)
190 196 throw new Error("The function must be specified");
191 197
192 198 function wrapresult(x, e?): PromiseLike<any> {
193 199 if (e) {
194 200 return {
195 201 then(cb, eb) {
196 202 try {
197 203 return eb ? wrapresult(eb(e)) : this;
198 204 } catch (e2) {
199 205 return wrapresult(null, e2);
200 206 }
201 207 }
202 208 };
203 209 } else {
204 210 if (x && x.then)
205 211 return x;
206 212 return {
207 213 then(cb) {
208 214 try {
209 215 return cb ? wrapresult(cb(x)) : this;
210 216 } catch (e2) {
211 217 return wrapresult(e2);
212 218 }
213 219 }
214 220 };
215 221 }
216 222 }
217 223
218 224 return (...args) => {
219 225 try {
220 226 return wrapresult(fn.apply(thisArg, args));
221 227 } catch (e) {
222 228 return wrapresult(null, e);
223 229 }
224 230 };
225 231 }
226 232
227 233 type _AnyFn = (...args) => any;
228 234
229 235 export function delegate<T, K extends keyof T>(target: T, _method: (K | _AnyFn)) {
230 236 let method;
231 237
232 238 if (!(_method instanceof Function)) {
233 239 argumentNotNull(target, "target");
234 240 method = target[_method];
235 241 if (!(method instanceof Function))
236 242 throw new Error("'method' argument must be a Function or a method name");
237 243 } else {
238 244 method = _method;
239 245 }
240 246
241 247 return (...args) => {
242 248 return method.apply(target, args);
243 249 };
244 250 }
245 251
246 252 /**
247 253 * Для каждого элемента массива вызывает указанную функцию и сохраняет
248 254 * возвращенное значение в массиве результатов.
249 255 *
250 256 * @remarks cb может выполняться асинхронно, при этом одновременно будет
251 257 * только одна операция.
252 258 *
253 259 * @async
254 260 */
255 261 export function pmap(items, cb) {
256 262 argumentNotNull(cb, "cb");
257 263
258 264 if (isPromise(items))
259 265 return items.then(data => pmap(data, cb));
260 266
261 267 if (isNull(items) || !items.length)
262 268 return items;
263 269
264 270 let i = 0;
265 271 const result = [];
266 272
267 273 function next() {
268 274 let r;
269 275 let ri;
270 276
271 277 function chain(x) {
272 278 result[ri] = x;
273 279 return next();
274 280 }
275 281
276 282 while (i < items.length) {
277 283 r = cb(items[i], i);
278 284 ri = i;
279 285 i++;
280 286 if (isPromise(r)) {
281 287 return r.then(chain);
282 288 } else {
283 289 result[ri] = r;
284 290 }
285 291 }
286 292 return result;
287 293 }
288 294
289 295 return next();
290 296 }
291 297
292 298 export function pfor(items, cb) {
293 299 argumentNotNull(cb, "cb");
294 300
295 301 if (isPromise(items))
296 302 return items.then(data => {
297 303 return pmap(data, cb);
298 304 });
299 305
300 306 if (isNull(items) || !items.length)
301 307 return items;
302 308
303 309 let i = 0;
304 310
305 311 function next() {
306 312 while (i < items.length) {
307 313 const r = cb(items[i], i);
308 314 i++;
309 315 if (isPromise(r))
310 316 return r.then(next);
311 317 }
312 318 }
313 319
314 320 return next();
315 321 }
316 322
317 323 /**
318 324 * Выбирает первый элемент из последовательности, или обещания, если в
319 325 * качестве параметра используется обещание, оно должно вернуть массив.
320 326 *
321 327 * @param {Function} cb обработчик результата, ему будет передан первый
322 328 * элемент последовательности в случае успеха
323 329 * @param {Function} err обработчик исключения, если массив пустой, либо
324 330 * не массив
325 331 *
326 332 * @remarks Если не указаны ни cb ни err, тогда функция вернет либо
327 333 * обещание, либо первый элемент.
328 334 * @async
329 335 */
330 336 export function first(sequence, cb: (x) => any, err: (x) => any) {
331 337 if (sequence) {
332 338 if (isPromise(sequence)) {
333 339 return sequence.then(res => first(res, cb, err));
334 340 } else if (sequence && "length" in sequence) {
335 341 if (sequence.length === 0) {
336 342 if (err)
337 343 return err(new Error("The sequence is empty"));
338 344 else
339 345 throw new Error("The sequence is empty");
340 346 }
341 347 return cb ? cb(sequence[0]) : sequence[0];
342 348 }
343 349 }
344 350
345 351 if (err)
346 352 return err(new Error("The sequence is required"));
347 353 else
348 354 throw new Error("The sequence is required");
349 355 }
350 356
351 357 export function destroy(d) {
352 358 if (d && "destroy" in d)
353 359 d.destroy();
354 360 }
General Comments 0
You need to be logged in to leave comments. Login now