@joist/di 4.2.3-next.2 → 4.2.3-next.20

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 CHANGED
@@ -38,6 +38,7 @@ npm i @joist/di
38
38
  ## Injectors
39
39
 
40
40
  Injectors are the core of the dependency injection system. They:
41
+
41
42
  - Create and manage service instances
42
43
  - Handle dependency resolution
43
44
  - Maintain a hierarchy of injectors
@@ -103,7 +104,7 @@ class ApiService {
103
104
 
104
105
  getData() {
105
106
  return this.#http()
106
- .fetch('/api/v1/users')
107
+ .fetch("/api/v1/users")
107
108
  .then((res) => res.json());
108
109
  }
109
110
  }
@@ -111,22 +112,22 @@ class ApiService {
111
112
 
112
113
  ```ts
113
114
  // services.test.ts
114
- test('should return json', async () => {
115
+ test("should return json", async () => {
115
116
  class MockHttpService extends HttpService {
116
117
  async fetch() {
117
- return Response.json({ fname: 'Danny', lname: 'Blue' });
118
+ return Response.json({ fname: "Danny", lname: "Blue" });
118
119
  }
119
120
  }
120
121
 
121
122
  const app = new Injector({
122
- providers: [[HttpService, { use: MockHttpService }]]
123
+ providers: [[HttpService, { use: MockHttpService }]],
123
124
  });
124
125
  const api = app.inject(ApiService);
125
126
 
126
127
  const res = await api.getData();
127
128
 
128
- assert.equals(res.fname, 'Danny');
129
- assert.equals(res.lname, 'Blue');
129
+ assert.equals(res.fname, "Danny");
130
+ assert.equals(res.lname, "Blue");
130
131
  });
131
132
  ```
132
133
 
@@ -148,7 +149,7 @@ class ConsoleLogger implements Logger {
148
149
  }
149
150
 
150
151
  @injectable({
151
- providers: [[Logger, { use: ConsoleLogger }]]
152
+ providers: [[Logger, { use: ConsoleLogger }]],
152
153
  })
153
154
  class MyService {}
154
155
  ```
@@ -168,13 +169,13 @@ const app = new Injector([
168
169
  factory() {
169
170
  const params = new URLSearchParams(window.location.search);
170
171
 
171
- if (params.has('debug')) {
172
+ if (params.has("debug")) {
172
173
  return console;
173
174
  }
174
175
 
175
176
  return new Logger(); // noop logger
176
- }
177
- }
177
+ },
178
+ },
178
179
  ]);
179
180
  ```
180
181
 
@@ -204,9 +205,9 @@ const app = new Injector([
204
205
  factory(i) {
205
206
  const logger = i.inject(Logger);
206
207
  return new Feature(logger);
207
- }
208
- }
209
- ]
208
+ },
209
+ },
210
+ ],
210
211
  ]);
211
212
  ```
212
213
 
@@ -216,15 +217,15 @@ In most cases, a token is any constructable class. There are cases where you mig
216
217
 
217
218
  ```ts
218
219
  // Token that resolves to a string
219
- const URL_TOKEN = new StaticToken<string>('app_url');
220
+ const URL_TOKEN = new StaticToken<string>("app_url");
220
221
 
221
222
  const app = new Injector([
222
223
  [
223
224
  URL_TOKEN,
224
225
  {
225
- factory: () => '/my-app-url/'
226
- }
227
- ]
226
+ factory: () => "/my-app-url/",
227
+ },
228
+ ],
228
229
  ]);
229
230
  ```
230
231
 
@@ -233,7 +234,7 @@ const app = new Injector([
233
234
  A static token can be provided a default factory function to use on creation.
234
235
 
235
236
  ```ts
236
- const URL_TOKEN = new StaticToken('app_url', () => '/default-url/');
237
+ const URL_TOKEN = new StaticToken("app_url", () => "/default-url/");
237
238
  ```
238
239
 
239
240
  ### Async Values
@@ -242,7 +243,7 @@ Static tokens can also leverage promises for cases when you need to asynchronous
242
243
 
243
244
  ```ts
244
245
  // StaticToken<Promise<string>>
245
- const URL_TOKEN = new StaticToken('app_url', async () => '/default-url/');
246
+ const URL_TOKEN = new StaticToken("app_url", async () => "/default-url/");
246
247
 
247
248
  const app = new Injector();
248
249
 
@@ -252,8 +253,8 @@ const url: string = await app.inject(URL_TOKEN);
252
253
  This allows you to dynamically import services:
253
254
 
254
255
  ```ts
255
- const HttpService = new StaticToken('HTTP_SERVICE', () => {
256
- return import('./http.service.js').then((m) => new m.HttpService());
256
+ const HttpService = new StaticToken("HTTP_SERVICE", () => {
257
+ return import("./http.service.js").then((m) => new m.HttpService());
257
258
  });
258
259
 
259
260
  class HackerNewsService {
@@ -262,9 +263,9 @@ class HackerNewsService {
262
263
  async getData() {
263
264
  const http = await this.#http();
264
265
 
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"');
266
+ const url = new URL("https://hacker-news.firebaseio.com/v0/beststories.json");
267
+ url.searchParams.set("limitToFirst", count.toString());
268
+ url.searchParams.set("orderBy", '"$key"');
268
269
 
269
270
  return http.fetchJson<string[]>(url);
270
271
  }
@@ -289,6 +290,56 @@ class MyService {
289
290
  }
290
291
  ```
291
292
 
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
+
292
343
  ## Hierarchical Injectors
293
344
 
294
345
  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:
@@ -331,8 +382,8 @@ const app = new DOMInjector();
331
382
  app.attach(document.body); // Anything rendered in the body will have access to this injector.
332
383
 
333
384
  class Colors {
334
- primary = 'red';
335
- secondary = 'green';
385
+ primary = "red";
386
+ secondary = "green";
336
387
  }
337
388
 
338
389
  @injectable()
@@ -345,12 +396,12 @@ class MyElement extends HTMLElement {
345
396
  }
346
397
  }
347
398
 
348
- customElements.define('my-element', MyElement);
399
+ customElements.define("my-element", MyElement);
349
400
  ```
350
401
 
351
402
  ### Context Elements
352
403
 
353
- Context elements are where Hierarchical Injectors can really shine as they allow you to define React/Preact-esque "context" elements.
404
+ Context elements are where Hierarchical Injectors can really shine as they allow you to define React/Preact-esque "context" elements.
354
405
  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.
355
406
  This also makes it easy to use attributes to define values for the service.
356
407
 
@@ -361,16 +412,16 @@ class ColorCtx {
361
412
  }
362
413
 
363
414
  @injectable({
364
- name: 'color-ctx',
365
- provideSelfAs: [ColorCtx]
415
+ name: "color-ctx",
416
+ provideSelfAs: [ColorCtx],
366
417
  })
367
418
  class ColorCtx extends HTMLElement implements ColorCtx {
368
419
  get primary() {
369
- return this.getAttribute("primary") ?? "red"
420
+ return this.getAttribute("primary") ?? "red";
370
421
  }
371
422
 
372
423
  get secondary() {
373
- return this.getAttribute("secondary") ?? "green"
424
+ return this.getAttribute("secondary") ?? "green";
374
425
  }
375
426
  }
376
427
 
@@ -385,8 +436,8 @@ class MyElement extends HTMLElement {
385
436
  }
386
437
 
387
438
  // Note: To use parent providers, the parent elements need to be defined first!
388
- customElements.define('color-ctx', ColorCtx);
389
- customElements.define('my-element', MyElement);
439
+ customElements.define("color-ctx", ColorCtx);
440
+ customElements.define("my-element", MyElement);
390
441
  ```
391
442
 
392
443
  ```html
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joist/di",
3
- "version": "4.2.3-next.2",
3
+ "version": "4.2.3-next.20",
4
4
  "type": "module",
5
5
  "main": "./target/lib.js",
6
6
  "module": "./target/lib.js",
@@ -6,10 +6,12 @@ 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
+
9
11
  export function injectableEl<
10
- T extends ConstructableToken<HTMLElement & { [INJECTOR]: Injector }>,
12
+ T extends ConstructableToken<InjectableEl>,
11
13
  >(Base: T, ctx: ClassDecoratorContext): T {
12
- const metadata: InjectableMetadata = ctx.metadata;
14
+ const metadata: InjectableMetadata<InjectableEl> = ctx.metadata;
13
15
 
14
16
  const def = {
15
17
  [Base.name]: class extends Base {
@@ -4,7 +4,8 @@ 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 { readInjector } from "./metadata.js";
7
+ import { LifecycleCallback, readInjector } from "./metadata.js";
8
+ import { StaticToken } from "./provider.js";
8
9
 
9
10
  it("should call onInit and onInject when a service is first created", () => {
10
11
  const i = new Injector();
@@ -128,3 +129,166 @@ it("should call onInject and on init when injected from another service", () =>
128
129
  onInjected: 2,
129
130
  });
130
131
  });
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
+ });
@@ -1,36 +1,53 @@
1
1
  import type { Injector } from "./injector.js";
2
- import type { InjectableMetadata, LifecycleCallback } from "./metadata.js";
2
+ import type {
3
+ InjectableMetadata,
4
+ LifecycleCallback,
5
+ LifecycleCondition,
6
+ LifecycleMethod,
7
+ } from "./metadata.js";
3
8
 
4
- export function injected() {
9
+ export function injected<T>(condition?: LifecycleCondition<T>) {
5
10
  return function onInjectDecorator(
6
11
  val: LifecycleCallback,
7
- ctx: ClassMethodDecoratorContext,
12
+ ctx: ClassMethodDecoratorContext<T>,
8
13
  ): void {
9
- const metadata: InjectableMetadata = ctx.metadata;
14
+ const metadata: InjectableMetadata<T> = ctx.metadata;
10
15
  metadata.onInjected ??= [];
11
- metadata.onInjected.push(val);
16
+ metadata.onInjected.push({
17
+ callback: val,
18
+ condition,
19
+ });
12
20
  };
13
21
  }
14
22
 
15
- export function created() {
23
+ export function created<T>(condition?: LifecycleCondition<T>) {
16
24
  return function onInjectDecorator(
17
25
  val: LifecycleCallback,
18
- ctx: ClassMethodDecoratorContext,
26
+ ctx: ClassMethodDecoratorContext<T>,
19
27
  ): void {
20
- const metadata: InjectableMetadata = ctx.metadata;
28
+ const metadata: InjectableMetadata<T> = ctx.metadata;
21
29
  metadata.onCreated ??= [];
22
- metadata.onCreated.push(val);
30
+ metadata.onCreated.push({
31
+ callback: val,
32
+ condition,
33
+ });
23
34
  };
24
35
  }
25
36
 
26
37
  export function callLifecycle(
27
38
  instance: object,
28
- i: Injector,
29
- methods?: LifecycleCallback[],
39
+ injector: Injector,
40
+ methods?: LifecycleMethod<any>[],
30
41
  ): void {
31
42
  if (methods) {
32
- for (const cb of methods) {
33
- cb.call(instance, i);
43
+ for (const { callback, condition } of methods) {
44
+ if (condition) {
45
+ const result = condition({ injector, instance });
46
+ if (result.enabled === false) {
47
+ continue;
48
+ }
49
+ }
50
+ callback.call(instance, injector);
34
51
  }
35
52
  }
36
53
  }
@@ -5,15 +5,20 @@ import type { InjectionToken } from "./provider.js";
5
5
 
6
6
  export type LifecycleCallback = (i: Injector) => void;
7
7
 
8
- export interface InjectableMetadata {
9
- onCreated?: LifecycleCallback[];
10
- onInjected?: LifecycleCallback[];
8
+ export type LifecycleCondition<T> = (ctx:{injector: Injector, instance: T}) => { enabled?: boolean };
9
+
10
+ export interface LifecycleMethod<T> {
11
+ callback: LifecycleCallback;
12
+ condition?: LifecycleCondition<T>;
13
+ }
14
+
15
+ export interface InjectableMetadata<T> {
16
+ onCreated?: LifecycleMethod<T>[];
17
+ onInjected?: LifecycleMethod<T>[];
11
18
  }
12
19
 
13
- export function readMetadata<T>(
14
- target: InjectionToken<T>,
15
- ): InjectableMetadata | null {
16
- const metadata: InjectableMetadata | null = target[Symbol.metadata];
20
+ export function readMetadata<T>(target: InjectionToken<T>): InjectableMetadata<T> | null {
21
+ const metadata: InjectableMetadata<T> | null = target[Symbol.metadata];
17
22
 
18
23
  return metadata;
19
24
  }
@@ -1,6 +1,7 @@
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 declare function injectableEl<T extends ConstructableToken<HTMLElement & {
4
+ export type InjectableEl = HTMLElement & {
5
5
  [INJECTOR]: Injector;
6
- }>>(Base: T, ctx: ClassDecoratorContext): T;
6
+ };
7
+ export declare function injectableEl<T extends ConstructableToken<InjectableEl>>(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;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
+ {"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;AAMhD,MAAM,UAAU,YAAY,CAE1B,IAAO,EAAE,GAA0B;IACnC,MAAM,QAAQ,GAAqC,GAAG,CAAC,QAAQ,CAAC;IAEhE,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 } 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;
2
+ import type { LifecycleCallback, LifecycleCondition, LifecycleMethod } from "./metadata.js";
3
+ export declare function injected<T>(condition?: LifecycleCondition<T>): (val: LifecycleCallback, ctx: ClassMethodDecoratorContext<T>) => void;
4
+ export declare function created<T>(condition?: LifecycleCondition<T>): (val: LifecycleCallback, ctx: ClassMethodDecoratorContext<T>) => void;
5
+ export declare function callLifecycle(instance: object, injector: Injector, methods?: LifecycleMethod<any>[]): void;
@@ -1,21 +1,33 @@
1
- export function injected() {
1
+ export function injected(condition) {
2
2
  return function onInjectDecorator(val, ctx) {
3
3
  const metadata = ctx.metadata;
4
4
  metadata.onInjected ??= [];
5
- metadata.onInjected.push(val);
5
+ metadata.onInjected.push({
6
+ callback: val,
7
+ condition,
8
+ });
6
9
  };
7
10
  }
8
- export function created() {
11
+ export function created(condition) {
9
12
  return function onInjectDecorator(val, ctx) {
10
13
  const metadata = ctx.metadata;
11
14
  metadata.onCreated ??= [];
12
- metadata.onCreated.push(val);
15
+ metadata.onCreated.push({
16
+ callback: val,
17
+ condition,
18
+ });
13
19
  };
14
20
  }
15
- export function callLifecycle(instance, i, methods) {
21
+ export function callLifecycle(instance, injector, methods) {
16
22
  if (methods) {
17
- for (const cb of methods) {
18
- cb.call(instance, i);
23
+ for (const { callback, condition } of methods) {
24
+ if (condition) {
25
+ const result = condition({ injector, instance });
26
+ if (result.enabled === false) {
27
+ continue;
28
+ }
29
+ }
30
+ callback.call(instance, injector);
19
31
  }
20
32
  }
21
33
  }
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/lib/lifecycle.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,QAAQ,CAAI,SAAiC;IAC3D,OAAO,SAAS,iBAAiB,CAC/B,GAAsB,EACtB,GAAmC;QAEnC,MAAM,QAAQ,GAA0B,GAAG,CAAC,QAAQ,CAAC;QACrD,QAAQ,CAAC,UAAU,KAAK,EAAE,CAAC;QAC3B,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;YACvB,QAAQ,EAAE,GAAG;YACb,SAAS;SACV,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAI,SAAiC;IAC1D,OAAO,SAAS,iBAAiB,CAC/B,GAAsB,EACtB,GAAmC;QAEnC,MAAM,QAAQ,GAA0B,GAAG,CAAC,QAAQ,CAAC;QACrD,QAAQ,CAAC,SAAS,KAAK,EAAE,CAAC;QAC1B,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;YACtB,QAAQ,EAAE,GAAG;YACb,SAAS;SACV,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAAgB,EAChB,QAAkB,EAClB,OAAgC;IAEhC,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,OAAO,EAAE,CAAC;YAC9C,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACjD,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;oBAC7B,SAAS;gBACX,CAAC;YACH,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -5,6 +5,7 @@ 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";
8
9
  it("should call onInit and onInject when a service is first created", () => {
9
10
  const i = new Injector();
10
11
  let MyService = (() => {
@@ -193,4 +194,242 @@ it("should call onInject and on init when injected from another service", () =>
193
194
  onInjected: 2,
194
195
  });
195
196
  });
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
+ });
196
435
  //# sourceMappingURL=lifecycle.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.test.js","sourceRoot":"","sources":["../../src/lib/lifecycle.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.test.js","sourceRoot":"","sources":["../../src/lib/lifecycle.test.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,19 @@
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 interface InjectableMetadata {
5
- onCreated?: LifecycleCallback[];
6
- onInjected?: LifecycleCallback[];
4
+ export type LifecycleCondition<T> = (ctx: {
5
+ injector: Injector;
6
+ instance: T;
7
+ }) => {
8
+ enabled?: boolean;
9
+ };
10
+ export interface LifecycleMethod<T> {
11
+ callback: LifecycleCallback;
12
+ condition?: LifecycleCondition<T>;
7
13
  }
8
- export declare function readMetadata<T>(target: InjectionToken<T>): InjectableMetadata | null;
14
+ export interface InjectableMetadata<T> {
15
+ onCreated?: LifecycleMethod<T>[];
16
+ onInjected?: LifecycleMethod<T>[];
17
+ }
18
+ export declare function readMetadata<T>(target: InjectionToken<T>): InjectableMetadata<T> | null;
9
19
  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;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"}
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;AAiBxD,MAAM,UAAU,YAAY,CAAI,MAAyB;IACvD,MAAM,QAAQ,GAAiC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEvE,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"}