@wirestate/lit 0.6.0 → 0.7.0-experimental.1

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.
Files changed (99) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/README.md +246 -10
  3. package/cjs/development/index.js +788 -58
  4. package/cjs/development/index.js.map +1 -1
  5. package/cjs/production/index.js +1 -1
  6. package/cjs/production/index.js.map +1 -1
  7. package/esm/development/commands/on-command-controller.js +59 -0
  8. package/esm/development/commands/on-command-controller.js.map +1 -0
  9. package/esm/development/commands/on-command.js +46 -0
  10. package/esm/development/commands/on-command.js.map +1 -0
  11. package/esm/development/commands/use-on-command.js +31 -0
  12. package/esm/development/commands/use-on-command.js.map +1 -0
  13. package/esm/development/consumption/injection.js +43 -9
  14. package/esm/development/consumption/injection.js.map +1 -1
  15. package/esm/development/consumption/use-injection.js +40 -6
  16. package/esm/development/consumption/use-injection.js.map +1 -1
  17. package/esm/development/context/ioc-context.js +12 -2
  18. package/esm/development/context/ioc-context.js.map +1 -1
  19. package/esm/development/error/error-code.js +4 -0
  20. package/esm/development/error/error-code.js.map +1 -0
  21. package/esm/development/events/on-event-controller.js +68 -0
  22. package/esm/development/events/on-event-controller.js.map +1 -0
  23. package/esm/development/events/on-event.js +68 -0
  24. package/esm/development/events/on-event.js.map +1 -0
  25. package/esm/development/events/use-on-events.js +42 -0
  26. package/esm/development/events/use-on-events.js.map +1 -0
  27. package/esm/development/index.js +16 -4
  28. package/esm/development/index.js.map +1 -1
  29. package/esm/development/provision/injectables-provide.js +47 -0
  30. package/esm/development/provision/injectables-provide.js.map +1 -0
  31. package/esm/development/provision/injectables-provider-controller.js +123 -0
  32. package/esm/development/provision/injectables-provider-controller.js.map +1 -0
  33. package/esm/development/provision/ioc-provide.js +58 -0
  34. package/esm/development/provision/ioc-provide.js.map +1 -0
  35. package/esm/development/provision/ioc-provider-controller.js +75 -0
  36. package/esm/development/provision/ioc-provider-controller.js.map +1 -0
  37. package/esm/development/provision/use-injectables-provider.js +27 -0
  38. package/esm/development/provision/use-injectables-provider.js.map +1 -0
  39. package/esm/development/provision/use-ioc-provision.js +27 -0
  40. package/esm/development/provision/use-ioc-provision.js.map +1 -0
  41. package/esm/development/queries/on-query-controller.js +59 -0
  42. package/esm/development/queries/on-query-controller.js.map +1 -0
  43. package/esm/development/queries/on-query.js +46 -0
  44. package/esm/development/queries/on-query.js.map +1 -0
  45. package/esm/development/queries/use-on-query.js +31 -0
  46. package/esm/development/queries/use-on-query.js.map +1 -0
  47. package/esm/production/commands/on-command-controller.js +1 -0
  48. package/esm/production/commands/on-command-controller.js.map +1 -0
  49. package/esm/production/commands/on-command.js +1 -0
  50. package/esm/production/commands/on-command.js.map +1 -0
  51. package/esm/production/commands/use-on-command.js +1 -0
  52. package/esm/production/commands/use-on-command.js.map +1 -0
  53. package/esm/production/consumption/injection.js +1 -1
  54. package/esm/production/consumption/injection.js.map +1 -1
  55. package/esm/production/consumption/use-injection.js +1 -1
  56. package/esm/production/consumption/use-injection.js.map +1 -1
  57. package/esm/production/context/ioc-context.js +1 -1
  58. package/esm/production/context/ioc-context.js.map +1 -1
  59. package/esm/production/error/error-code.js +1 -0
  60. package/esm/production/error/error-code.js.map +1 -0
  61. package/esm/production/events/on-event-controller.js +1 -0
  62. package/esm/production/events/on-event-controller.js.map +1 -0
  63. package/esm/production/events/on-event.js +1 -0
  64. package/esm/production/events/on-event.js.map +1 -0
  65. package/esm/production/events/use-on-events.js +1 -0
  66. package/esm/production/events/use-on-events.js.map +1 -0
  67. package/esm/production/index.js +1 -1
  68. package/esm/production/provision/injectables-provide.js +1 -0
  69. package/esm/production/provision/injectables-provide.js.map +1 -0
  70. package/esm/production/provision/injectables-provider-controller.js +1 -0
  71. package/esm/production/provision/injectables-provider-controller.js.map +1 -0
  72. package/esm/production/provision/ioc-provide.js +1 -0
  73. package/esm/production/provision/ioc-provide.js.map +1 -0
  74. package/esm/production/provision/ioc-provider-controller.js +1 -0
  75. package/esm/production/provision/ioc-provider-controller.js.map +1 -0
  76. package/esm/production/provision/use-injectables-provider.js +1 -0
  77. package/esm/production/provision/use-injectables-provider.js.map +1 -0
  78. package/esm/production/provision/use-ioc-provision.js +1 -0
  79. package/esm/production/provision/use-ioc-provision.js.map +1 -0
  80. package/esm/production/queries/on-query-controller.js +1 -0
  81. package/esm/production/queries/on-query-controller.js.map +1 -0
  82. package/esm/production/queries/on-query.js +1 -0
  83. package/esm/production/queries/on-query.js.map +1 -0
  84. package/esm/production/queries/use-on-query.js +1 -0
  85. package/esm/production/queries/use-on-query.js.map +1 -0
  86. package/index.d.ts +730 -29
  87. package/package.json +1 -1
  88. package/esm/development/provision/container-provider-controller.js +0 -41
  89. package/esm/development/provision/container-provider-controller.js.map +0 -1
  90. package/esm/development/provision/services-provider-controller.js +0 -63
  91. package/esm/development/provision/services-provider-controller.js.map +0 -1
  92. package/esm/development/provision/use-container-provision.js +0 -9
  93. package/esm/development/provision/use-container-provision.js.map +0 -1
  94. package/esm/production/provision/container-provider-controller.js +0 -1
  95. package/esm/production/provision/container-provider-controller.js.map +0 -1
  96. package/esm/production/provision/services-provider-controller.js +0 -1
  97. package/esm/production/provision/services-provider-controller.js.map +0 -1
  98. package/esm/production/provision/use-container-provision.js +0 -1
  99. package/esm/production/provision/use-container-provision.js.map +0 -1
@@ -2,52 +2,131 @@
2
2
 
3
3
  var context = require('@lit/context');
4
4
  var core = require('@wirestate/core');
5
+ var tslib = require('tslib');
5
6
 
7
+ /**
8
+ * Unique symbol used as a key for the IoC context.
9
+ *
10
+ * @group Context
11
+ */
6
12
  var IOC_CONTAINER_KEY = Symbol("ContainerContext");
7
- var ContainerContext = context.createContext(IOC_CONTAINER_KEY);
13
+ /**
14
+ * Lit context object for providing and consuming the IoC container.
15
+ *
16
+ * @group Context
17
+ */
18
+ var IocContextObject = context.createContext(IOC_CONTAINER_KEY);
8
19
 
9
- function injection(_a) {
10
- var injectionId = _a.injectionId,
11
- subscribe = _a.subscribe;
20
+ /**
21
+ * Decorator to inject a service from the IoC container into a Lit element property.
22
+ *
23
+ * @group Consumption
24
+ *
25
+ * @param optionsOrInjectionId - Injection options or service identifier.
26
+ * @returns An instance of {@link InjectionDecorator}.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * class MyElement extends LitElement {
31
+ * @injection(MyService)
32
+ * private myService!: MyService;
33
+ *
34
+ * public render() {
35
+ * return html`<div>${this.myService.getName()}</div>`;
36
+ * }
37
+ * }
38
+ * ```
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * class MyElement extends LitElement {
43
+ * @injection({ injectionId: MyService, once: true })
44
+ * private myService!: MyService;
45
+ *
46
+ * public render() {
47
+ * return html`<div>${this.myService.getName()}</div>`;
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ function injection(optionsOrInjectionId) {
53
+ var options = typeof optionsOrInjectionId === "object" && optionsOrInjectionId !== null && "injectionId" in optionsOrInjectionId ? optionsOrInjectionId : {
54
+ injectionId: optionsOrInjectionId
55
+ };
12
56
  return function (protoOrTarget, nameOrContext) {
57
+ var injectionId = options.injectionId,
58
+ once = options.once;
13
59
  // Standard decorators branch.
14
60
  if (typeof nameOrContext === "object") {
15
61
  nameOrContext.addInitializer(function () {
16
62
  var _this = this;
17
63
  new context.ContextConsumer(this, {
18
- context: ContainerContext,
64
+ context: IocContextObject,
19
65
  callback: function (it) {
20
66
  protoOrTarget.set.call(_this, it.container.get(injectionId));
21
67
  },
22
- subscribe: subscribe
68
+ subscribe: !once
23
69
  });
24
70
  });
25
71
  } else {
26
72
  // Experimental decorators branch.
27
73
  protoOrTarget.constructor.addInitializer(function (element) {
28
74
  new context.ContextConsumer(element, {
29
- context: ContainerContext,
75
+ context: IocContextObject,
30
76
  callback: function (it) {
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
77
  element[nameOrContext] = it.container.get(injectionId);
33
78
  },
34
- subscribe: subscribe
79
+ subscribe: !once
35
80
  });
36
81
  });
37
82
  }
38
83
  };
39
84
  }
40
85
 
41
- function useInjection(host, _a) {
42
- var once = _a.once,
43
- injectionId = _a.injectionId,
44
- value = _a.value;
86
+ /**
87
+ * Hook (controller) to inject a service from the IoC container.
88
+ *
89
+ * @group Consumption
90
+ *
91
+ * @param host - The host element.
92
+ * @param optionsOrInjectionId - Injection options or service identifier.
93
+ * @returns An instance of {@link UseInjectionValue}.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * class MyElement extends LitElement {
98
+ * private myService = useInjection(this, MyService);
99
+ *
100
+ * render() {
101
+ * return html`<div>${this.myService.value.getName()}</div>`;
102
+ * }
103
+ * }
104
+ * ```
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * class MyElement extends LitElement {
109
+ * private myService = useInjection(this, { injectionId: MyService, once: true });
110
+ *
111
+ * render() {
112
+ * return html`<div>${this.myService.value.getName()}</div>`;
113
+ * }
114
+ * }
115
+ * ```
116
+ */
117
+ function useInjection(host, optionsOrInjectionId) {
118
+ var options = typeof optionsOrInjectionId === "object" && optionsOrInjectionId !== null && "injectionId" in optionsOrInjectionId ? optionsOrInjectionId : {
119
+ injectionId: optionsOrInjectionId
120
+ };
121
+ var once = options.once,
122
+ injectionId = options.injectionId,
123
+ value = options.value;
45
124
  var current = {
46
125
  value: value,
47
126
  injectionId: injectionId
48
127
  };
49
128
  new context.ContextConsumer(host, {
50
- context: ContainerContext,
129
+ context: IocContextObject,
51
130
  subscribe: !once,
52
131
  callback: function (it) {
53
132
  current.value = it.container.get(injectionId);
@@ -56,15 +135,441 @@ function useInjection(host, _a) {
56
135
  return current;
57
136
  }
58
137
 
59
- var ContainerProviderController = /** @class */function () {
60
- function ContainerProviderController(host, container) {
138
+ /**
139
+ * Controller that registers a command handler for the host element's lifetime.
140
+ *
141
+ * @remarks
142
+ * The handler is registered when the host connects and unregistered when it disconnects.
143
+ * It automatically re-registers if the IoC container is updated.
144
+ *
145
+ * @group Commands
146
+ */
147
+ var OnCommandController = /** @class */function () {
148
+ /**
149
+ * @param host - The host element.
150
+ * @param type - Unique identifier of the command to handle.
151
+ * @param handler - The command handler function.
152
+ */
153
+ function OnCommandController(host, type, handler) {
154
+ var _this = this;
155
+ this.bus = null;
156
+ this.unregister = null;
157
+ host.addController(this);
158
+ this.type = type;
159
+ this.handler = handler;
160
+ new context.ContextConsumer(host, {
161
+ context: IocContextObject,
162
+ subscribe: true,
163
+ callback: function (context) {
164
+ _this.bus = context.container.get(core.CommandBus);
165
+ if (host.isConnected) {
166
+ _this.reregister();
167
+ }
168
+ }
169
+ });
170
+ }
171
+ OnCommandController.prototype.hostConnected = function () {
172
+ this.reregister();
173
+ };
174
+ OnCommandController.prototype.hostDisconnected = function () {
175
+ this.cleanup();
176
+ };
177
+ OnCommandController.prototype.reregister = function () {
178
+ this.cleanup();
179
+ if (this.bus) {
180
+ this.unregister = this.bus.register(this.type, this.handler);
181
+ }
182
+ };
183
+ OnCommandController.prototype.cleanup = function () {
184
+ var _a;
185
+ (_a = this.unregister) === null || _a === void 0 ? void 0 : _a.call(this);
186
+ this.unregister = null;
187
+ };
188
+ return OnCommandController;
189
+ }();
190
+
191
+ /**
192
+ * Decorator for Lit element methods that handle a specific command.
193
+ *
194
+ * @remarks
195
+ * The handler is registered when the host connects and unregistered when it disconnects.
196
+ *
197
+ * @group Commands
198
+ *
199
+ * @param type - Unique identifier of the command to handle.
200
+ * @returns A method decorator function.
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * class MyElement extends LitElement {
205
+ * @onCommand("SAVE")
206
+ * private onSave(data: SomeData): void {
207
+ * // handle command
208
+ * }
209
+ * }
210
+ * ```
211
+ */
212
+ function onCommand(type) {
213
+ return function (protoOrTarget, nameOrContext) {
214
+ if (typeof nameOrContext === "object") {
215
+ // Standard decorators:
216
+ nameOrContext.addInitializer(function () {
217
+ var _this = this;
218
+ new OnCommandController(this, type, function (data) {
219
+ return _this[nameOrContext.name](data);
220
+ });
221
+ });
222
+ } else {
223
+ // Experimental legacy decorators:
224
+ protoOrTarget.constructor.addInitializer(function (element) {
225
+ new OnCommandController(element, type, function (data) {
226
+ return element[nameOrContext](data);
227
+ });
228
+ });
229
+ }
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Hook that registers a command handler for the host element's lifetime.
235
+ *
236
+ * @group Commands
237
+ *
238
+ * @param host - The host element.
239
+ * @param options - Command handling options.
240
+ * @param options.type - The command type to listen for.
241
+ * @param options.handler - The command handler function.
242
+ * @returns The command controller instance.
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * class MyElement extends LitElement {
247
+ * private onSave = useOnCommand(this, {
248
+ * type: "SAVE",
249
+ * handler: (data) => console.log("Saving:", data),
250
+ * });
251
+ * }
252
+ * ```
253
+ */
254
+ function useOnCommand(host, _a) {
255
+ var type = _a.type,
256
+ handler = _a.handler;
257
+ return new OnCommandController(host, type, handler);
258
+ }
259
+
260
+ /**
261
+ * Controller that subscribes to events for the host element's lifetime.
262
+ *
263
+ * @remarks
264
+ * The handler is registered when the host connects and unregistered when it disconnects.
265
+ * It automatically re-subscribes if the IoC container is updated.
266
+ *
267
+ * @group Events
268
+ */
269
+ var OnEventController = /** @class */function () {
270
+ /**
271
+ * @param host - The host element.
272
+ * @param types - Event types to listen for. If null, all events will be handled.
273
+ * @param handler - The event handler function.
274
+ */
275
+ function OnEventController(host, types, handler) {
276
+ var _this = this;
277
+ this.bus = null;
278
+ this.unsubscriber = null;
279
+ host.addController(this);
280
+ this.types = types;
281
+ this.handler = handler;
282
+ new context.ContextConsumer(host, {
283
+ context: IocContextObject,
284
+ subscribe: true,
285
+ callback: function (context) {
286
+ _this.bus = context.container.get(core.EventBus);
287
+ if (host.isConnected) {
288
+ _this.resubscribe();
289
+ }
290
+ }
291
+ });
292
+ }
293
+ OnEventController.prototype.hostConnected = function () {
294
+ this.resubscribe();
295
+ };
296
+ OnEventController.prototype.hostDisconnected = function () {
297
+ this.cleanup();
298
+ };
299
+ OnEventController.prototype.resubscribe = function () {
300
+ var _this = this;
301
+ this.cleanup();
302
+ if (this.bus) {
303
+ if (this.types === null) {
304
+ this.unsubscriber = this.bus.subscribe(this.handler);
305
+ } else {
306
+ this.unsubscriber = this.bus.subscribe(function (event) {
307
+ if (_this.types.includes(event.type)) {
308
+ _this.handler(event);
309
+ }
310
+ });
311
+ }
312
+ }
313
+ };
314
+ OnEventController.prototype.cleanup = function () {
315
+ var _a;
316
+ (_a = this.unsubscriber) === null || _a === void 0 ? void 0 : _a.call(this);
317
+ this.unsubscriber = null;
318
+ };
319
+ return OnEventController;
320
+ }();
321
+
322
+ /**
323
+ * Decorator for Lit element methods that handle events from the event bus.
324
+ *
325
+ * @remarks
326
+ * The handler is registered when the host connects and unregistered when it disconnects.
327
+ *
328
+ * @group Events
329
+ *
330
+ * @param types - Event types to listen for. If omitted, all events will be handled.
331
+ * @returns A method decorator function.
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * class MyElement extends LitElement {
336
+ * @onEvent()
337
+ * private onMyEvent(event: Event) {
338
+ * console.log("Event received:", event);
339
+ * }
340
+ * }
341
+ * ```
342
+ *
343
+ * @example
344
+ * ```typescript
345
+ * class MyElement extends LitElement {
346
+ * @onEvent("MY_EVENT_TYPE")
347
+ * private onMyEvent(event: MyEvent) {
348
+ * console.log("Event received:", event);
349
+ * }
350
+ * }
351
+ * ```
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * class MyElement extends LitElement {
356
+ * @onEvent(["MY_EVENT_TYPE_1", "MY_EVENT_TYPE_2"])
357
+ * private onMyEvent(event: Event) {
358
+ * console.log("Event received:", event);
359
+ * }
360
+ * }
361
+ * ```
362
+ */
363
+ function onEvent(types) {
364
+ var normalized = types === undefined ? null : Array.isArray(types) ? tslib.__spreadArray([], types, true) : [types];
365
+ return function (protoOrTarget, nameOrContext) {
366
+ if (typeof nameOrContext === "object") {
367
+ // Standard decorators:
368
+ nameOrContext.addInitializer(function () {
369
+ var _this = this;
370
+ new OnEventController(this, normalized, function (event) {
371
+ return _this[nameOrContext.name](event);
372
+ });
373
+ });
374
+ } else {
375
+ // Experimental legacy decorators:
376
+ protoOrTarget.constructor.addInitializer(function (element) {
377
+ new OnEventController(element, normalized, function (event) {
378
+ return element[nameOrContext](event);
379
+ });
380
+ });
381
+ }
382
+ };
383
+ }
384
+
385
+ /**
386
+ * Hook that subscribes to events for the host element's lifetime.
387
+ *
388
+ * @group Events
389
+ *
390
+ * @param host - The host element.
391
+ * @param options - Event handling options.
392
+ * @param options.handler - Event handler function.
393
+ * @param options.types - Event types to listen for, if null or undefined, all events will be handled.
394
+ * @returns An instance of {@link OnEventController}.
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * class MyElement extends LitElement {
399
+ * private eventHandler = useOnEvents(this, {
400
+ * handler: (event) => console.log(event),
401
+ * });
402
+ * }
403
+ * ```
404
+ *
405
+ * @example
406
+ * ```typescript
407
+ * class MyElement extends LitElement {
408
+ * private eventHandler = useOnEvents(this, {
409
+ * types: ["MY_EVENT"],
410
+ * handler: (event) => console.log(event),
411
+ * });
412
+ * }
413
+ * ```
414
+ */
415
+ function useOnEvents(host, _a) {
416
+ var types = _a.types,
417
+ handler = _a.handler;
418
+ var normalized = types ? Array.isArray(types) ? tslib.__spreadArray([], types, true) : [types] : null;
419
+ return new OnEventController(host, normalized, handler);
420
+ }
421
+
422
+ /**
423
+ * Reactive controller that registers a query handler on the {@link QueryBus} for the host element's lifetime.
424
+ *
425
+ * @remarks
426
+ * The handler is registered when the host connects and unregistered when it disconnects.
427
+ * It automatically re-registers if the IoC container is updated.
428
+ *
429
+ * @group Queries
430
+ */
431
+ var OnQueryController = /** @class */function () {
432
+ /**
433
+ * @param host - The host element.
434
+ * @param type - Unique identifier of the query to handle.
435
+ * @param handler - The query handler function.
436
+ */
437
+ function OnQueryController(host, type, handler) {
438
+ var _this = this;
439
+ this.bus = null;
440
+ this.unregister = null;
441
+ host.addController(this);
442
+ this.type = type;
443
+ this.handler = handler;
444
+ new context.ContextConsumer(host, {
445
+ context: IocContextObject,
446
+ subscribe: true,
447
+ callback: function (context) {
448
+ _this.bus = context.container.get(core.QueryBus);
449
+ if (host.isConnected) {
450
+ _this.reregister();
451
+ }
452
+ }
453
+ });
454
+ }
455
+ OnQueryController.prototype.hostConnected = function () {
456
+ this.reregister();
457
+ };
458
+ OnQueryController.prototype.hostDisconnected = function () {
459
+ this.cleanup();
460
+ };
461
+ OnQueryController.prototype.reregister = function () {
462
+ this.cleanup();
463
+ if (this.bus) {
464
+ this.unregister = this.bus.register(this.type, this.handler);
465
+ }
466
+ };
467
+ OnQueryController.prototype.cleanup = function () {
468
+ var _a;
469
+ (_a = this.unregister) === null || _a === void 0 ? void 0 : _a.call(this);
470
+ this.unregister = null;
471
+ };
472
+ return OnQueryController;
473
+ }();
474
+
475
+ /**
476
+ * Decorator for Lit element methods that handle a specific query.
477
+ *
478
+ * @remarks
479
+ * The handler is registered when the host connects and unregistered when it disconnects.
480
+ *
481
+ * @group Queries
482
+ *
483
+ * @param type - Unique identifier of the query to handle.
484
+ * @returns A method decorator function.
485
+ *
486
+ * @example
487
+ * ```typescript
488
+ * class MyElement extends LitElement {
489
+ * @onQuery("GET_USER_NAME")
490
+ * private onGetUserName(data: QueryData) {
491
+ * return "Alice";
492
+ * }
493
+ * }
494
+ * ```
495
+ */
496
+ function onQuery(type) {
497
+ return function (protoOrTarget, nameOrContext) {
498
+ if (typeof nameOrContext === "object") {
499
+ // Standard decorators:
500
+ nameOrContext.addInitializer(function () {
501
+ var _this = this;
502
+ new OnQueryController(this, type, function (data) {
503
+ return _this[nameOrContext.name](data);
504
+ });
505
+ });
506
+ } else {
507
+ // Experimental legacy decorators:
508
+ protoOrTarget.constructor.addInitializer(function (element) {
509
+ new OnQueryController(element, type, function (data) {
510
+ return element[nameOrContext](data);
511
+ });
512
+ });
513
+ }
514
+ };
515
+ }
516
+
517
+ /**
518
+ * Hook that registers a query handler for the host element's lifetime.
519
+ *
520
+ * @group Queries
521
+ *
522
+ * @param host - The host element.
523
+ * @param options - Query handling options.
524
+ * @param options.type - The query type to handle.
525
+ * @param options.handler - The query handler function.
526
+ * @returns An instance of {@link OnQueryController}.
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * class MyElement extends LitElement {
531
+ * private getUserController = useOnQuery(this, {
532
+ * type: "GET_USER",
533
+ * handler: (data) => ({ name: "Alice" }),
534
+ * });
535
+ * }
536
+ * ```
537
+ */
538
+ function useOnQuery(host, _a) {
539
+ var type = _a.type,
540
+ handler = _a.handler;
541
+ return new OnQueryController(host, type, handler);
542
+ }
543
+
544
+ /**
545
+ * Controller that provides an IoC container context to the host element and its children.
546
+ *
547
+ * @remarks
548
+ * It manages the lifecycle of the container and handles revision updates to notify consumers.
549
+ * The container is created (or used from options) when the controller is instantiated.
550
+ * Seed data is applied when the host connects.
551
+ *
552
+ * @group Provision
553
+ */
554
+ var IocProviderController = /** @class */function () {
555
+ /**
556
+ * @param host - The host element.
557
+ * @param options - Provisioning options.
558
+ * @param options.container - Optional existing container to use. If not provided, a new one will be created.
559
+ * @param options.seed - Optional seed data to apply to the container.
560
+ */
561
+ function IocProviderController(host, _a) {
562
+ var _b = _a === void 0 ? {} : _a,
563
+ container = _b.container,
564
+ seed = _b.seed;
61
565
  var _this = this;
62
566
  this.host = host;
63
567
  this.revision = 1;
64
568
  this.host.addController(this);
65
- this.container = container !== null && container !== void 0 ? container : core.createIocContainer();
569
+ this.container = container !== null && container !== void 0 ? container : core.createContainer();
570
+ this.seed = seed;
66
571
  this.provider = new context.ContextProvider(host, {
67
- context: ContainerContext,
572
+ context: IocContextObject,
68
573
  initialValue: {
69
574
  container: this.container,
70
575
  revision: this.revision,
@@ -74,9 +579,23 @@ var ContainerProviderController = /** @class */function () {
74
579
  }
75
580
  });
76
581
  }
77
- ContainerProviderController.prototype.hostConnected = function () {};
78
- ContainerProviderController.prototype.hostDisconnected = function () {};
79
- ContainerProviderController.prototype.nextRevision = function () {
582
+ Object.defineProperty(IocProviderController.prototype, "value", {
583
+ /**
584
+ * @returns Current {@link IocContext} value served to child consumers.
585
+ */
586
+ get: function () {
587
+ return this.provider.value;
588
+ },
589
+ enumerable: false,
590
+ configurable: true
591
+ });
592
+ IocProviderController.prototype.hostConnected = function () {
593
+ if (this.seed) {
594
+ core.applySharedSeed(this.container, this.seed);
595
+ }
596
+ };
597
+ IocProviderController.prototype.hostDisconnected = function () {};
598
+ IocProviderController.prototype.nextRevision = function () {
80
599
  var _this = this;
81
600
  this.revision += 1;
82
601
  this.provider.setValue({
@@ -88,34 +607,151 @@ var ContainerProviderController = /** @class */function () {
88
607
  });
89
608
  return this.revision;
90
609
  };
91
- return ContainerProviderController;
610
+ return IocProviderController;
92
611
  }();
93
612
 
94
- var ServicesProviderController = /** @class */function () {
95
- function ServicesProviderController(host, options) {
613
+ /**
614
+ * Decorator that provides an IoC container to child components.
615
+ *
616
+ * @remarks
617
+ * The container is provided via Lit context. It is created (or used from options) when the host connects.
618
+ *
619
+ * @group Provision
620
+ *
621
+ * @param options - Provisioning options.
622
+ * @param options.container - Optional existing container to use, if not provided, a new one will be created.
623
+ * @param options.seed - Optional seed data to apply to the container.
624
+ * @returns An instance of {@link IocProviderDecorator}.
625
+ *
626
+ * @example
627
+ * ```typescript
628
+ * class MyRootElement extends LitElement {
629
+ * @iocProvide({ seed: { someData: "value" } })
630
+ * private ioc!: IocProviderController;
631
+ * }
632
+ * ```
633
+ */
634
+ function iocProvide(_a) {
635
+ var _b = _a === void 0 ? {} : _a,
636
+ container = _b.container,
637
+ seed = _b.seed;
638
+ return function (protoOrTarget, nameOrContext) {
639
+ if (typeof nameOrContext === "object") {
640
+ // Standard decorators:
641
+ nameOrContext.addInitializer(function () {
642
+ protoOrTarget.set.call(this, new IocProviderController(this, {
643
+ container: container,
644
+ seed: seed
645
+ }));
646
+ });
647
+ } else {
648
+ var controller_1;
649
+ protoOrTarget.constructor.addInitializer(function (element) {
650
+ controller_1 = new IocProviderController(element, {
651
+ container: container,
652
+ seed: seed
653
+ });
654
+ });
655
+ return {
656
+ get: function () {
657
+ return controller_1;
658
+ },
659
+ set: function () {},
660
+ configurable: true,
661
+ enumerable: true
662
+ };
663
+ }
664
+ };
665
+ }
666
+
667
+ var ERROR_CODE_INVALID_ARGUMENTS = 2051;
668
+
669
+ /**
670
+ * Controller that binds injectables to an IoC container for the host element's lifetime.
671
+ *
672
+ * @remarks
673
+ * Entries are bound when the host connects and unbound when it disconnects.
674
+ * If no `into` context is provided, it uses the nearest {@link IocProviderController}.
675
+ * Seeds are applied before entries are bound.
676
+ *
677
+ * @group Provision
678
+ *
679
+ * @example
680
+ * ```typescript
681
+ * class MyComponent extends LitElement {
682
+ * private services = new InjectablesProviderController(this, {
683
+ * entries: [AuthService, UserService],
684
+ * activate: [AuthService],
685
+ * seeds: [[AuthService, { role: "admin" }]],
686
+ * });
687
+ * }
688
+ * ```
689
+ */
690
+ var InjectablesProviderController = /** @class */function () {
691
+ /**
692
+ * @param host - The host element.
693
+ * @param options - Provisioning options.
694
+ * @param options.entries - List of service entries to bind to the container.
695
+ * @param options.into - Target IoC context; if omitted, uses the nearest provider context.
696
+ * @param options.activate - List of service identifiers to activate immediately after binding.
697
+ * @param options.seeds - Seed data applied before binding.
698
+ */
699
+ function InjectablesProviderController(host, options) {
700
+ var _this = this;
701
+ var _a, _b, _c;
96
702
  this.host = host;
703
+ /**
704
+ * Tracks the context to which entries are currently bound, for correct cleanup on disconnect.
705
+ */
706
+ this.boundContext = null;
97
707
  this.host.addController(this);
98
708
  this.entries = options.entries;
99
- this.activate = options.activate;
100
- this.seeds = options.seeds;
101
- this.into = options.into;
102
- this.consumer = new context.ContextConsumer(host, {
103
- context: ContainerContext,
104
- subscribe: true,
105
- callback: function (it) {
106
- return;
107
- }
108
- });
709
+ this.activate = (_a = options.activate) !== null && _a !== void 0 ? _a : null;
710
+ this.seeds = (_b = options.seeds) !== null && _b !== void 0 ? _b : null;
711
+ this.into = (_c = options.into) !== null && _c !== void 0 ? _c : null;
712
+ if (!this.into) {
713
+ // subscribe: false — binding happens once per connect, not on every revision update.
714
+ this.consumer = new context.ContextConsumer(host, {
715
+ context: IocContextObject,
716
+ subscribe: false,
717
+ callback: function (context) {
718
+ if (!host.isConnected) {
719
+ return;
720
+ }
721
+ _this.bind(context);
722
+ }
723
+ });
724
+ }
109
725
  }
110
- ServicesProviderController.prototype.hostConnected = function () {
111
- var context = this.into ? typeof this.into === "function" ? this.into() : this.into : this.consumer.value;
112
- if (!context) {
113
- if (this.consumer["provided"] === false) {
114
- throw new Error("not provided");
726
+ InjectablesProviderController.prototype.hostConnected = function () {
727
+ var _a;
728
+ if (!this.into) {
729
+ // ContextConsumer with subscribe:false only invokes the user callback once (provided flag stays true
730
+ // after disconnect). On reconnect we fall back to the cached consumer.value so bind() still fires.
731
+ if ((_a = this.consumer) === null || _a === void 0 ? void 0 : _a.value) {
732
+ this.bind(this.consumer.value);
115
733
  }
116
- throw new Error("todo");
734
+ return;
735
+ }
736
+ var context = typeof this.into === "function" ? this.into() : this.into;
737
+ if (!context) {
738
+ throw new core.WirestateError(ERROR_CODE_INVALID_ARGUMENTS, "InjectablesProviderController: the 'into' option resolved to null or undefined. " + "Ensure the value or resolver function returns a valid IocContext.");
739
+ }
740
+ this.bind(context);
741
+ };
742
+ InjectablesProviderController.prototype.hostDisconnected = function () {
743
+ if (!this.boundContext) {
744
+ return;
745
+ }
746
+ this.unbind(this.boundContext);
747
+ };
748
+ InjectablesProviderController.prototype.bind = function (context) {
749
+ if (this.boundContext) {
750
+ // Re-binding without unbinding first would leave stale entries; unbind the previous context.
751
+ this.unbind(this.boundContext);
117
752
  }
118
- // Seed must be applied BEFORE binding so @Inject(INITIAL_STATE_TOKEN) works during activation.
753
+ this.boundContext = context;
754
+ // Seeds must be applied before binding so @Inject(SEEDS_TOKEN) resolves during activation.
119
755
  if (this.seeds) {
120
756
  core.applySeeds(context.container, this.seeds);
121
757
  }
@@ -125,38 +761,132 @@ var ServicesProviderController = /** @class */function () {
125
761
  }
126
762
  if (this.activate) {
127
763
  for (var _b = 0, _c = this.activate; _b < _c.length; _b++) {
128
- var eager = _c[_b];
129
- context.container.get(eager);
764
+ var token = _c[_b];
765
+ context.container.get(token);
130
766
  }
131
767
  }
132
768
  };
133
- ServicesProviderController.prototype.hostDisconnected = function () {
134
- var context = this.into ? typeof this.into === "function" ? this.into() : this.into : this.consumer.value;
135
- if (!context) {
136
- throw new Error("todo");
137
- }
769
+ InjectablesProviderController.prototype.unbind = function (context) {
138
770
  for (var _i = 0, _a = this.entries; _i < _a.length; _i++) {
139
771
  var entry = _a[_i];
140
772
  var token = core.getEntryToken(entry);
141
- context.container.unbind(token);
773
+ if (context.container.isBound(token)) {
774
+ context.container.unbind(token);
775
+ }
142
776
  }
143
- // Remove only this provider's targeted initial state entries.
144
777
  if (this.seeds) {
145
778
  core.unapplySeeds(context.container, this.seeds);
146
779
  }
780
+ this.boundContext = null;
147
781
  };
148
- return ServicesProviderController;
782
+ return InjectablesProviderController;
149
783
  }();
150
784
 
151
- function useContainerProvision(host, _a) {
152
- var container = _a.container;
153
- return new ContainerProviderController(host, container);
785
+ /**
786
+ * Decorator that binds a set of injectables to the nearest IoC container for the host element's lifetime.
787
+ *
788
+ * @remarks
789
+ * Entries are bound when the host connects and unbound when it disconnects.
790
+ *
791
+ * @group Provision
792
+ *
793
+ * @param options - Provisioning options.
794
+ * @returns An instance of {@link InjectablesProviderDecorator}.
795
+ *
796
+ * @example
797
+ * ```typescript
798
+ * class MyComponent extends LitElement {
799
+ * @injectablesProvide({ entries: [AuthService, UserService], activate: [AuthService] })
800
+ * public controller!: InjectablesProviderController<MyComponent>;
801
+ * }
802
+ * ```
803
+ */
804
+ function injectablesProvide(options) {
805
+ return function (protoOrTarget, nameOrContext) {
806
+ if (typeof nameOrContext === "object") {
807
+ // Standard decorators:
808
+ nameOrContext.addInitializer(function () {
809
+ protoOrTarget.set.call(this, new InjectablesProviderController(this, options));
810
+ });
811
+ } else {
812
+ var controller_1;
813
+ protoOrTarget.constructor.addInitializer(function (element) {
814
+ controller_1 = new InjectablesProviderController(element, options);
815
+ });
816
+ return {
817
+ get: function () {
818
+ return controller_1;
819
+ },
820
+ set: function () {},
821
+ configurable: true,
822
+ enumerable: true
823
+ };
824
+ }
825
+ };
826
+ }
827
+
828
+ /**
829
+ * Hook that binds injectables to the nearest IoC container for the host element's lifetime.
830
+ *
831
+ * @group Provision
832
+ *
833
+ * @param host - The host element.
834
+ * @param options - Provisioning options.
835
+ * @returns An instance of {@link InjectablesProviderController}.
836
+ *
837
+ * @example
838
+ * ```typescript
839
+ * class MyComponent extends LitElement {
840
+ * private services = useInjectablesProvider(this, {
841
+ * entries: [AuthService, UserService],
842
+ * activate: [AuthService],
843
+ * });
844
+ * }
845
+ * ```
846
+ */
847
+ function useInjectablesProvider(host, options) {
848
+ return new InjectablesProviderController(host, options);
849
+ }
850
+
851
+ /**
852
+ * Hook that provides an IoC container to the host element and its children.
853
+ *
854
+ * @group Provision
855
+ *
856
+ * @param host - The host element.
857
+ * @param options - Provisioning options.
858
+ * @returns An instance of {@link IocProviderController}.
859
+ *
860
+ * @example
861
+ * ```typescript
862
+ * class MyRootElement extends LitElement {
863
+ * private ioc = useIocProvision(this, { seed: { initialData: "..." } });
864
+ * }
865
+ * ```
866
+ */
867
+ function useIocProvision(host, options) {
868
+ if (options === void 0) {
869
+ options = {};
870
+ }
871
+ return new IocProviderController(host, options);
154
872
  }
155
873
 
156
- exports.ContainerContext = ContainerContext;
157
- exports.ContainerProviderController = ContainerProviderController;
158
- exports.ServicesProviderController = ServicesProviderController;
874
+ exports.InjectablesProviderController = InjectablesProviderController;
875
+ exports.IocContextObject = IocContextObject;
876
+ exports.IocProviderController = IocProviderController;
877
+ exports.OnCommandController = OnCommandController;
878
+ exports.OnEventController = OnEventController;
879
+ exports.OnQueryController = OnQueryController;
880
+ exports.injectablesProvide = injectablesProvide;
159
881
  exports.injection = injection;
160
- exports.useContainerProvision = useContainerProvision;
882
+ exports.iocProvide = iocProvide;
883
+ exports.onCommand = onCommand;
884
+ exports.onEvent = onEvent;
885
+ exports.onQuery = onQuery;
886
+ exports.useInjectablesProvider = useInjectablesProvider;
161
887
  exports.useInjection = useInjection;
888
+ exports.useIocProvision = useIocProvision;
889
+ exports.useOnCommand = useOnCommand;
890
+ exports.useOnEvents = useOnEvents;
891
+ exports.useOnQuery = useOnQuery;
162
892
  //# sourceMappingURL=index.js.map