@joist/di 4.2.3-next.12 → 4.2.3-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -85
- package/package.json +1 -1
- package/src/lib/dom/injectable-el.ts +2 -4
- package/src/lib/lifecycle.test.ts +1 -165
- package/src/lib/lifecycle.ts +13 -30
- package/src/lib/metadata.ts +7 -12
- package/target/lib/dom/injectable-el.d.ts +2 -3
- package/target/lib/dom/injectable-el.js.map +1 -1
- package/target/lib/lifecycle.d.ts +4 -4
- package/target/lib/lifecycle.js +7 -19
- package/target/lib/lifecycle.js.map +1 -1
- package/target/lib/lifecycle.test.js +0 -239
- package/target/lib/lifecycle.test.js.map +1 -1
- package/target/lib/metadata.d.ts +4 -14
- package/target/lib/metadata.js.map +1 -1
package/README.md
CHANGED
|
@@ -38,7 +38,6 @@ npm i @joist/di
|
|
|
38
38
|
## Injectors
|
|
39
39
|
|
|
40
40
|
Injectors are the core of the dependency injection system. They:
|
|
41
|
-
|
|
42
41
|
- Create and manage service instances
|
|
43
42
|
- Handle dependency resolution
|
|
44
43
|
- Maintain a hierarchy of injectors
|
|
@@ -104,7 +103,7 @@ class ApiService {
|
|
|
104
103
|
|
|
105
104
|
getData() {
|
|
106
105
|
return this.#http()
|
|
107
|
-
.fetch(
|
|
106
|
+
.fetch('/api/v1/users')
|
|
108
107
|
.then((res) => res.json());
|
|
109
108
|
}
|
|
110
109
|
}
|
|
@@ -112,22 +111,22 @@ class ApiService {
|
|
|
112
111
|
|
|
113
112
|
```ts
|
|
114
113
|
// services.test.ts
|
|
115
|
-
test(
|
|
114
|
+
test('should return json', async () => {
|
|
116
115
|
class MockHttpService extends HttpService {
|
|
117
116
|
async fetch() {
|
|
118
|
-
return Response.json({ fname:
|
|
117
|
+
return Response.json({ fname: 'Danny', lname: 'Blue' });
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
const app = new Injector({
|
|
123
|
-
providers: [[HttpService, { use: MockHttpService }]]
|
|
122
|
+
providers: [[HttpService, { use: MockHttpService }]]
|
|
124
123
|
});
|
|
125
124
|
const api = app.inject(ApiService);
|
|
126
125
|
|
|
127
126
|
const res = await api.getData();
|
|
128
127
|
|
|
129
|
-
assert.equals(res.fname,
|
|
130
|
-
assert.equals(res.lname,
|
|
128
|
+
assert.equals(res.fname, 'Danny');
|
|
129
|
+
assert.equals(res.lname, 'Blue');
|
|
131
130
|
});
|
|
132
131
|
```
|
|
133
132
|
|
|
@@ -149,7 +148,7 @@ class ConsoleLogger implements Logger {
|
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
@injectable({
|
|
152
|
-
providers: [[Logger, { use: ConsoleLogger }]]
|
|
151
|
+
providers: [[Logger, { use: ConsoleLogger }]]
|
|
153
152
|
})
|
|
154
153
|
class MyService {}
|
|
155
154
|
```
|
|
@@ -169,13 +168,13 @@ const app = new Injector([
|
|
|
169
168
|
factory() {
|
|
170
169
|
const params = new URLSearchParams(window.location.search);
|
|
171
170
|
|
|
172
|
-
if (params.has(
|
|
171
|
+
if (params.has('debug')) {
|
|
173
172
|
return console;
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
return new Logger(); // noop logger
|
|
177
|
-
}
|
|
178
|
-
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
179
178
|
]);
|
|
180
179
|
```
|
|
181
180
|
|
|
@@ -205,9 +204,9 @@ const app = new Injector([
|
|
|
205
204
|
factory(i) {
|
|
206
205
|
const logger = i.inject(Logger);
|
|
207
206
|
return new Feature(logger);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
]
|
|
211
210
|
]);
|
|
212
211
|
```
|
|
213
212
|
|
|
@@ -217,15 +216,15 @@ In most cases, a token is any constructable class. There are cases where you mig
|
|
|
217
216
|
|
|
218
217
|
```ts
|
|
219
218
|
// Token that resolves to a string
|
|
220
|
-
const URL_TOKEN = new StaticToken<string>(
|
|
219
|
+
const URL_TOKEN = new StaticToken<string>('app_url');
|
|
221
220
|
|
|
222
221
|
const app = new Injector([
|
|
223
222
|
[
|
|
224
223
|
URL_TOKEN,
|
|
225
224
|
{
|
|
226
|
-
factory: () =>
|
|
227
|
-
}
|
|
228
|
-
]
|
|
225
|
+
factory: () => '/my-app-url/'
|
|
226
|
+
}
|
|
227
|
+
]
|
|
229
228
|
]);
|
|
230
229
|
```
|
|
231
230
|
|
|
@@ -234,7 +233,7 @@ const app = new Injector([
|
|
|
234
233
|
A static token can be provided a default factory function to use on creation.
|
|
235
234
|
|
|
236
235
|
```ts
|
|
237
|
-
const URL_TOKEN = new StaticToken(
|
|
236
|
+
const URL_TOKEN = new StaticToken('app_url', () => '/default-url/');
|
|
238
237
|
```
|
|
239
238
|
|
|
240
239
|
### Async Values
|
|
@@ -243,7 +242,7 @@ Static tokens can also leverage promises for cases when you need to asynchronous
|
|
|
243
242
|
|
|
244
243
|
```ts
|
|
245
244
|
// StaticToken<Promise<string>>
|
|
246
|
-
const URL_TOKEN = new StaticToken(
|
|
245
|
+
const URL_TOKEN = new StaticToken('app_url', async () => '/default-url/');
|
|
247
246
|
|
|
248
247
|
const app = new Injector();
|
|
249
248
|
|
|
@@ -253,8 +252,8 @@ const url: string = await app.inject(URL_TOKEN);
|
|
|
253
252
|
This allows you to dynamically import services:
|
|
254
253
|
|
|
255
254
|
```ts
|
|
256
|
-
const HttpService = new StaticToken(
|
|
257
|
-
return import(
|
|
255
|
+
const HttpService = new StaticToken('HTTP_SERVICE', () => {
|
|
256
|
+
return import('./http.service.js').then((m) => new m.HttpService());
|
|
258
257
|
});
|
|
259
258
|
|
|
260
259
|
class HackerNewsService {
|
|
@@ -263,9 +262,9 @@ class HackerNewsService {
|
|
|
263
262
|
async getData() {
|
|
264
263
|
const http = await this.#http();
|
|
265
264
|
|
|
266
|
-
const url = new URL(
|
|
267
|
-
url.searchParams.set(
|
|
268
|
-
url.searchParams.set(
|
|
265
|
+
const url = new URL('https://hacker-news.firebaseio.com/v0/beststories.json');
|
|
266
|
+
url.searchParams.set('limitToFirst', count.toString());
|
|
267
|
+
url.searchParams.set('orderBy', '"$key"');
|
|
269
268
|
|
|
270
269
|
return http.fetchJson<string[]>(url);
|
|
271
270
|
}
|
|
@@ -290,56 +289,6 @@ class MyService {
|
|
|
290
289
|
}
|
|
291
290
|
```
|
|
292
291
|
|
|
293
|
-
### Conditional Lifecycle Hooks
|
|
294
|
-
|
|
295
|
-
You can control when lifecycle callbacks are executed by providing a condition function. The condition function receives the current injector:
|
|
296
|
-
|
|
297
|
-
```ts
|
|
298
|
-
class MyService {
|
|
299
|
-
@created((injector) => ({ enabled: true }))
|
|
300
|
-
onCreated() {
|
|
301
|
-
// This will execute because enabled is true
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
@injected((injector) => {
|
|
305
|
-
return {
|
|
306
|
-
enabled: process.env.NODE_ENV === "development",
|
|
307
|
-
};
|
|
308
|
-
})
|
|
309
|
-
onInjected() {
|
|
310
|
-
// will only execute when NODE_ENV is development
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
The condition function can return an object with an `enabled` property that determines whether the callback should execute:
|
|
316
|
-
|
|
317
|
-
- `{ enabled: true }` - The callback will execute
|
|
318
|
-
- `{ enabled: false }` - The callback will not execute
|
|
319
|
-
- `{}` - The callback will execute (default behavior)
|
|
320
|
-
|
|
321
|
-
You can use the injector to access other services or check the injector's configuration:
|
|
322
|
-
|
|
323
|
-
```ts
|
|
324
|
-
class MyService {
|
|
325
|
-
@created((injector) => {
|
|
326
|
-
const config = injector.inject(ConfigService);
|
|
327
|
-
return { enabled: config.featureEnabled };
|
|
328
|
-
})
|
|
329
|
-
onCreated() {
|
|
330
|
-
// Only executes if feature is enabled in config
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
Lifecycle conditions are useful when you need to:
|
|
336
|
-
|
|
337
|
-
- Execute callbacks only in specific environments
|
|
338
|
-
- Control callback execution based on injector state
|
|
339
|
-
- Implement feature flags for lifecycle hooks
|
|
340
|
-
- Conditionally initialize services based on configuration
|
|
341
|
-
- Make decisions based on other services in the injector
|
|
342
|
-
|
|
343
292
|
## Hierarchical Injectors
|
|
344
293
|
|
|
345
294
|
Injectors can be defined with a parent. The top-most parent will (by default) be where services are constructed and cached. Only if manually defined providers are found earlier in the chain will services be constructed lower. The injector resolution algorithm behaves as follows:
|
|
@@ -382,8 +331,8 @@ const app = new DOMInjector();
|
|
|
382
331
|
app.attach(document.body); // Anything rendered in the body will have access to this injector.
|
|
383
332
|
|
|
384
333
|
class Colors {
|
|
385
|
-
primary =
|
|
386
|
-
secondary =
|
|
334
|
+
primary = 'red';
|
|
335
|
+
secondary = 'green';
|
|
387
336
|
}
|
|
388
337
|
|
|
389
338
|
@injectable()
|
|
@@ -396,12 +345,12 @@ class MyElement extends HTMLElement {
|
|
|
396
345
|
}
|
|
397
346
|
}
|
|
398
347
|
|
|
399
|
-
customElements.define(
|
|
348
|
+
customElements.define('my-element', MyElement);
|
|
400
349
|
```
|
|
401
350
|
|
|
402
351
|
### Context Elements
|
|
403
352
|
|
|
404
|
-
Context elements are where Hierarchical Injectors can really shine as they allow you to define React/Preact-esque "context" elements.
|
|
353
|
+
Context elements are where Hierarchical Injectors can really shine as they allow you to define React/Preact-esque "context" elements.
|
|
405
354
|
Since custom elements are treated the same as any other class, they can define providers for their local scope. The `provideSelfAs` property will provide the current class for the tokens given.
|
|
406
355
|
This also makes it easy to use attributes to define values for the service.
|
|
407
356
|
|
|
@@ -412,16 +361,16 @@ class ColorCtx {
|
|
|
412
361
|
}
|
|
413
362
|
|
|
414
363
|
@injectable({
|
|
415
|
-
name:
|
|
416
|
-
provideSelfAs: [ColorCtx]
|
|
364
|
+
name: 'color-ctx',
|
|
365
|
+
provideSelfAs: [ColorCtx]
|
|
417
366
|
})
|
|
418
367
|
class ColorCtx extends HTMLElement implements ColorCtx {
|
|
419
368
|
get primary() {
|
|
420
|
-
return this.getAttribute("primary") ?? "red"
|
|
369
|
+
return this.getAttribute("primary") ?? "red"
|
|
421
370
|
}
|
|
422
371
|
|
|
423
372
|
get secondary() {
|
|
424
|
-
return this.getAttribute("secondary") ?? "green"
|
|
373
|
+
return this.getAttribute("secondary") ?? "green"
|
|
425
374
|
}
|
|
426
375
|
}
|
|
427
376
|
|
|
@@ -436,8 +385,8 @@ class MyElement extends HTMLElement {
|
|
|
436
385
|
}
|
|
437
386
|
|
|
438
387
|
// Note: To use parent providers, the parent elements need to be defined first!
|
|
439
|
-
customElements.define(
|
|
440
|
-
customElements.define(
|
|
388
|
+
customElements.define('color-ctx', ColorCtx);
|
|
389
|
+
customElements.define('my-element', MyElement);
|
|
441
390
|
```
|
|
442
391
|
|
|
443
392
|
```html
|
package/package.json
CHANGED
|
@@ -6,12 +6,10 @@ import { callLifecycle } from "../lifecycle.js";
|
|
|
6
6
|
import type { InjectableMetadata } from "../metadata.js";
|
|
7
7
|
import type { ConstructableToken } from "../provider.js";
|
|
8
8
|
|
|
9
|
-
export type InjectableEl = HTMLElement & { [INJECTOR]: Injector };
|
|
10
|
-
|
|
11
9
|
export function injectableEl<
|
|
12
|
-
T extends ConstructableToken<
|
|
10
|
+
T extends ConstructableToken<HTMLElement & { [INJECTOR]: Injector }>,
|
|
13
11
|
>(Base: T, ctx: ClassDecoratorContext): T {
|
|
14
|
-
const metadata: InjectableMetadata
|
|
12
|
+
const metadata: InjectableMetadata = ctx.metadata;
|
|
15
13
|
|
|
16
14
|
const def = {
|
|
17
15
|
[Base.name]: class extends Base {
|
|
@@ -4,8 +4,7 @@ import { inject } from "./inject.js";
|
|
|
4
4
|
import { injectable } from "./injectable.js";
|
|
5
5
|
import { Injector } from "./injector.js";
|
|
6
6
|
import { created, injected } from "./lifecycle.js";
|
|
7
|
-
import {
|
|
8
|
-
import { StaticToken } from "./provider.js";
|
|
7
|
+
import { readInjector } from "./metadata.js";
|
|
9
8
|
|
|
10
9
|
it("should call onInit and onInject when a service is first created", () => {
|
|
11
10
|
const i = new Injector();
|
|
@@ -129,166 +128,3 @@ it("should call onInject and on init when injected from another service", () =>
|
|
|
129
128
|
onInjected: 2,
|
|
130
129
|
});
|
|
131
130
|
});
|
|
132
|
-
|
|
133
|
-
it("should respect enabled=false condition in lifecycle callbacks", () => {
|
|
134
|
-
const i = new Injector();
|
|
135
|
-
|
|
136
|
-
@injectable()
|
|
137
|
-
class MyService {
|
|
138
|
-
res = {
|
|
139
|
-
onCreated: 0,
|
|
140
|
-
onInjected: 0,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
@created(() => ({ enabled: false }))
|
|
144
|
-
onCreated() {
|
|
145
|
-
this.res.onCreated++;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
@injected(() => ({ enabled: false }))
|
|
149
|
-
onInjected() {
|
|
150
|
-
this.res.onInjected++;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const service = i.inject(MyService);
|
|
155
|
-
|
|
156
|
-
assert.deepEqual(service.res, {
|
|
157
|
-
onCreated: 0,
|
|
158
|
-
onInjected: 0,
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("should respect enabled=true condition in lifecycle callbacks", () => {
|
|
163
|
-
const i = new Injector();
|
|
164
|
-
|
|
165
|
-
@injectable()
|
|
166
|
-
class MyService {
|
|
167
|
-
res = {
|
|
168
|
-
onCreated: 0,
|
|
169
|
-
onInjected: 0,
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
@created(() => ({ enabled: true }))
|
|
173
|
-
onCreated() {
|
|
174
|
-
this.res.onCreated++;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
@injected(() => ({ enabled: true }))
|
|
178
|
-
onInjected() {
|
|
179
|
-
this.res.onInjected++;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const service = i.inject(MyService);
|
|
184
|
-
|
|
185
|
-
assert.deepEqual(service.res, {
|
|
186
|
-
onCreated: 1,
|
|
187
|
-
onInjected: 1,
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("should execute callbacks when condition returns undefined enabled", () => {
|
|
192
|
-
const i = new Injector();
|
|
193
|
-
|
|
194
|
-
@injectable()
|
|
195
|
-
class MyService {
|
|
196
|
-
res = {
|
|
197
|
-
onCreated: 0,
|
|
198
|
-
onInjected: 0,
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
@created(() => ({ enabled: undefined }))
|
|
202
|
-
onCreated() {
|
|
203
|
-
this.res.onCreated++;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
@injected(() => ({ enabled: undefined }))
|
|
207
|
-
onInjected() {
|
|
208
|
-
this.res.onInjected++;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const service = i.inject(MyService);
|
|
213
|
-
|
|
214
|
-
assert.deepEqual(service.res, {
|
|
215
|
-
onCreated: 1,
|
|
216
|
-
onInjected: 1,
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
it("should execute callbacks when condition returns empty object", () => {
|
|
221
|
-
const i = new Injector();
|
|
222
|
-
|
|
223
|
-
@injectable()
|
|
224
|
-
class MyService {
|
|
225
|
-
res = {
|
|
226
|
-
onCreated: 0,
|
|
227
|
-
onInjected: 0,
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
@created(() => ({}))
|
|
231
|
-
onCreated() {
|
|
232
|
-
this.res.onCreated++;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
@injected(() => ({}))
|
|
236
|
-
onInjected() {
|
|
237
|
-
this.res.onInjected++;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const service = i.inject(MyService);
|
|
242
|
-
|
|
243
|
-
assert.deepEqual(service.res, {
|
|
244
|
-
onCreated: 1,
|
|
245
|
-
onInjected: 1,
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
it("should pass the injector to the condition", () => {
|
|
251
|
-
const IS_PROD = new StaticToken("isProd", () => false);
|
|
252
|
-
|
|
253
|
-
const i = new Injector();
|
|
254
|
-
|
|
255
|
-
function isProd() {
|
|
256
|
-
return (val: LifecycleCallback, ctx: ClassMethodDecoratorContext) => {
|
|
257
|
-
created(({ injector }) => {
|
|
258
|
-
const enabled = injector.inject(IS_PROD);
|
|
259
|
-
return { enabled };
|
|
260
|
-
})(val, ctx);
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
@injectable()
|
|
265
|
-
class MyService {
|
|
266
|
-
count = 0;
|
|
267
|
-
|
|
268
|
-
@isProd()
|
|
269
|
-
onCreated() {
|
|
270
|
-
this.count++;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const service = i.inject(MyService);
|
|
275
|
-
assert.equal(service.count, 0); // Not called because count is 0
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
it("should pass the instance to the condition", () => {
|
|
279
|
-
const i = new Injector();
|
|
280
|
-
|
|
281
|
-
@injectable()
|
|
282
|
-
class MyService {
|
|
283
|
-
enabled = false;
|
|
284
|
-
count = 0;
|
|
285
|
-
|
|
286
|
-
@created(({ instance }) => ({ enabled: instance.enabled }))
|
|
287
|
-
onCreated() {
|
|
288
|
-
this.count++;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const service = i.inject(MyService);
|
|
293
|
-
assert.equal(service.count, 0); // not called because instance.enabled is false
|
|
294
|
-
});
|
package/src/lib/lifecycle.ts
CHANGED
|
@@ -1,53 +1,36 @@
|
|
|
1
1
|
import type { Injector } from "./injector.js";
|
|
2
|
-
import type {
|
|
3
|
-
InjectableMetadata,
|
|
4
|
-
LifecycleCallback,
|
|
5
|
-
LifecycleCondition,
|
|
6
|
-
LifecycleMethod,
|
|
7
|
-
} from "./metadata.js";
|
|
2
|
+
import type { InjectableMetadata, LifecycleCallback } from "./metadata.js";
|
|
8
3
|
|
|
9
|
-
export function injected
|
|
4
|
+
export function injected() {
|
|
10
5
|
return function onInjectDecorator(
|
|
11
6
|
val: LifecycleCallback,
|
|
12
|
-
ctx: ClassMethodDecoratorContext
|
|
7
|
+
ctx: ClassMethodDecoratorContext,
|
|
13
8
|
): void {
|
|
14
|
-
const metadata: InjectableMetadata
|
|
9
|
+
const metadata: InjectableMetadata = ctx.metadata;
|
|
15
10
|
metadata.onInjected ??= [];
|
|
16
|
-
metadata.onInjected.push(
|
|
17
|
-
callback: val,
|
|
18
|
-
condition,
|
|
19
|
-
});
|
|
11
|
+
metadata.onInjected.push(val);
|
|
20
12
|
};
|
|
21
13
|
}
|
|
22
14
|
|
|
23
|
-
export function created
|
|
15
|
+
export function created() {
|
|
24
16
|
return function onInjectDecorator(
|
|
25
17
|
val: LifecycleCallback,
|
|
26
|
-
ctx: ClassMethodDecoratorContext
|
|
18
|
+
ctx: ClassMethodDecoratorContext,
|
|
27
19
|
): void {
|
|
28
|
-
const metadata: InjectableMetadata
|
|
20
|
+
const metadata: InjectableMetadata = ctx.metadata;
|
|
29
21
|
metadata.onCreated ??= [];
|
|
30
|
-
metadata.onCreated.push(
|
|
31
|
-
callback: val,
|
|
32
|
-
condition,
|
|
33
|
-
});
|
|
22
|
+
metadata.onCreated.push(val);
|
|
34
23
|
};
|
|
35
24
|
}
|
|
36
25
|
|
|
37
26
|
export function callLifecycle(
|
|
38
27
|
instance: object,
|
|
39
|
-
|
|
40
|
-
methods?:
|
|
28
|
+
i: Injector,
|
|
29
|
+
methods?: LifecycleCallback[],
|
|
41
30
|
): void {
|
|
42
31
|
if (methods) {
|
|
43
|
-
for (const
|
|
44
|
-
|
|
45
|
-
const result = condition({ injector, instance });
|
|
46
|
-
if (result.enabled === false) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
callback.call(instance, injector);
|
|
32
|
+
for (const cb of methods) {
|
|
33
|
+
cb.call(instance, i);
|
|
51
34
|
}
|
|
52
35
|
}
|
|
53
36
|
}
|
package/src/lib/metadata.ts
CHANGED
|
@@ -5,20 +5,15 @@ import type { InjectionToken } from "./provider.js";
|
|
|
5
5
|
|
|
6
6
|
export type LifecycleCallback = (i: Injector) => void;
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
callback: LifecycleCallback;
|
|
12
|
-
condition?: LifecycleCondition<T>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface InjectableMetadata<T> {
|
|
16
|
-
onCreated?: LifecycleMethod<T>[];
|
|
17
|
-
onInjected?: LifecycleMethod<T>[];
|
|
8
|
+
export interface InjectableMetadata {
|
|
9
|
+
onCreated?: LifecycleCallback[];
|
|
10
|
+
onInjected?: LifecycleCallback[];
|
|
18
11
|
}
|
|
19
12
|
|
|
20
|
-
export function readMetadata<T>(
|
|
21
|
-
|
|
13
|
+
export function readMetadata<T>(
|
|
14
|
+
target: InjectionToken<T>,
|
|
15
|
+
): InjectableMetadata | null {
|
|
16
|
+
const metadata: InjectableMetadata | null = target[Symbol.metadata];
|
|
22
17
|
|
|
23
18
|
return metadata;
|
|
24
19
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { INJECTOR } from "../injector.js";
|
|
2
2
|
import type { Injector } from "../injector.js";
|
|
3
3
|
import type { ConstructableToken } from "../provider.js";
|
|
4
|
-
export
|
|
4
|
+
export declare function injectableEl<T extends ConstructableToken<HTMLElement & {
|
|
5
5
|
[INJECTOR]: Injector;
|
|
6
|
-
};
|
|
7
|
-
export declare function injectableEl<T extends ConstructableToken<InjectableEl>>(Base: T, ctx: ClassDecoratorContext): T;
|
|
6
|
+
}>>(Base: T, ctx: ClassDecoratorContext): T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injectable-el.js","sourceRoot":"","sources":["../../../src/lib/dom/injectable-el.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"injectable-el.js","sourceRoot":"","sources":["../../../src/lib/dom/injectable-el.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,UAAU,YAAY,CAE1B,IAAO,EAAE,GAA0B;IACnC,MAAM,QAAQ,GAAuB,GAAG,CAAC,QAAQ,CAAC;IAElD,MAAM,GAAG,GAAG;QACV,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAM,SAAQ,IAAI;YAC7B,YAAY,GAAG,CAAQ;gBACrB,KAAK,EAAE,CAAC;gBAER,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAEhC,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,EAAE;oBAC7C,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY,EAAE,CAAC;wBACpD,CAAC,CAAC,eAAe,EAAE,CAAC;wBAEpB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBACvB,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACrD,CAAC;YAED,iBAAiB;gBACf,IAAI,CAAC,aAAa,CAChB,IAAI,mBAAmB,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE;oBAC5C,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;gBAC9B,CAAC,CAAC,CACH,CAAC;gBAEF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;gBAE1D,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBAC5B,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,CAAC;YACH,CAAC;YAED,oBAAoB;gBAIlB,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;oBAC/B,KAAK,CAAC,oBAAoB,EAAE,CAAC;gBAC/B,CAAC;gBAED,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC;YACpC,CAAC;SACF;KACF,CAAC;IAEF,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Injector } from "./injector.js";
|
|
2
|
-
import type { LifecycleCallback
|
|
3
|
-
export declare function injected
|
|
4
|
-
export declare function created
|
|
5
|
-
export declare function callLifecycle(instance: object,
|
|
2
|
+
import type { LifecycleCallback } from "./metadata.js";
|
|
3
|
+
export declare function injected(): (val: LifecycleCallback, ctx: ClassMethodDecoratorContext) => void;
|
|
4
|
+
export declare function created(): (val: LifecycleCallback, ctx: ClassMethodDecoratorContext) => void;
|
|
5
|
+
export declare function callLifecycle(instance: object, i: Injector, methods?: LifecycleCallback[]): void;
|
package/target/lib/lifecycle.js
CHANGED
|
@@ -1,33 +1,21 @@
|
|
|
1
|
-
export function injected(
|
|
1
|
+
export function injected() {
|
|
2
2
|
return function onInjectDecorator(val, ctx) {
|
|
3
3
|
const metadata = ctx.metadata;
|
|
4
4
|
metadata.onInjected ??= [];
|
|
5
|
-
metadata.onInjected.push(
|
|
6
|
-
callback: val,
|
|
7
|
-
condition,
|
|
8
|
-
});
|
|
5
|
+
metadata.onInjected.push(val);
|
|
9
6
|
};
|
|
10
7
|
}
|
|
11
|
-
export function created(
|
|
8
|
+
export function created() {
|
|
12
9
|
return function onInjectDecorator(val, ctx) {
|
|
13
10
|
const metadata = ctx.metadata;
|
|
14
11
|
metadata.onCreated ??= [];
|
|
15
|
-
metadata.onCreated.push(
|
|
16
|
-
callback: val,
|
|
17
|
-
condition,
|
|
18
|
-
});
|
|
12
|
+
metadata.onCreated.push(val);
|
|
19
13
|
};
|
|
20
14
|
}
|
|
21
|
-
export function callLifecycle(instance,
|
|
15
|
+
export function callLifecycle(instance, i, methods) {
|
|
22
16
|
if (methods) {
|
|
23
|
-
for (const
|
|
24
|
-
|
|
25
|
-
const result = condition({ injector, instance });
|
|
26
|
-
if (result.enabled === false) {
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
callback.call(instance, injector);
|
|
17
|
+
for (const cb of methods) {
|
|
18
|
+
cb.call(instance, i);
|
|
31
19
|
}
|
|
32
20
|
}
|
|
33
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lib/lifecycle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lib/lifecycle.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,QAAQ;IACtB,OAAO,SAAS,iBAAiB,CAC/B,GAAsB,EACtB,GAAgC;QAEhC,MAAM,QAAQ,GAAuB,GAAG,CAAC,QAAQ,CAAC;QAClD,QAAQ,CAAC,UAAU,KAAK,EAAE,CAAC;QAC3B,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,SAAS,iBAAiB,CAC/B,GAAsB,EACtB,GAAgC;QAEhC,MAAM,QAAQ,GAAuB,GAAG,CAAC,QAAQ,CAAC;QAClD,QAAQ,CAAC,SAAS,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,CAAW,EACX,OAA6B;IAE7B,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -5,7 +5,6 @@ import { injectable } from "./injectable.js";
|
|
|
5
5
|
import { Injector } from "./injector.js";
|
|
6
6
|
import { created, injected } from "./lifecycle.js";
|
|
7
7
|
import { readInjector } from "./metadata.js";
|
|
8
|
-
import { StaticToken } from "./provider.js";
|
|
9
8
|
it("should call onInit and onInject when a service is first created", () => {
|
|
10
9
|
const i = new Injector();
|
|
11
10
|
let MyService = (() => {
|
|
@@ -194,242 +193,4 @@ it("should call onInject and on init when injected from another service", () =>
|
|
|
194
193
|
onInjected: 2,
|
|
195
194
|
});
|
|
196
195
|
});
|
|
197
|
-
it("should respect enabled=false condition in lifecycle callbacks", () => {
|
|
198
|
-
const i = new Injector();
|
|
199
|
-
let MyService = (() => {
|
|
200
|
-
let _classDecorators = [injectable()];
|
|
201
|
-
let _classDescriptor;
|
|
202
|
-
let _classExtraInitializers = [];
|
|
203
|
-
let _classThis;
|
|
204
|
-
let _instanceExtraInitializers = [];
|
|
205
|
-
let _onCreated_decorators;
|
|
206
|
-
let _onInjected_decorators;
|
|
207
|
-
var MyService = class {
|
|
208
|
-
static { _classThis = this; }
|
|
209
|
-
static {
|
|
210
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
211
|
-
_onCreated_decorators = [created(() => ({ enabled: false }))];
|
|
212
|
-
_onInjected_decorators = [injected(() => ({ enabled: false }))];
|
|
213
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
214
|
-
__esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
215
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
216
|
-
MyService = _classThis = _classDescriptor.value;
|
|
217
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
218
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
219
|
-
}
|
|
220
|
-
res = (__runInitializers(this, _instanceExtraInitializers), {
|
|
221
|
-
onCreated: 0,
|
|
222
|
-
onInjected: 0,
|
|
223
|
-
});
|
|
224
|
-
onCreated() {
|
|
225
|
-
this.res.onCreated++;
|
|
226
|
-
}
|
|
227
|
-
onInjected() {
|
|
228
|
-
this.res.onInjected++;
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
return MyService = _classThis;
|
|
232
|
-
})();
|
|
233
|
-
const service = i.inject(MyService);
|
|
234
|
-
assert.deepEqual(service.res, {
|
|
235
|
-
onCreated: 0,
|
|
236
|
-
onInjected: 0,
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
it("should respect enabled=true condition in lifecycle callbacks", () => {
|
|
240
|
-
const i = new Injector();
|
|
241
|
-
let MyService = (() => {
|
|
242
|
-
let _classDecorators = [injectable()];
|
|
243
|
-
let _classDescriptor;
|
|
244
|
-
let _classExtraInitializers = [];
|
|
245
|
-
let _classThis;
|
|
246
|
-
let _instanceExtraInitializers = [];
|
|
247
|
-
let _onCreated_decorators;
|
|
248
|
-
let _onInjected_decorators;
|
|
249
|
-
var MyService = class {
|
|
250
|
-
static { _classThis = this; }
|
|
251
|
-
static {
|
|
252
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
253
|
-
_onCreated_decorators = [created(() => ({ enabled: true }))];
|
|
254
|
-
_onInjected_decorators = [injected(() => ({ enabled: true }))];
|
|
255
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
256
|
-
__esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
257
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
258
|
-
MyService = _classThis = _classDescriptor.value;
|
|
259
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
260
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
261
|
-
}
|
|
262
|
-
res = (__runInitializers(this, _instanceExtraInitializers), {
|
|
263
|
-
onCreated: 0,
|
|
264
|
-
onInjected: 0,
|
|
265
|
-
});
|
|
266
|
-
onCreated() {
|
|
267
|
-
this.res.onCreated++;
|
|
268
|
-
}
|
|
269
|
-
onInjected() {
|
|
270
|
-
this.res.onInjected++;
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
return MyService = _classThis;
|
|
274
|
-
})();
|
|
275
|
-
const service = i.inject(MyService);
|
|
276
|
-
assert.deepEqual(service.res, {
|
|
277
|
-
onCreated: 1,
|
|
278
|
-
onInjected: 1,
|
|
279
|
-
});
|
|
280
|
-
});
|
|
281
|
-
it("should execute callbacks when condition returns undefined enabled", () => {
|
|
282
|
-
const i = new Injector();
|
|
283
|
-
let MyService = (() => {
|
|
284
|
-
let _classDecorators = [injectable()];
|
|
285
|
-
let _classDescriptor;
|
|
286
|
-
let _classExtraInitializers = [];
|
|
287
|
-
let _classThis;
|
|
288
|
-
let _instanceExtraInitializers = [];
|
|
289
|
-
let _onCreated_decorators;
|
|
290
|
-
let _onInjected_decorators;
|
|
291
|
-
var MyService = class {
|
|
292
|
-
static { _classThis = this; }
|
|
293
|
-
static {
|
|
294
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
295
|
-
_onCreated_decorators = [created(() => ({ enabled: undefined }))];
|
|
296
|
-
_onInjected_decorators = [injected(() => ({ enabled: undefined }))];
|
|
297
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
298
|
-
__esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
299
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
300
|
-
MyService = _classThis = _classDescriptor.value;
|
|
301
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
302
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
303
|
-
}
|
|
304
|
-
res = (__runInitializers(this, _instanceExtraInitializers), {
|
|
305
|
-
onCreated: 0,
|
|
306
|
-
onInjected: 0,
|
|
307
|
-
});
|
|
308
|
-
onCreated() {
|
|
309
|
-
this.res.onCreated++;
|
|
310
|
-
}
|
|
311
|
-
onInjected() {
|
|
312
|
-
this.res.onInjected++;
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
return MyService = _classThis;
|
|
316
|
-
})();
|
|
317
|
-
const service = i.inject(MyService);
|
|
318
|
-
assert.deepEqual(service.res, {
|
|
319
|
-
onCreated: 1,
|
|
320
|
-
onInjected: 1,
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
-
it("should execute callbacks when condition returns empty object", () => {
|
|
324
|
-
const i = new Injector();
|
|
325
|
-
let MyService = (() => {
|
|
326
|
-
let _classDecorators = [injectable()];
|
|
327
|
-
let _classDescriptor;
|
|
328
|
-
let _classExtraInitializers = [];
|
|
329
|
-
let _classThis;
|
|
330
|
-
let _instanceExtraInitializers = [];
|
|
331
|
-
let _onCreated_decorators;
|
|
332
|
-
let _onInjected_decorators;
|
|
333
|
-
var MyService = class {
|
|
334
|
-
static { _classThis = this; }
|
|
335
|
-
static {
|
|
336
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
337
|
-
_onCreated_decorators = [created(() => ({}))];
|
|
338
|
-
_onInjected_decorators = [injected(() => ({}))];
|
|
339
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
340
|
-
__esDecorate(this, null, _onInjected_decorators, { kind: "method", name: "onInjected", static: false, private: false, access: { has: obj => "onInjected" in obj, get: obj => obj.onInjected }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
341
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
342
|
-
MyService = _classThis = _classDescriptor.value;
|
|
343
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
344
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
345
|
-
}
|
|
346
|
-
res = (__runInitializers(this, _instanceExtraInitializers), {
|
|
347
|
-
onCreated: 0,
|
|
348
|
-
onInjected: 0,
|
|
349
|
-
});
|
|
350
|
-
onCreated() {
|
|
351
|
-
this.res.onCreated++;
|
|
352
|
-
}
|
|
353
|
-
onInjected() {
|
|
354
|
-
this.res.onInjected++;
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
return MyService = _classThis;
|
|
358
|
-
})();
|
|
359
|
-
const service = i.inject(MyService);
|
|
360
|
-
assert.deepEqual(service.res, {
|
|
361
|
-
onCreated: 1,
|
|
362
|
-
onInjected: 1,
|
|
363
|
-
});
|
|
364
|
-
});
|
|
365
|
-
it("should pass the injector to the condition", () => {
|
|
366
|
-
const IS_PROD = new StaticToken("isProd", () => false);
|
|
367
|
-
const i = new Injector();
|
|
368
|
-
function isProd() {
|
|
369
|
-
return (val, ctx) => {
|
|
370
|
-
created(({ injector }) => {
|
|
371
|
-
const enabled = injector.inject(IS_PROD);
|
|
372
|
-
return { enabled };
|
|
373
|
-
})(val, ctx);
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
let MyService = (() => {
|
|
377
|
-
let _classDecorators = [injectable()];
|
|
378
|
-
let _classDescriptor;
|
|
379
|
-
let _classExtraInitializers = [];
|
|
380
|
-
let _classThis;
|
|
381
|
-
let _instanceExtraInitializers = [];
|
|
382
|
-
let _onCreated_decorators;
|
|
383
|
-
var MyService = class {
|
|
384
|
-
static { _classThis = this; }
|
|
385
|
-
static {
|
|
386
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
387
|
-
_onCreated_decorators = [isProd()];
|
|
388
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
389
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
390
|
-
MyService = _classThis = _classDescriptor.value;
|
|
391
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
392
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
393
|
-
}
|
|
394
|
-
count = (__runInitializers(this, _instanceExtraInitializers), 0);
|
|
395
|
-
onCreated() {
|
|
396
|
-
this.count++;
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
return MyService = _classThis;
|
|
400
|
-
})();
|
|
401
|
-
const service = i.inject(MyService);
|
|
402
|
-
assert.equal(service.count, 0);
|
|
403
|
-
});
|
|
404
|
-
it("should pass the instance to the condition", () => {
|
|
405
|
-
const i = new Injector();
|
|
406
|
-
let MyService = (() => {
|
|
407
|
-
let _classDecorators = [injectable()];
|
|
408
|
-
let _classDescriptor;
|
|
409
|
-
let _classExtraInitializers = [];
|
|
410
|
-
let _classThis;
|
|
411
|
-
let _instanceExtraInitializers = [];
|
|
412
|
-
let _onCreated_decorators;
|
|
413
|
-
var MyService = class {
|
|
414
|
-
static { _classThis = this; }
|
|
415
|
-
static {
|
|
416
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
417
|
-
_onCreated_decorators = [created(({ instance }) => ({ enabled: instance.enabled }))];
|
|
418
|
-
__esDecorate(this, null, _onCreated_decorators, { kind: "method", name: "onCreated", static: false, private: false, access: { has: obj => "onCreated" in obj, get: obj => obj.onCreated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
419
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
420
|
-
MyService = _classThis = _classDescriptor.value;
|
|
421
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
422
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
423
|
-
}
|
|
424
|
-
enabled = (__runInitializers(this, _instanceExtraInitializers), false);
|
|
425
|
-
count = 0;
|
|
426
|
-
onCreated() {
|
|
427
|
-
this.count++;
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
return MyService = _classThis;
|
|
431
|
-
})();
|
|
432
|
-
const service = i.inject(MyService);
|
|
433
|
-
assert.equal(service.count, 0);
|
|
434
|
-
});
|
|
435
196
|
//# sourceMappingURL=lifecycle.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.test.js","sourceRoot":"","sources":["../../src/lib/lifecycle.test.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,
|
|
1
|
+
{"version":3,"file":"lifecycle.test.js","sourceRoot":"","sources":["../../src/lib/lifecycle.test.ts"],"names":[],"mappings":"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"}
|
package/target/lib/metadata.d.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { type Injector } from "./injector.js";
|
|
2
2
|
import type { InjectionToken } from "./provider.js";
|
|
3
3
|
export type LifecycleCallback = (i: Injector) => void;
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}) => {
|
|
8
|
-
enabled?: boolean;
|
|
9
|
-
};
|
|
10
|
-
export interface LifecycleMethod<T> {
|
|
11
|
-
callback: LifecycleCallback;
|
|
12
|
-
condition?: LifecycleCondition<T>;
|
|
4
|
+
export interface InjectableMetadata {
|
|
5
|
+
onCreated?: LifecycleCallback[];
|
|
6
|
+
onInjected?: LifecycleCallback[];
|
|
13
7
|
}
|
|
14
|
-
export
|
|
15
|
-
onCreated?: LifecycleMethod<T>[];
|
|
16
|
-
onInjected?: LifecycleMethod<T>[];
|
|
17
|
-
}
|
|
18
|
-
export declare function readMetadata<T>(target: InjectionToken<T>): InjectableMetadata<T> | null;
|
|
8
|
+
export declare function readMetadata<T>(target: InjectionToken<T>): InjectableMetadata | null;
|
|
19
9
|
export declare function readInjector<T>(target: T): Injector | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/lib/metadata.ts"],"names":[],"mappings":"AAAC,MAAc,CAAC,QAAQ,KAAK,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAiB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/lib/metadata.ts"],"names":[],"mappings":"AAAC,MAAc,CAAC,QAAQ,KAAK,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAiB,MAAM,eAAe,CAAC;AAUxD,MAAM,UAAU,YAAY,CAC1B,MAAyB;IAEzB,MAAM,QAAQ,GAA8B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEpE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAI,MAAS;IACvC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,MAAM,CAAC,QAAQ,CAAa,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|