@wirestate/core 0.6.3 → 0.7.0-experimental.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.
Files changed (167) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +48 -37
  3. package/cjs/development/index.js +325 -91
  4. package/cjs/development/index.js.map +1 -1
  5. package/cjs/development/lib.js +1033 -248
  6. package/cjs/development/lib.js.map +1 -1
  7. package/cjs/development/test-utils.js +95 -32
  8. package/cjs/development/test-utils.js.map +1 -1
  9. package/cjs/production/index.js +1 -1
  10. package/cjs/production/index.js.map +1 -1
  11. package/cjs/production/lib.js +1 -1
  12. package/cjs/production/lib.js.map +1 -1
  13. package/cjs/production/test-utils.js +1 -1
  14. package/cjs/production/test-utils.js.map +1 -1
  15. package/esm/development/alias.js +10 -1
  16. package/esm/development/alias.js.map +1 -1
  17. package/esm/development/bind/bind-constant.js +25 -4
  18. package/esm/development/bind/bind-constant.js.map +1 -1
  19. package/esm/development/bind/bind-dynamic-value.js +27 -7
  20. package/esm/development/bind/bind-dynamic-value.js.map +1 -1
  21. package/esm/development/bind/bind-entry.js +50 -17
  22. package/esm/development/bind/bind-entry.js.map +1 -1
  23. package/esm/development/bind/bind-service.js +71 -19
  24. package/esm/development/bind/bind-service.js.map +1 -1
  25. package/esm/development/bind/get-entry-token.js +21 -5
  26. package/esm/development/bind/get-entry-token.js.map +1 -1
  27. package/esm/development/commands/command-bus.js +93 -46
  28. package/esm/development/commands/command-bus.js.map +1 -1
  29. package/esm/development/commands/command-optional.js +28 -5
  30. package/esm/development/commands/command-optional.js.map +1 -1
  31. package/esm/development/commands/command.js +26 -5
  32. package/esm/development/commands/command.js.map +1 -1
  33. package/esm/development/commands/get-command-handler-metadata.js +8 -3
  34. package/esm/development/commands/get-command-handler-metadata.js.map +1 -1
  35. package/esm/development/commands/on-command.js +19 -3
  36. package/esm/development/commands/on-command.js.map +1 -1
  37. package/esm/development/container/create-base-container.js +57 -0
  38. package/esm/development/container/create-base-container.js.map +1 -0
  39. package/esm/development/container/create-container.js +78 -0
  40. package/esm/development/container/create-container.js.map +1 -0
  41. package/esm/development/container/wire-scope.js +236 -54
  42. package/esm/development/container/wire-scope.js.map +1 -1
  43. package/esm/development/error/error-code.js +2 -1
  44. package/esm/development/error/error-code.js.map +1 -1
  45. package/esm/development/error/wirestate-error.js +25 -4
  46. package/esm/development/error/wirestate-error.js.map +1 -1
  47. package/esm/development/events/build-event-dispatcher.js +20 -2
  48. package/esm/development/events/build-event-dispatcher.js.map +1 -1
  49. package/esm/development/events/emit-event.js +18 -5
  50. package/esm/development/events/emit-event.js.map +1 -1
  51. package/esm/development/events/event-bus.js +58 -9
  52. package/esm/development/events/event-bus.js.map +1 -1
  53. package/esm/development/events/get-event-handler-metadata.js +19 -4
  54. package/esm/development/events/get-event-handler-metadata.js.map +1 -1
  55. package/esm/development/events/on-event.js +31 -2
  56. package/esm/development/events/on-event.js.map +1 -1
  57. package/esm/development/index.js +5 -4
  58. package/esm/development/index.js.map +1 -1
  59. package/esm/development/queries/get-query-handler-metadata.js +20 -4
  60. package/esm/development/queries/get-query-handler-metadata.js.map +1 -1
  61. package/esm/development/queries/on-query.js +24 -2
  62. package/esm/development/queries/on-query.js.map +1 -1
  63. package/esm/development/queries/query-bus.js +82 -31
  64. package/esm/development/queries/query-bus.js.map +1 -1
  65. package/esm/development/queries/query-optional.js +19 -5
  66. package/esm/development/queries/query-optional.js.map +1 -1
  67. package/esm/development/queries/query.js +25 -5
  68. package/esm/development/queries/query.js.map +1 -1
  69. package/esm/development/registry.js +81 -24
  70. package/esm/development/registry.js.map +1 -1
  71. package/esm/development/seeds/apply-seeds.js +19 -5
  72. package/esm/development/seeds/apply-seeds.js.map +1 -1
  73. package/esm/development/seeds/apply-shared-seed.js +16 -4
  74. package/esm/development/seeds/apply-shared-seed.js.map +1 -1
  75. package/esm/development/seeds/tokens.js +31 -0
  76. package/esm/development/seeds/tokens.js.map +1 -0
  77. package/esm/development/seeds/unapply-seeds.js +16 -5
  78. package/esm/development/seeds/unapply-seeds.js.map +1 -1
  79. package/esm/development/service/get-activated-handler-metadata.js +16 -4
  80. package/esm/development/service/get-activated-handler-metadata.js.map +1 -1
  81. package/esm/development/service/get-deactivation-handler-metadata.js +16 -4
  82. package/esm/development/service/get-deactivation-handler-metadata.js.map +1 -1
  83. package/esm/development/service/on-activated.js +22 -2
  84. package/esm/development/service/on-activated.js.map +1 -1
  85. package/esm/development/service/on-deactivation.js +22 -2
  86. package/esm/development/service/on-deactivation.js.map +1 -1
  87. package/esm/development/test-utils/mock-bind-entry.js +17 -7
  88. package/esm/development/test-utils/mock-bind-entry.js.map +1 -1
  89. package/esm/development/test-utils/mock-bind-service.js +17 -7
  90. package/esm/development/test-utils/mock-bind-service.js.map +1 -1
  91. package/esm/development/test-utils/mock-container.js +25 -8
  92. package/esm/development/test-utils/mock-container.js.map +1 -1
  93. package/esm/development/test-utils/mock-service.js +18 -5
  94. package/esm/development/test-utils/mock-service.js.map +1 -1
  95. package/esm/development/test-utils/mock-unbind-service.js +16 -3
  96. package/esm/development/test-utils/mock-unbind-service.js.map +1 -1
  97. package/esm/development/types/commands.js +6 -1
  98. package/esm/development/types/commands.js.map +1 -1
  99. package/esm/production/alias.js +1 -1
  100. package/esm/production/alias.js.map +1 -1
  101. package/esm/production/bind/bind-constant.js +1 -1
  102. package/esm/production/bind/bind-constant.js.map +1 -1
  103. package/esm/production/bind/bind-dynamic-value.js +1 -1
  104. package/esm/production/bind/bind-dynamic-value.js.map +1 -1
  105. package/esm/production/bind/bind-entry.js +1 -1
  106. package/esm/production/bind/bind-entry.js.map +1 -1
  107. package/esm/production/bind/bind-service.js.map +1 -1
  108. package/esm/production/bind/get-entry-token.js.map +1 -1
  109. package/esm/production/commands/command-bus.js +1 -1
  110. package/esm/production/commands/command-bus.js.map +1 -1
  111. package/esm/production/commands/command-optional.js.map +1 -1
  112. package/esm/production/commands/command.js.map +1 -1
  113. package/esm/production/commands/get-command-handler-metadata.js.map +1 -1
  114. package/esm/production/commands/on-command.js.map +1 -1
  115. package/esm/production/container/create-base-container.js +1 -0
  116. package/esm/production/container/create-base-container.js.map +1 -0
  117. package/esm/production/container/create-container.js +1 -0
  118. package/esm/production/container/create-container.js.map +1 -0
  119. package/esm/production/container/wire-scope.js +1 -1
  120. package/esm/production/container/wire-scope.js.map +1 -1
  121. package/esm/production/error/error-code.js +1 -1
  122. package/esm/production/error/error-code.js.map +1 -1
  123. package/esm/production/error/wirestate-error.js.map +1 -1
  124. package/esm/production/events/build-event-dispatcher.js.map +1 -1
  125. package/esm/production/events/emit-event.js.map +1 -1
  126. package/esm/production/events/event-bus.js +1 -1
  127. package/esm/production/events/event-bus.js.map +1 -1
  128. package/esm/production/events/get-event-handler-metadata.js.map +1 -1
  129. package/esm/production/events/on-event.js.map +1 -1
  130. package/esm/production/index.js +1 -1
  131. package/esm/production/queries/get-query-handler-metadata.js.map +1 -1
  132. package/esm/production/queries/on-query.js.map +1 -1
  133. package/esm/production/queries/query-bus.js +1 -1
  134. package/esm/production/queries/query-bus.js.map +1 -1
  135. package/esm/production/queries/query-optional.js.map +1 -1
  136. package/esm/production/queries/query.js.map +1 -1
  137. package/esm/production/registry.js +1 -1
  138. package/esm/production/registry.js.map +1 -1
  139. package/esm/production/seeds/apply-seeds.js +1 -1
  140. package/esm/production/seeds/apply-seeds.js.map +1 -1
  141. package/esm/production/seeds/apply-shared-seed.js +1 -1
  142. package/esm/production/seeds/apply-shared-seed.js.map +1 -1
  143. package/esm/production/seeds/tokens.js +1 -0
  144. package/esm/production/seeds/tokens.js.map +1 -0
  145. package/esm/production/seeds/unapply-seeds.js +1 -1
  146. package/esm/production/seeds/unapply-seeds.js.map +1 -1
  147. package/esm/production/service/get-activated-handler-metadata.js.map +1 -1
  148. package/esm/production/service/get-deactivation-handler-metadata.js.map +1 -1
  149. package/esm/production/service/on-activated.js.map +1 -1
  150. package/esm/production/service/on-deactivation.js.map +1 -1
  151. package/esm/production/test-utils/mock-bind-entry.js +1 -1
  152. package/esm/production/test-utils/mock-bind-entry.js.map +1 -1
  153. package/esm/production/test-utils/mock-bind-service.js +1 -1
  154. package/esm/production/test-utils/mock-bind-service.js.map +1 -1
  155. package/esm/production/test-utils/mock-container.js +1 -1
  156. package/esm/production/test-utils/mock-container.js.map +1 -1
  157. package/esm/production/test-utils/mock-service.js.map +1 -1
  158. package/esm/production/test-utils/mock-unbind-service.js.map +1 -1
  159. package/esm/production/types/commands.js.map +1 -1
  160. package/index.d.ts +1159 -229
  161. package/lib.d.ts +128 -9
  162. package/package.json +1 -2
  163. package/test-utils.d.ts +140 -40
  164. package/esm/development/container/create-ioc-container.js +0 -35
  165. package/esm/development/container/create-ioc-container.js.map +0 -1
  166. package/esm/production/container/create-ioc-container.js +0 -1
  167. package/esm/production/container/create-ioc-container.js.map +0 -1
@@ -4,6 +4,7 @@ var inversify = require('inversify');
4
4
  var tslib = require('tslib');
5
5
 
6
6
  var ERROR_CODE_GENERIC = 1;
7
+ var ERROR_CODE_VALIDATION_ERROR = 50;
7
8
  var ERROR_CODE_INVALID_ARGUMENTS = 51;
8
9
  var ERROR_CODE_BINDING_SCOPE = 52;
9
10
  var ERROR_CODE_FAILED_TO_RESOLVE_QUERY_HANDLER = 101;
@@ -12,20 +13,41 @@ var ERROR_CODE_ACCESS_BEFORE_ACTIVATION = 200;
12
13
  var ERROR_CODE_ACCESS_AFTER_DISPOSAL = 201;
13
14
 
14
15
  /**
15
- * A custom error class that contains generic error information for Wirestate-related issues.
16
+ * Base error class for all Wirestate-related exceptions.
16
17
  *
17
- * This class extends the native `Error` class and is used to represent errors specific
18
- * to the Wirestate library, providing more structured error handling.
18
+ * @remarks
19
+ * `WirestateError` provides structured error information, including a numeric error code
20
+ * and a descriptive message. It is used throughout the library to signal lifecycle
21
+ * violations, messaging failures, and configuration issues.
22
+ *
23
+ * @group Error
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * try {
28
+ * scope.getContainer();
29
+ * } catch (error) {
30
+ * if (error instanceof WirestateError) {
31
+ * console.error(`Error code: ${error.code}`);
32
+ * }
33
+ * }
34
+ * ```
19
35
  */
20
36
  var WirestateError = /** @class */function (_super) {
21
37
  tslib.__extends(WirestateError, _super);
38
+ /**
39
+ * Creates a new instance of WirestateError.
40
+ *
41
+ * @param code - Numeric identifier for the error (defaults to ERROR_CODE_GENERIC).
42
+ * @param detail - Optional descriptive message.
43
+ */
22
44
  function WirestateError(code, detail) {
23
45
  if (code === void 0) {
24
46
  code = ERROR_CODE_GENERIC;
25
47
  }
26
48
  var _this = _super.call(this) || this;
27
49
  /**
28
- * Name or error class to help differentiate error class in minified environments.
50
+ * The name of the error class, useful for identification in minified environments.
29
51
  */
30
52
  _this.name = "WirestateError";
31
53
  _this.code = code;
@@ -36,23 +58,64 @@ var WirestateError = /** @class */function (_super) {
36
58
  }(Error);
37
59
 
38
60
  /**
39
- * Binds a constant value to a token in the container.
61
+ * Binds a constant value to a service identifier in the container.
62
+ *
63
+ * @remarks
64
+ * Use this to register configuration values, primitive constants, or pre-instantiated objects.
65
+ * Constant values are bound with a singleton scope by default.
66
+ *
67
+ * @group Bind
68
+ *
69
+ * @template T - Type of the service being bound.
70
+ *
71
+ * @param container - Target Inversify {@link Container}.
72
+ * @param entry - Descriptor containing `id` (token) and `value` (constant).
73
+ * @returns Inversify fluent syntax for additional constraints.
74
+ *
75
+ * @throws {@link WirestateError} If `entry.scopeBindingType` is not `Singleton`.
40
76
  *
41
- * @param container - target Inversify container
42
- * @param entry - entry descriptor to bind
77
+ * @example
78
+ * ```typescript
79
+ * const API_URL: unique symbol = Symbol("API_URL");
80
+ *
81
+ * bindConstant(container, {
82
+ * id: API_URL,
83
+ * value: "https://api.example.com"
84
+ * });
85
+ * ```
43
86
  */
44
87
  function bindConstant(container, entry) {
45
88
  if (entry.scopeBindingType && entry.scopeBindingType !== inversify.bindingScopeValues.Singleton) {
46
89
  throw new WirestateError(ERROR_CODE_BINDING_SCOPE, "Provided unexpected binding scope for constant value.");
47
90
  }
48
- container.bind(entry.id).toConstantValue(entry.value);
91
+ return container.bind(entry.id).toConstantValue(entry.value);
49
92
  }
50
93
 
51
94
  /**
52
- * Binds a constant value to a token in the container.
95
+ * Binds a dynamic value (factory-based) to an identifier in the container.
96
+ *
97
+ * @remarks
98
+ * Use this when the value depends on runtime state or requires logic during resolution.
99
+ * The binding uses `entry.factory` if provided; otherwise, it falls back to `entry.value`.
100
+ * Supports custom scoping via `entry.scopeBindingType`.
101
+ *
102
+ * @group Bind
103
+ *
104
+ * @template T - Type of the value being bound.
105
+ *
106
+ * @param container - Target Inversify {@link Container}.
107
+ * @param entry - Descriptor containing `id`, `factory` or `value`, and optional `scopeBindingType`.
108
+ * @returns Inversify fluent syntax for additional constraints.
53
109
  *
54
- * @param container - target Inversify container
55
- * @param entry - descriptor of entry to bind
110
+ * @example
111
+ * ```typescript
112
+ * const DATE_NOW: unique symbol = Symbol("DATE_NOW");
113
+ *
114
+ * bindDynamicValue(container, {
115
+ * id: DATE_NOW,
116
+ * factory: () => new Date()
117
+ * });
118
+ * ```
56
119
  */
57
120
  function bindDynamicValue(container, entry) {
58
121
  var binding = container.bind(entry.id).toDynamicValue(function () {
@@ -62,31 +125,40 @@ function bindDynamicValue(container, entry) {
62
125
  return entry.value;
63
126
  });
64
127
  if (!entry.scopeBindingType) {
65
- return;
128
+ return binding;
66
129
  } else if (entry.scopeBindingType === inversify.bindingScopeValues.Transient) {
67
- binding.inTransientScope();
130
+ return binding.inTransientScope();
68
131
  } else if (entry.scopeBindingType === inversify.bindingScopeValues.Request) {
69
- binding.inRequestScope();
132
+ return binding.inRequestScope();
70
133
  } else {
71
- binding.inSingletonScope();
134
+ return binding.inSingletonScope();
72
135
  }
73
136
  }
74
137
 
75
138
  /**
76
- * Command execution status.
139
+ * Represents the current state of a command execution.
140
+ *
141
+ * @group Commands
77
142
  */
78
143
  exports.CommandStatus = void 0;
79
144
  (function (CommandStatus) {
145
+ /** The command task has started but not yet completed. */
80
146
  CommandStatus["PENDING"] = "pending";
147
+ /** The command task has successfully completed. */
81
148
  CommandStatus["SETTLED"] = "settled";
149
+ /** The command task failed with an error. */
82
150
  CommandStatus["ERROR"] = "error";
83
151
  })(exports.CommandStatus || (exports.CommandStatus = {}));
84
152
 
85
153
  /**
86
- * Dispatches commands to handlers.
154
+ * Orchestrates command dispatching and handler registration.
87
155
  *
88
- * Unlike queries, command execution always wraps the handler in a promise
89
- * and returns a descriptor with task, status, and responder.
156
+ * @remarks
157
+ * The `CommandBus` provides a way to decouple command dispatchers from their handlers.
158
+ * It supports handler shadowing: when multiple handlers are registered for the same type,
159
+ * the last registered one takes priority.
160
+ *
161
+ * @group Commands
90
162
  */
91
163
  var CommandBus = /** @class */function () {
92
164
  function CommandBus() {
@@ -97,45 +169,32 @@ var CommandBus = /** @class */function () {
97
169
  this.handlers = new Map();
98
170
  }
99
171
  /**
100
- * Registers a command handler.
101
- * Returns an unregister function.
102
- *
103
- * @param type - command type
104
- * @param handler - handler function
105
- * @returns unregister function
172
+ * Removes all registered command handlers from the bus.
106
173
  */
107
- CommandBus.prototype.register = function (type, handler) {
108
- var _this = this;
109
- var stack = this.handlers.get(type);
110
- if (!stack) {
111
- stack = [];
112
- this.handlers.set(type, stack);
113
- }
114
- stack.push(handler);
115
- return function () {
116
- var current = _this.handlers.get(type);
117
- if (!current) {
118
- return;
119
- }
120
- var index = current.indexOf(handler);
121
- if (index >= 0) {
122
- current.splice(index, 1);
123
- }
124
- // Clean empty stacks.
125
- if (current.length === 0) {
126
- _this.handlers.delete(type);
127
- }
128
- };
174
+ CommandBus.prototype.clear = function () {
175
+ this.handlers.clear();
129
176
  };
130
177
  /**
131
178
  * Dispatches a command to the last registered handler.
132
- * Wraps the handler execution in a promise and returns a descriptor.
133
179
  *
134
- * @param type - command type
135
- * @param data - command payload
136
- * @returns command descriptor with task, status, and responder
180
+ * @remarks
181
+ * Execution is always asynchronous. The handler's return value is wrapped in a Promise.
182
+ * Returns a {@link CommandDescriptor} that tracks the execution status and task.
137
183
  *
138
- * @throws if no handler is registered
184
+ * @template R - Type of the command result.
185
+ * @template D - Type of the command payload data.
186
+ *
187
+ * @param type - Command identifier.
188
+ * @param data - Optional payload for the handler.
189
+ * @returns A descriptor for the executing command.
190
+ *
191
+ * @throws {@link WirestateError} If no handler is registered.
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * const descriptor: CommandDescriptor<User> = commandBus.command<User, string>("GET_USER", "id-123");
196
+ * const user: User = await descriptor.task;
197
+ * ```
139
198
  */
140
199
  CommandBus.prototype.command = function (type, data) {
141
200
  var stack = this.handlers.get(type);
@@ -159,96 +218,214 @@ var CommandBus = /** @class */function () {
159
218
  return descriptor;
160
219
  };
161
220
  /**
162
- * Dispatches a command to the last registered handler, returning null if no handler exists.
221
+ * Dispatches a command if a handler exists, otherwise returns null.
222
+ *
223
+ * @template R - Type of the command result.
224
+ * @template D - Type of the command payload data.
163
225
  *
164
- * @param type - command type
165
- * @param data - command payload
166
- * @returns command descriptor or null if no handler is registered
226
+ * @param type - Command identifier.
227
+ * @param data - Optional payload for the handler.
228
+ * @returns A command descriptor, or `null` if no handler is found.
167
229
  */
168
230
  CommandBus.prototype.commandOptional = function (type, data) {
169
231
  var stack = this.handlers.get(type);
170
232
  return (stack === null || stack === void 0 ? void 0 : stack.length) ? this.command(type, data) : null;
171
233
  };
172
234
  /**
173
- * Checks if a handler is registered for the given type.
235
+ * Checks if at least one handler is registered for the given command type.
174
236
  *
175
- * @param type - command type
176
- * @returns true if handler exists
237
+ * @param type - Command identifier.
238
+ * @returns `true` if a handler is available, `false` otherwise.
177
239
  */
178
240
  CommandBus.prototype.has = function (type) {
179
241
  var _a;
180
242
  return Boolean((_a = this.handlers.get(type)) === null || _a === void 0 ? void 0 : _a.length);
181
243
  };
182
244
  /**
183
- * Removes all registered handlers.
245
+ * Registers a handler for a specific command type.
246
+ *
247
+ * @remarks
248
+ * If multiple handlers are registered for the same type, they are stored in a stack.
249
+ * The most recently registered handler will be used for dispatching.
250
+ *
251
+ * @template D - Type of the command payload data.
252
+ * @template R - Type of the command execution result.
253
+ *
254
+ * @param type - Command identifier.
255
+ * @param handler - Function to execute when the command is dispatched.
256
+ * @returns A function to unregister the handler.
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const unregister: CommandUnregister = commandBus.register("LOG_MESSAGE", (message: string) => {
261
+ * console.log(message);
262
+ * });
263
+ * ```
184
264
  */
185
- CommandBus.prototype.clear = function () {
186
- this.handlers.clear();
265
+ CommandBus.prototype.register = function (type, handler) {
266
+ var _this = this;
267
+ var stack = this.handlers.get(type);
268
+ if (!stack) {
269
+ stack = [];
270
+ this.handlers.set(type, stack);
271
+ }
272
+ stack.push(handler);
273
+ return function () {
274
+ return _this.unregister(type, handler);
275
+ };
276
+ };
277
+ /**
278
+ * Removes a previously registered command handler.
279
+ *
280
+ * @remarks
281
+ * If the handler was not registered for the given type, this operation does nothing.
282
+ *
283
+ * @template D - Type of the command payload data.
284
+ * @template R - Type of the command execution result.
285
+ *
286
+ * @param type - Command identifier.
287
+ * @param handler - The handler function instance to remove.
288
+ */
289
+ CommandBus.prototype.unregister = function (type, handler) {
290
+ var current = this.handlers.get(type);
291
+ if (!current) {
292
+ return;
293
+ }
294
+ var index = current.indexOf(handler);
295
+ if (index >= 0) {
296
+ current.splice(index, 1);
297
+ }
298
+ // Clean empty stacks.
299
+ if (current.length === 0) {
300
+ this.handlers.delete(type);
301
+ }
187
302
  };
188
303
  return CommandBus;
189
304
  }();
190
305
 
191
306
  /**
192
- * Token for the container-scoped seeds map.
193
- */
194
- var SEEDS_TOKEN = Symbol("@wirestate/seeds");
195
- /**
196
- * Token for the container-scoped shared seed object.
197
- */
198
- var SEED_TOKEN = Symbol("@wirestate/seed");
199
- /**
200
- * Map of class constructors to their declared query handlers.
201
- * Inherited via a prototype chain at resolve time.
307
+ * Registry of class constructors to their declared query handlers.
308
+ *
309
+ * @remarks
310
+ * This map is populated by the {@link OnQuery} decorator. Handlers are
311
+ * inherited via the prototype chain at service resolution time.
312
+ *
313
+ * @group Queries
314
+ * @internal
202
315
  */
203
316
  var QUERY_HANDLER_METADATA = new WeakMap();
204
317
  /**
205
- * Map of class constructors to their declared command handlers.
206
- * Inherited via a prototype chain at resolve time.
318
+ * Registry of class constructors to their declared command handlers.
319
+ *
320
+ * @remarks
321
+ * This map is populated by the {@link OnCommand} decorator. Handlers are
322
+ * inherited via the prototype chain at service resolution time.
323
+ *
324
+ * @group Commands
325
+ * @internal
207
326
  */
208
327
  var COMMAND_HANDLER_METADATA = new WeakMap();
209
328
  /**
210
- * Map of class constructors to their `@OnActivated`-decorated method names.
211
- * Inherited via a prototype chain at resolve time.
329
+ * Registry of class constructors to their `@OnActivated`-decorated method names.
330
+ *
331
+ * @remarks
332
+ * This map is populated by the {@link OnActivated} decorator. Activation hooks are
333
+ * executed in parent-to-child order during service initialization.
334
+ *
335
+ * @group Service
336
+ * @internal
212
337
  */
213
338
  var ACTIVATED_HANDLER_METADATA = new WeakMap();
214
339
  /**
215
- * Map of class constructors to their `@OnDeactivation`-decorated method names.
216
- * Inherited via a prototype chain at resolve time.
340
+ * Registry of class constructors to their `@OnDeactivation`-decorated method names.
341
+ *
342
+ * @remarks
343
+ * This map is populated by the {@link OnDeactivation} decorator. Deactivation hooks are
344
+ * executed in parent-to-child order during service disposal.
345
+ *
346
+ * @group Service
347
+ * @internal
217
348
  */
218
349
  var DEACTIVATION_HANDLER_METADATA = new WeakMap();
219
350
  /**
220
- * Map of class constructors for their declared event handlers.
221
- * Inherited via a prototype chain at resolve time.
351
+ * Registry of class constructors to their declared event handlers.
352
+ *
353
+ * @remarks
354
+ * This map is populated by the {@link OnEvent} decorator. Event handlers are
355
+ * inherited via the prototype chain at service resolution time.
356
+ *
357
+ * @group Events
358
+ * @internal
222
359
  */
223
360
  var EVENT_HANDLER_METADATA = new WeakMap();
224
361
  /**
225
- * Private storage for service-to-container references.
362
+ * Internal storage for mapping service instances to their originating Inversify containers.
363
+ *
364
+ * @remarks
365
+ * Used during the service lifecycle to ensure that resolution and messaging
366
+ * occur within the correct container context.
367
+ *
368
+ * @group Bind
369
+ * @internal
226
370
  */
227
371
  var CONTAINER_REFS_BY_SERVICE = new WeakMap();
228
372
  /**
229
- * Private storage for injected WireScope instances per service.
373
+ * Internal storage for managing injected {@link WireScope} instances per service.
374
+ *
375
+ * @remarks
376
+ * Tracks the scopes associated with a service instance for lifecycle management
377
+ * and cleanup.
378
+ *
379
+ * @group Container
380
+ * @internal
230
381
  */
231
382
  var WIRE_SCOPES_BY_SERVICE = new WeakMap();
232
383
  /**
233
- * Private storage for service event unsubscribers.
384
+ * Internal storage for service event unsubscribers.
385
+ *
386
+ * @remarks
387
+ * Stores the unsubscription functions returned when a service automatically
388
+ * subscribes to events via the {@link OnEvent} decorator.
389
+ *
390
+ * @group Events
391
+ * @internal
234
392
  */
235
393
  var EVENT_UNSUBSCRIBERS_BY_SERVICE = new WeakMap();
236
394
  /**
237
- * Private storage for service query unregisters.
395
+ * Internal storage for service query unregisters.
396
+ *
397
+ * @remarks
398
+ * Stores the unregistration functions returned when a service automatically
399
+ * registers query handlers via the {@link OnQuery} decorator.
400
+ *
401
+ * @group Queries
402
+ * @internal
238
403
  */
239
404
  var QUERY_UNREGISTERS_BY_SERVICE = new WeakMap();
240
405
  /**
241
- * Private storage for service command unregisters.
406
+ * Internal storage for service command unregisters.
407
+ *
408
+ * @remarks
409
+ * Stores the unregistration functions returned when a service automatically
410
+ * registers command handlers via the {@link OnCommand} decorator.
411
+ *
412
+ * @group Commands
413
+ * @internal
242
414
  */
243
415
  var COMMAND_UNREGISTERS_BY_SERVICE = new WeakMap();
244
416
 
245
417
  /**
246
418
  * Retrieves `@OnCommand` metadata from the class hierarchy.
247
- * Returns handlers ordered from base to derived class.
248
419
  *
249
- * @param instance - service instance
250
- * @returns metadata list
420
+ * @remarks
421
+ * Traverses the prototype chain to collect all command handlers.
422
+ * Returns metadata ordered from base class to derived class to ensure parent-first execution.
423
+ *
424
+ * @group Commands
251
425
  * @internal
426
+ *
427
+ * @param instance - The service instance to inspect.
428
+ * @returns A read-only array of metadata for all discovered command handlers.
252
429
  */
253
430
  function getCommandHandlerMetadata(instance) {
254
431
  var constructor = instance.constructor;
@@ -266,16 +443,40 @@ function getCommandHandlerMetadata(instance) {
266
443
  }
267
444
 
268
445
  /**
269
- * Dispatches events to subscribers.
446
+ * Orchestrates event broadcasting to multiple subscribers.
447
+ *
448
+ * @remarks
449
+ * The `EventBus` facilitates decoupled, many-to-many communication.
450
+ * Unlike commands or queries, which are dispatched to a single handler,
451
+ * events are broadcast to all registered subscribers.
452
+ *
453
+ * @group Events
270
454
  */
271
455
  var EventBus = /** @class */function () {
272
456
  function EventBus() {
273
457
  this.handlers = new Set();
274
458
  }
275
459
  /**
276
- * Broadcasts an event to all subscribers.
460
+ * Broadcasts an event to all registered subscribers.
461
+ *
462
+ * @remarks
463
+ * Handlers are executed in a try-catch block to ensure that a single
464
+ * failing subscriber does not prevent others from receiving the event.
277
465
  *
278
- * @param event - event to emit
466
+ * @template P - Type of the event payload.
467
+ * @template T - Type of the event identifier.
468
+ * @template F - Type of the event source.
469
+ *
470
+ * @param event - The event object to broadcast.
471
+ *
472
+ * @example
473
+ * ```typescript
474
+ * eventBus.emit({
475
+ * type: "USER_LOGGED_IN",
476
+ * payload: { userId: "123" },
477
+ * from: AuthService
478
+ * });
479
+ * ```
279
480
  */
280
481
  EventBus.prototype.emit = function (event) {
281
482
  // Snapshot prevents concurrent modification errors if handlers sub/unsub during emit.
@@ -291,21 +492,46 @@ var EventBus = /** @class */function () {
291
492
  }
292
493
  };
293
494
  /**
294
- * Subscribes a handler to all events.
295
- * Returns an unsubscribe function.
495
+ * Registers a handler to receive all broadcasted events.
496
+ *
497
+ * @param handler - Function invoked for every emitted event.
498
+ * @returns An {@link EventUnsubscriber} function to remove the subscription.
296
499
  *
297
- * @param handler - event handler function
298
- * @returns unsubscribe function
500
+ * @example
501
+ * ```typescript
502
+ * const unsubscribe: EventUnsubscriber = eventBus.subscribe((event) => {
503
+ * console.log('Received event:', event);
504
+ * });
505
+ * ```
299
506
  */
300
507
  EventBus.prototype.subscribe = function (handler) {
301
508
  var _this = this;
302
509
  this.handlers.add(handler);
303
510
  return function () {
304
- _this.handlers.delete(handler);
511
+ return _this.unsubscribe(handler);
305
512
  };
306
513
  };
307
514
  /**
308
- * Removes all registered handlers.
515
+ * Removes a previously registered event handler.
516
+ *
517
+ * @remarks
518
+ * If the handler was not subscribed, this operation does nothing.
519
+ *
520
+ * @param handler - The handler function instance to remove.
521
+ */
522
+ EventBus.prototype.unsubscribe = function (handler) {
523
+ this.handlers.delete(handler);
524
+ };
525
+ /**
526
+ * Checks if the bus has any active subscribers.
527
+ *
528
+ * @returns `true` if at least one handler is registered, `false` otherwise.
529
+ */
530
+ EventBus.prototype.has = function () {
531
+ return this.handlers.size > 0;
532
+ };
533
+ /**
534
+ * Removes all registered handlers from the bus.
309
535
  *
310
536
  * @internal
311
537
  */
@@ -316,7 +542,15 @@ var EventBus = /** @class */function () {
316
542
  }();
317
543
 
318
544
  /**
319
- * Dispatches queries to handlers.
545
+ * Orchestrates query dispatching and handler registration.
546
+ *
547
+ * @remarks
548
+ * The `QueryBus` provides a request-response mechanism for decoupled communication.
549
+ * It supports handler shadowing: when multiple handlers are registered for the same type,
550
+ * the last registered one (e.g., at the component level) takes priority over earlier ones
551
+ * (e.g., at the global service level).
552
+ *
553
+ * @group Queries
320
554
  */
321
555
  var QueryBus = /** @class */function () {
322
556
  function QueryBus() {
@@ -327,12 +561,23 @@ var QueryBus = /** @class */function () {
327
561
  this.handlers = new Map();
328
562
  }
329
563
  /**
330
- * Registers a query handler.
331
- * Returns an unregister function.
564
+ * Registers a handler for a specific query type.
332
565
  *
333
- * @param type - query type
334
- * @param handler - handler function
335
- * @returns unregister function
566
+ * @remarks
567
+ * If multiple handlers are registered for the same type, they are stored in a stack.
568
+ * The most recently registered handler will be used for resolution.
569
+ *
570
+ * @template D - Type of the query input data.
571
+ * @template R - Type of the query result.
572
+ *
573
+ * @param type - Unique query identifier.
574
+ * @param handler - Function to execute when the query is dispatched.
575
+ * @returns A function to unregister the handler.
576
+ *
577
+ * @example
578
+ * ```typescript
579
+ * const unregister: QueryUnregister = queryBus.register("GET_NOW", () => Date.now());
580
+ * ```
336
581
  */
337
582
  QueryBus.prototype.register = function (type, handler) {
338
583
  var _this = this;
@@ -343,28 +588,56 @@ var QueryBus = /** @class */function () {
343
588
  }
344
589
  stack.push(handler);
345
590
  return function () {
346
- var current = _this.handlers.get(type);
347
- if (!current) {
348
- return;
349
- }
350
- var index = current.indexOf(handler);
351
- if (index >= 0) {
352
- current.splice(index, 1);
353
- }
354
- // Clean empty stacks.
355
- if (current.length === 0) {
356
- _this.handlers.delete(type);
357
- }
591
+ return _this.unregister(type, handler);
358
592
  };
359
593
  };
360
594
  /**
361
- * Dispatches a query to the last registered handler.
595
+ * Removes a previously registered query handler.
596
+ *
597
+ * @remarks
598
+ * If the handler was not registered for the given type, this operation does nothing.
362
599
  *
363
- * @param type - query type
364
- * @param data - query payload
365
- * @returns query result
600
+ * @template D - Type of the query input data.
601
+ * @template R - Type of the query result.
366
602
  *
367
- * @throws if no handler is registered
603
+ * @param type - Unique query identifier.
604
+ * @param handler - The handler function instance to remove.
605
+ */
606
+ QueryBus.prototype.unregister = function (type, handler) {
607
+ var current = this.handlers.get(type);
608
+ if (!current) {
609
+ return;
610
+ }
611
+ var index = current.indexOf(handler);
612
+ if (index >= 0) {
613
+ current.splice(index, 1);
614
+ }
615
+ // Clean empty stacks.
616
+ if (current.length === 0) {
617
+ this.handlers.delete(type);
618
+ }
619
+ };
620
+ /**
621
+ * Dispatches a query to the last registered handler and returns the result.
622
+ *
623
+ * @remarks
624
+ * Query handlers can be synchronous or asynchronous. The result is returned as-is
625
+ * (or as a Promise if the handler is async).
626
+ *
627
+ * @template R - Type of the expected query result.
628
+ * @template D - Type of the data (payload) passed to the query.
629
+ * @template T - Type of the query identifier.
630
+ *
631
+ * @param type - Unique query identifier.
632
+ * @param data - Optional input data for the handler.
633
+ * @returns The result of the query execution.
634
+ *
635
+ * @throws {@link WirestateError} If no handler is registered for the given type.
636
+ *
637
+ * @example
638
+ * ```typescript
639
+ * const user: User = await queryBus.query<User, string>("FIND_USER", "user-id-123");
640
+ * ```
368
641
  */
369
642
  QueryBus.prototype.query = function (type, data) {
370
643
  var stack = this.handlers.get(type);
@@ -375,11 +648,15 @@ var QueryBus = /** @class */function () {
375
648
  throw new WirestateError(ERROR_CODE_FAILED_TO_RESOLVE_QUERY_HANDLER, "No query handler registered in container for type: '".concat(String(type), "'."));
376
649
  };
377
650
  /**
378
- * Dispatches a query to the last registered handler, returning null if no handler exists.
651
+ * Dispatches a query if a handler exists, otherwise returns null.
652
+ *
653
+ * @template R - Type of the expected query result.
654
+ * @template D - Type of the data (payload) passed to the query.
655
+ * @template T - Type of the query identifier.
379
656
  *
380
- * @param type - query type
381
- * @param data - query payload
382
- * @returns query result or null if no handler is registered
657
+ * @param type - Unique query identifier.
658
+ * @param data - Optional input data for the handler.
659
+ * @returns The query result, or `null` if no handler is found.
383
660
  */
384
661
  QueryBus.prototype.queryOptional = function (type, data) {
385
662
  var stack = this.handlers.get(type);
@@ -389,17 +666,17 @@ var QueryBus = /** @class */function () {
389
666
  return null;
390
667
  };
391
668
  /**
392
- * Checks if a handler is registered for the given type.
669
+ * Checks if at least one handler is registered for the given query type.
393
670
  *
394
- * @param type - query type
395
- * @returns true if handler exists
671
+ * @param type - Unique query identifier.
672
+ * @returns `true` if a handler is available, `false` otherwise.
396
673
  */
397
674
  QueryBus.prototype.has = function (type) {
398
675
  var stack = this.handlers.get(type);
399
676
  return Boolean(stack && stack.length);
400
677
  };
401
678
  /**
402
- * Removes all registered handlers.
679
+ * Removes all registered query handlers from the bus.
403
680
  *
404
681
  * @internal
405
682
  */
@@ -410,9 +687,44 @@ var QueryBus = /** @class */function () {
410
687
  }();
411
688
 
412
689
  /**
413
- * Injectable scope providing access to wirestate buses and seeds.
414
- * Each injecting service receives its own instance (transient scope).
415
- * The scope is activated and deactivated automatically alongside its owner service.
690
+ * Unique symbol used as a token for the container-scoped seeds map.
691
+ *
692
+ * @remarks
693
+ * This token is used to bind and resolve the {@link SeedsMap} in the Inversify {@link Container}.
694
+ *
695
+ * @group Seeds
696
+ *
697
+ * @example
698
+ * ```typescript
699
+ * const seedsMap: SeedsMap = container.get(SEEDS_TOKEN);
700
+ * ```
701
+ */
702
+ var SEEDS_TOKEN = Symbol("@wirestate/core/seeds");
703
+ /**
704
+ * Unique symbol used as a token for the container-scoped shared seed object.
705
+ *
706
+ * @remarks
707
+ * This token is used to bind and resolve the global shared seed object in the Inversify {@link Container}.
708
+ *
709
+ * @group Seeds
710
+ *
711
+ * @example
712
+ * ```typescript
713
+ * const sharedSeed: AnyObject = container.get(SEED_TOKEN);
714
+ * ```
715
+ */
716
+ var SEED_TOKEN = Symbol("@wirestate/core/seed");
717
+
718
+ /**
719
+ * A transient bridge providing services with access to Wirestate buses, lazy resolution, and seeds.
720
+ *
721
+ * @remarks
722
+ * Every service bound via {@link bindService} receives its own unique `WireScope` instance.
723
+ * It acts as a facade to the IoC container while enforcing lifecycle safety.
724
+ *
725
+ * Methods are available only while the scope is "active" (after service activation and before deactivation).
726
+ *
727
+ * @group Container
416
728
  */
417
729
  var WireScope = /** @class */function () {
418
730
  function WireScope(container) {
@@ -423,12 +735,18 @@ var WireScope = /** @class */function () {
423
735
  this.isDisposed = false;
424
736
  }
425
737
  /**
426
- * Access the IoC container.
427
- * Available only for activated instances of scope.
738
+ * Provides direct access to the underlying Inversify {@link Container}.
739
+ *
740
+ * @returns The active {@link Container}.
428
741
  *
429
- * @returns active container
742
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
430
743
  *
431
- * @throws WirestateError if scope is not activated or already disposed
744
+ * @example
745
+ * ```typescript
746
+ * const container: Container = scope.getContainer();
747
+ *
748
+ * container.bind("TOKEN").toConstantValue(42);
749
+ * ```
432
750
  */
433
751
  WireScope.prototype.getContainer = function () {
434
752
  if (this.container) {
@@ -441,41 +759,64 @@ var WireScope = /** @class */function () {
441
759
  }
442
760
  };
443
761
  /**
444
- * Resolves a sibling service or injected value.
445
- * Use for lazy resolution or circular dependency breaking.
446
- * Available only for activated containers.
762
+ * Lazily resolves a service or value from the container.
763
+ *
764
+ * @remarks
765
+ * Use this to break circular dependencies or for services that are not needed immediately.
766
+ *
767
+ * @template T - Type of the service or value to resolve.
768
+ *
769
+ * @param injectionId - Service token (class constructor, symbol, or string).
770
+ * @returns The resolved instance or value.
447
771
  *
448
- * @param injectionId - injection identifier
449
- * @returns resolved injection, service instance, or generic value
772
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
773
+ * @throws {Error} If the service cannot be resolved from the container.
450
774
  *
451
- * @throws WirestateError if scope is not activated
775
+ * @example
776
+ * ```typescript
777
+ * const service: MyService = scope.resolve(MyService);
778
+ * ```
452
779
  */
453
780
  WireScope.prototype.resolve = function (injectionId) {
454
781
  return this.getContainer().get(injectionId);
455
782
  };
456
783
  /**
457
- * Resolves a sibling service or injected value.
458
- * Use for lazy resolution or circular dependency breaking.
459
- * Available only for activated containers.
784
+ * Lazily resolves a service if it is bound, otherwise returns null.
460
785
  *
461
- * @param injectionId - injection identifier
462
- * @returns resolved injection, service instance, generic value, or null if it is not bound
786
+ * @template T - Type of the service or value to resolve.
463
787
  *
464
- * @throws WirestateError if scope is not activated
788
+ * @param injectionId - Service token (class constructor, symbol, or string).
789
+ * @returns The resolved instance, value, or `null` if not bound.
790
+ *
791
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
792
+ *
793
+ * @example
794
+ * ```typescript
795
+ * const logger: Logger | null = scope.resolveOptional(Logger);
796
+ *
797
+ * logger?.info("Resolved optionally");
798
+ * ```
465
799
  */
466
800
  WireScope.prototype.resolveOptional = function (injectionId) {
467
801
  var container = this.getContainer();
468
802
  return container.isBound(injectionId) ? container.get(injectionId) : null;
469
803
  };
470
804
  /**
471
- * Broadcasts an event.
472
- * Available only for activated containers.
805
+ * Dispatches an event to the {@link EventBus}.
806
+ *
807
+ * @template P - Type of the event payload.
808
+ * @template T - Type of the event identifier.
809
+ *
810
+ * @param type - Event identifier.
811
+ * @param payload - Optional data associated with the event.
812
+ * @param from - Optional source identifier (defaults to current scope).
473
813
  *
474
- * @param type - type of event to emit
475
- * @param payload - optional payload to send with the event
476
- * @param from - optional sender of the event
814
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
477
815
  *
478
- * @throws WirestateError if scope is not activated
816
+ * @example
817
+ * ```typescript
818
+ * scope.emitEvent("VALUE_CHANGED", { value: "abcd" });
819
+ * ```
479
820
  */
480
821
  WireScope.prototype.emitEvent = function (type, payload, from) {
481
822
  this.getContainer().get(EventBus).emit({
@@ -485,63 +826,210 @@ var WireScope = /** @class */function () {
485
826
  });
486
827
  };
487
828
  /**
488
- * Dispatches a query and returns the result.
489
- * Available only for activated containers.
829
+ * Subscribes to all events on the {@link EventBus}.
830
+ *
831
+ * @param handler - Function called for every emitted event.
832
+ * @returns A function to unsubscribe.
833
+ *
834
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
835
+ *
836
+ * @example
837
+ * ```typescript
838
+ * const unsubscribe: EventUnsubscriber = scope.subscribeToEvent((event) => {
839
+ * console.log("Event received:", event);
840
+ * });
841
+ * ```
842
+ */
843
+ WireScope.prototype.subscribeToEvent = function (handler) {
844
+ return this.getContainer().get(EventBus).subscribe(handler);
845
+ };
846
+ /**
847
+ * Unsubscribes a specific handler from the {@link EventBus}.
848
+ *
849
+ * @param handler - The handler instance to remove.
850
+ *
851
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
852
+ *
853
+ * @example
854
+ * ```typescript
855
+ * scope.unsubscribeFromEvent(this.onEvent);
856
+ * ```
857
+ */
858
+ WireScope.prototype.unsubscribeFromEvent = function (handler) {
859
+ this.getContainer().get(EventBus).unsubscribe(handler);
860
+ };
861
+ /**
862
+ * Dispatches a query and waits for the result.
863
+ *
864
+ * @template R - Type of the query result.
865
+ * @template D - Type of the query data (payload).
866
+ * @template T - Type of the query identifier.
490
867
  *
491
- * @param type - query type
492
- * @param data - query data
493
- * @returns query result
868
+ * @param type - Query identifier.
869
+ * @param data - Input data for the query handler.
870
+ * @returns The query result (can be a Promise).
494
871
  *
495
- * @throws WirestateError if scope is not activated
872
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
873
+ * @throws {@link WirestateError} If no query handler is registered.
874
+ *
875
+ * @example
876
+ * ```typescript
877
+ * const user: User = await scope.queryData("GET_USER", { id: 1 });
878
+ * ```
496
879
  */
497
880
  WireScope.prototype.queryData = function (type, data) {
498
881
  return this.getContainer().get(QueryBus).query(type, data);
499
882
  };
500
883
  /**
501
- * Dispatches a query and returns the result.
502
- * Available only for activated containers.
884
+ * Dispatches a query and returns the result, or null if no handler is registered.
885
+ *
886
+ * @template R - Type of the query result.
887
+ * @template D - Type of the query data (payload).
888
+ * @template T - Type of the query identifier.
503
889
  *
504
- * @param type - query type
505
- * @param data - query data
506
- * @returns query result or null if handler is not registered
890
+ * @param type - Query identifier.
891
+ * @param data - Input data for the query handler.
892
+ * @returns The query result or `null`.
893
+ *
894
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
895
+ *
896
+ * @example
897
+ * ```typescript
898
+ * const config: Config | null = await scope.queryOptionalData("GET_CONFIG");
899
+ * ```
507
900
  */
508
901
  WireScope.prototype.queryOptionalData = function (type, data) {
509
902
  return this.getContainer().get(QueryBus).queryOptional(type, data);
510
903
  };
511
904
  /**
512
- * Dispatches a command and returns the descriptor.
513
- * Available only for activated containers.
905
+ * Registers a handler for a specific query type.
906
+ *
907
+ * @template D - Type of the query data (payload).
908
+ * @template R - Type of the query result.
909
+ *
910
+ * @param type - Query identifier.
911
+ * @param handler - The handler function.
912
+ * @returns A function to unregister the handler.
913
+ *
914
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
915
+ *
916
+ * @example
917
+ * ```typescript
918
+ * scope.registerQueryHandler("GET_DATE_NOW", () => new Date());
919
+ * ```
920
+ */
921
+ WireScope.prototype.registerQueryHandler = function (type, handler) {
922
+ return this.getContainer().get(QueryBus).register(type, handler);
923
+ };
924
+ /**
925
+ * Removes a specific query handler registration.
926
+ *
927
+ * @template D - Type of the query data (payload).
928
+ * @template R - Type of the query result.
929
+ *
930
+ * @param type - Query identifier.
931
+ * @param handler - The handler instance to remove.
932
+ *
933
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
934
+ *
935
+ * @example
936
+ * ```typescript
937
+ * scope.unregisterQueryHandler("GET_DATE_NOW", this.onGetDateNow);
938
+ * ```
939
+ */
940
+ WireScope.prototype.unregisterQueryHandler = function (type, handler) {
941
+ this.getContainer().get(QueryBus).unregister(type, handler);
942
+ };
943
+ /**
944
+ * Dispatches a command and returns a descriptor to track its progress.
945
+ *
946
+ * @template R - Type of the command result.
947
+ * @template D - Type of the command payload.
948
+ * @template T - Type of the command identifier.
949
+ *
950
+ * @param type - Command identifier.
951
+ * @param data - Payload for the command.
952
+ * @returns A {@link CommandDescriptor}.
953
+ *
954
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
955
+ * @throws {@link WirestateError} If no command handler is registered.
514
956
  *
515
- * @param type - command type
516
- * @param data - command data
517
- * @returns command descriptor
957
+ * @example
958
+ * ```typescript
959
+ * const descriptor: CommandDescriptor = scope.executeCommand("LOGOUT");
518
960
  *
519
- * @throws WirestateError if scope is not activated
961
+ * await descriptor.task;
962
+ * ```
520
963
  */
521
964
  WireScope.prototype.executeCommand = function (type, data) {
522
965
  return this.getContainer().get(CommandBus).command(type, data);
523
966
  };
524
967
  /**
525
- * Dispatches a command and returns the descriptor.
526
- * Available only for activated containers.
968
+ * Dispatches a command if a handler is registered, otherwise returns null.
527
969
  *
528
- * @param type - command type
529
- * @param data - command data
530
- * @returns command descriptor or null if handler is not registered
970
+ * @template R - Type of the command result.
971
+ * @template D - Type of the command payload.
972
+ * @template T - Type of the command identifier.
973
+ *
974
+ * @param type - Command identifier.
975
+ * @param data - Payload for the command.
976
+ * @returns A {@link CommandDescriptor} or `null`.
977
+ *
978
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
979
+ *
980
+ * @example
981
+ * ```typescript
982
+ * const descriptor: CommandDescriptor | null = scope.executeOptionalCommand("CLEANUP_CACHE");
983
+ *
984
+ * if (descriptor) {
985
+ * await descriptor.task;
986
+ * }
987
+ * ```
531
988
  */
532
989
  WireScope.prototype.executeOptionalCommand = function (type, data) {
533
990
  return this.getContainer().get(CommandBus).commandOptional(type, data);
534
991
  };
535
992
  /**
536
- * Reads seed for the provided injection.
537
- * Returns shared seed if parameters are not provided.
538
- * Available only for activated containers.
993
+ * Registers a handler for a specific command type.
994
+ *
995
+ * @template D - Type of the command payload.
996
+ * @template R - Type of the command result.
539
997
  *
540
- * @param seed - lookup key
541
- * @returns seed data or null if missing
998
+ * @param type - Command identifier.
999
+ * @param handler - The handler function.
1000
+ * @returns A function to unregister the handler.
542
1001
  *
543
- * @throws WirestateError if context is not activated
1002
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
1003
+ *
1004
+ * @example
1005
+ * ```typescript
1006
+ * scope.registerCommandHandler("LOG_ERROR", (error) => {
1007
+ * console.error(error);
1008
+ * });
1009
+ * ```
544
1010
  */
1011
+ WireScope.prototype.registerCommandHandler = function (type, handler) {
1012
+ return this.getContainer().get(CommandBus).register(type, handler);
1013
+ };
1014
+ /**
1015
+ * Removes a specific command handler registration.
1016
+ *
1017
+ * @template D - Type of the command payload.
1018
+ * @template R - Type of the command result.
1019
+ *
1020
+ * @param type - Command identifier.
1021
+ * @param handler - The handler instance to remove.
1022
+ *
1023
+ * @throws {@link WirestateError} If accessed before activation or after disposal.
1024
+ *
1025
+ * @example
1026
+ * ```typescript
1027
+ * scope.unregisterCommandHandler("LOG_ERROR", this.handleLogError);
1028
+ * ```
1029
+ */
1030
+ WireScope.prototype.unregisterCommandHandler = function (type, handler) {
1031
+ this.getContainer().get(CommandBus).unregister(type, handler);
1032
+ };
545
1033
  WireScope.prototype.getSeed = function (seed) {
546
1034
  return seed ? this.getContainer().get(SEEDS_TOKEN).get(seed) || null : this.getContainer().get(SEED_TOKEN);
547
1035
  };
@@ -550,12 +1038,27 @@ var WireScope = /** @class */function () {
550
1038
  }();
551
1039
 
552
1040
  /**
553
- * Retrieves `@OnEvent` metadata from the class hierarchy.
554
- * Returns handlers ordered from base to derived class.
1041
+ * Retrieves event handler metadata for a service instance by traversing its prototype chain.
1042
+ *
1043
+ * @remarks
1044
+ * This utility collects metadata registered via the {@link OnEvent} decorator.
1045
+ * It ensures that handlers are returned in parent-to-child order (base class handlers first),
1046
+ * which is critical for maintaining predictable event execution patterns in inherited services.
555
1047
  *
556
- * @param instance - service instance
557
- * @returns metadata list
1048
+ * @group Events
558
1049
  * @internal
1050
+ *
1051
+ * @param instance - The service instance to scan for event handlers.
1052
+ * @returns A read-only array of event handler metadata, ordered from base to derived class.
1053
+ *
1054
+ * @example
1055
+ * ```typescript
1056
+ * const metadata = getEventHandlerMetadata(myService);
1057
+ *
1058
+ * metadata.forEach(meta => {
1059
+ * console.log(`Method ${String(meta.propertyKey)} handles event ${String(meta.type)}`);
1060
+ * });
1061
+ * ```
559
1062
  */
560
1063
  function getEventHandlerMetadata(instance) {
561
1064
  var constructor = instance.constructor;
@@ -575,9 +1078,27 @@ function getEventHandlerMetadata(instance) {
575
1078
  /**
576
1079
  * Composes service event handlers into a single dispatcher.
577
1080
  *
578
- * @param instance - service instance
579
- * @returns event handler or null if no handlers are declared
1081
+ * @remarks
1082
+ * Scans the provided instance for methods decorated with {@link OnEvent}.
1083
+ * If handlers are found, it returns a fan-out function that dispatches events
1084
+ * to all matching methods based on their registered event types.
1085
+ *
1086
+ * @group Events
580
1087
  * @internal
1088
+ *
1089
+ * @template T - Type of the service instance.
1090
+ *
1091
+ * @param instance - Service instance to scan for handlers.
1092
+ * @returns A unified event handler, or `null` if no handlers are declared.
1093
+ *
1094
+ * @example
1095
+ * ```typescript
1096
+ * const dispatcher = buildEventDispatcher(myServiceInstance);
1097
+ *
1098
+ * if (dispatcher) {
1099
+ * dispatcher({ type: "SOME_EVENT", payload: { data: 123 } });
1100
+ * }
1101
+ * ```
581
1102
  */
582
1103
  function buildEventDispatcher(instance) {
583
1104
  var entries = [];
@@ -608,12 +1129,28 @@ function buildEventDispatcher(instance) {
608
1129
  }
609
1130
 
610
1131
  /**
611
- * Retrieves `@OnQuery` metadata from the class hierarchy.
612
- * Returns handlers ordered from base to derived class.
1132
+ * Retrieves query handler metadata for a service instance by traversing its prototype chain.
1133
+ *
1134
+ * @remarks
1135
+ * This utility collects metadata registered via the {@link OnQuery} decorator.
1136
+ * It ensures that handlers are returned in parent-to-child order (base class handlers first).
1137
+ * Since queries support shadowing, child class handlers registered later will effectively
1138
+ * override parent handlers for the same query type.
613
1139
  *
614
- * @param instance - service instance
615
- * @returns metadata list
1140
+ * @group Queries
616
1141
  * @internal
1142
+ *
1143
+ * @param instance - The service instance to scan for query handlers.
1144
+ * @returns A read-only array of query handler metadata, ordered from base to derived class.
1145
+ *
1146
+ * @example
1147
+ * ```typescript
1148
+ * const metadata = getQueryHandlerMetadata(myService);
1149
+ *
1150
+ * metadata.forEach(meta => {
1151
+ * console.log(`Method ${String(meta.methodName)} handles query ${String(meta.type)}`);
1152
+ * });
1153
+ * ```
617
1154
  */
618
1155
  function getQueryHandlerMetadata(instance) {
619
1156
  var constructor = instance.constructor;
@@ -631,12 +1168,24 @@ function getQueryHandlerMetadata(instance) {
631
1168
  }
632
1169
 
633
1170
  /**
634
- * Retrieves `@OnActivated` method names from the class hierarchy.
635
- * Returns method names ordered from base to derived class.
1171
+ * Retrieves the names of methods decorated with {@link OnActivated} by traversing the prototype chain.
636
1172
  *
637
- * @param instance - service instance
638
- * @returns list of method names
1173
+ * @remarks
1174
+ * This utility ensures that handlers are returned in parent-to-child order (base class handlers first),
1175
+ * maintaining a predictable initialization sequence for inherited services.
1176
+ *
1177
+ * @group Service
639
1178
  * @internal
1179
+ *
1180
+ * @param instance - The service instance to scan for activation handlers.
1181
+ * @returns A read-only array of method names (strings or symbols).
1182
+ *
1183
+ * @example
1184
+ * ```typescript
1185
+ * const methods = getActivatedHandlerMetadata(myService);
1186
+ *
1187
+ * methods.forEach(methodName => (myService as any)[methodName]());
1188
+ * ```
640
1189
  */
641
1190
  function getActivatedHandlerMetadata(instance) {
642
1191
  var constructor = instance.constructor;
@@ -654,12 +1203,24 @@ function getActivatedHandlerMetadata(instance) {
654
1203
  }
655
1204
 
656
1205
  /**
657
- * Retrieves `@OnDeactivation` method names from the class hierarchy.
658
- * Returns method names ordered from base to derived class.
1206
+ * Retrieves the names of methods decorated with {@link OnDeactivation} by traversing the prototype chain.
1207
+ *
1208
+ * @remarks
1209
+ * This utility ensures that handlers are returned in parent-to-child order (base class handlers first),
1210
+ * maintaining a predictable cleanup sequence for inherited services.
659
1211
  *
660
- * @param instance - service instance
661
- * @returns list of method names
1212
+ * @group Service
662
1213
  * @internal
1214
+ *
1215
+ * @param instance - The service instance to scan for deactivation handlers.
1216
+ * @returns A read-only array of method names (strings or symbols).
1217
+ *
1218
+ * @example
1219
+ * ```typescript
1220
+ * const methods = getDeactivationHandlerMetadata(myService);
1221
+ *
1222
+ * methods.forEach(methodName => (myService as any)[methodName]());
1223
+ * ```
663
1224
  */
664
1225
  function getDeactivationHandlerMetadata(instance) {
665
1226
  var constructor = instance.constructor;
@@ -677,12 +1238,56 @@ function getDeactivationHandlerMetadata(instance) {
677
1238
  }
678
1239
 
679
1240
  /**
680
- * Registers a service class in the container with activation/deactivation logic.
681
- * Ensures container references, event subscriptions, command and query handlers are managed correctly.
1241
+ * Binds a service class in the {@link Container} with full lifecycle and messaging integration.
1242
+ *
1243
+ * @remarks
1244
+ * Binds the class in singleton scope and configures Inversify activation/deactivation hooks to:
1245
+ * - Manage the `IS_DISPOSED` lifecycle state flag.
1246
+ * - Trigger `@OnActivated` and `@OnDeactivation` decorated methods.
1247
+ * - Register/unregister `@OnCommand`, `@OnEvent` and `@OnQuery` handlers.
1248
+ * - Set up event dispatching and bus subscriptions.
1249
+ * - Track and dispose injected {@link WireScope} instances.
1250
+ *
1251
+ * @group Bind
1252
+ *
1253
+ * @template T - Type of the service instance.
682
1254
  *
683
- * @param container - target Inversify container
684
- * @param entry - service constructor
685
- * @param options - options object to control binding flow
1255
+ * @param container - Target Inversify {@link Container}.
1256
+ * @param entry - Service class constructor.
1257
+ * @param options - Configuration options for the binding.
1258
+ *
1259
+ * @example
1260
+ * ```typescript
1261
+ * @Injectable()
1262
+ * class UserService {
1263
+ * @OnActivated()
1264
+ * public onActivated(): void {
1265
+ * console.log("UserService activated");
1266
+ * }
1267
+ *
1268
+ * @OnDeactivation()
1269
+ * public onDeactivation(): void {
1270
+ * console.log("UserService deactivating");
1271
+ * }
1272
+ *
1273
+ * @OnEvent("USER_LOGGED_IN")
1274
+ * private onUserLoggedIn(event: UserLoggedInEvent) {
1275
+ * console.log('User logged in:', event.payload);
1276
+ * }
1277
+ *
1278
+ * @OnCommand("LOG_DATE_NOW")
1279
+ * private onLogDateNow(): void {
1280
+ * console.log("Date now:", new Date());
1281
+ * }
1282
+ *
1283
+ * @OnQuery("DATE_NOW")
1284
+ * private onQueryDateNow(): void {
1285
+ * return new Date();
1286
+ * }
1287
+ * }
1288
+ *
1289
+ * bindService(container, UserService);
1290
+ * ```
686
1291
  */
687
1292
  function bindService(container, entry, options) {
688
1293
  // Inversify's fluent binding API only allows a single `.onActivation` /
@@ -776,9 +1381,10 @@ function bindService(container, entry, options) {
776
1381
  /**
777
1382
  * Attaches a event subscription to a service.
778
1383
  *
779
- * @param service - service instance
780
- * @param handler - event handler
781
1384
  * @internal
1385
+ *
1386
+ * @param service - Service instance.
1387
+ * @param handler - Event handler.
782
1388
  */
783
1389
  function attachEventsSubscription(service, handler) {
784
1390
  var _a;
@@ -790,8 +1396,9 @@ function attachEventsSubscription(service, handler) {
790
1396
  /**
791
1397
  * Detaches the event subscription from a service.
792
1398
  *
793
- * @param service - service instance
794
1399
  * @internal
1400
+ *
1401
+ * @param service - Service instance.
795
1402
  */
796
1403
  function detachEventSubscription(service) {
797
1404
  var unsubscribe = EVENT_UNSUBSCRIBERS_BY_SERVICE.get(service);
@@ -803,9 +1410,10 @@ function detachEventSubscription(service) {
803
1410
  /**
804
1411
  * Registers a query unregister function for a service.
805
1412
  *
806
- * @param service - service instance
807
- * @param unregister - query unregister function
808
1413
  * @internal
1414
+ *
1415
+ * @param service - Service instance.
1416
+ * @param unregister - Query unregister function.
809
1417
  */
810
1418
  function attachQueryUnregister(service, unregister) {
811
1419
  var list = QUERY_UNREGISTERS_BY_SERVICE.get(service);
@@ -818,8 +1426,9 @@ function attachQueryUnregister(service, unregister) {
818
1426
  /**
819
1427
  * Executes and removes all query unregister functions for a service.
820
1428
  *
821
- * @param service - service instance
822
1429
  * @internal
1430
+ *
1431
+ * @param service - Service instance.
823
1432
  */
824
1433
  function detachQueryUnregister(service) {
825
1434
  var list = QUERY_UNREGISTERS_BY_SERVICE.get(service);
@@ -835,9 +1444,10 @@ function detachQueryUnregister(service) {
835
1444
  /**
836
1445
  * Registers a command unregister function for a service.
837
1446
  *
838
- * @param service - service instance
839
- * @param unregister - command unregister function
840
1447
  * @internal
1448
+ *
1449
+ * @param service - Service instance.
1450
+ * @param unregister - Command unregister function.
841
1451
  */
842
1452
  function attachCommandUnregister(service, unregister) {
843
1453
  var list = COMMAND_UNREGISTERS_BY_SERVICE.get(service);
@@ -850,8 +1460,9 @@ function attachCommandUnregister(service, unregister) {
850
1460
  /**
851
1461
  * Executes and removes all command unregister functions for a service.
852
1462
  *
853
- * @param service - service instance
854
1463
  * @internal
1464
+ *
1465
+ * @param service - Service instance.
855
1466
  */
856
1467
  function detachCommandUnregister(service) {
857
1468
  var list = COMMAND_UNREGISTERS_BY_SERVICE.get(service);
@@ -869,11 +1480,12 @@ function detachCommandUnregister(service) {
869
1480
  * Property iteration happens only when the constructor metadata declares a WireScope
870
1481
  * parameter, avoiding false positives from manually created or subclassed scopes.
871
1482
  *
872
- * todo: Simplify this part.
1483
+ * Todo: Simplify this part..
873
1484
  *
874
- * @param service - service instance
875
- * @param Service - service constructor
876
1485
  * @internal
1486
+ *
1487
+ * @param service - Service instance.
1488
+ * @param Service - Service constructor.
877
1489
  */
878
1490
  function attachWireScopes(service, Service) {
879
1491
  var paramTypes = Reflect.getMetadata("design:paramtypes", Service);
@@ -898,10 +1510,11 @@ function attachWireScopes(service, Service) {
898
1510
  * Marks all injected WireScope instances for this service as disposed and removes
899
1511
  * the stored references.
900
1512
  *
901
- * todo: Simplify this part.
1513
+ * Todo: Simplify this part..
902
1514
  *
903
- * @param service - service instance
904
1515
  * @internal
1516
+ *
1517
+ * @param service - Service instance.
905
1518
  */
906
1519
  function detachWireScopes(service) {
907
1520
  var scopes = WIRE_SCOPES_BY_SERVICE.get(service);
@@ -917,72 +1530,242 @@ function detachWireScopes(service) {
917
1530
  }
918
1531
 
919
1532
  /**
920
- * Binds a single service entry to the container, dispatching to the
921
- * correct binding strategy based on the descriptor's `type` field.
1533
+ * Binds an entry to the Inversify {@link Container} using the appropriate strategy.
1534
+ *
1535
+ * @remarks
1536
+ * This is a high-level dispatching function that selects the binding method based on the `entry` type:
1537
+ * - **Class Constructor**: Binds as a singleton service via {@link bindService}.
1538
+ * - **ConstantValue**: Binds a fixed value via {@link bindConstant}.
1539
+ * - **DynamicValue**: Binds a factory-generated value via {@link bindDynamicValue}.
1540
+ * - **Instance**: Binds a value as a class instance via {@link bindService}.
1541
+ *
1542
+ * @group Bind
1543
+ *
1544
+ * @template T - Type of the object being bound.
1545
+ *
1546
+ * @param container - Target Inversify {@link Container}.
1547
+ * @param entry - Class constructor or {@link InjectableDescriptor} describing the service.
1548
+ * @param options - Optional binding configuration (primarily used for class-based services).
1549
+ *
1550
+ * @throws {@link WirestateError} If `entry.scopeBindingType` is not `Singleton` for constant values.
1551
+ *
1552
+ * @example
1553
+ * ```typescript
1554
+ * // Binding a class constructor (defaults to singleton)
1555
+ * class MyService {}
922
1556
  *
923
- * Supports:
924
- * - Service classes (function entries) - bound as singleton
925
- * - Constant values - bound via `bindConstant`
926
- * - Dynamic values - bound via `toDynamicValue` with optional scope
927
- * - Instance bindings - bound as generic singleton service
1557
+ * bindEntry(container, MyService);
928
1558
  *
929
- * @param container - target IOC container to bind into
930
- * @param entry - entry descriptor to bind
931
- * @param options - optional binding configuration
932
- * @returns void
1559
+ * // Binding a constant value
1560
+ * const API_URL: unique symbol = Symbol("API_URL");
1561
+ *
1562
+ * bindEntry(container, {
1563
+ * id: API_URL,
1564
+ * value: "https://api.example.com"
1565
+ * });
1566
+ *
1567
+ * // Binding a dynamic value (factory)
1568
+ * const CURRENT_TIME: unique symbol = Symbol("CURRENT_TIME");
1569
+ *
1570
+ * bindEntry(container, {
1571
+ * id: CURRENT_TIME,
1572
+ * bindingType: "DynamicValue",
1573
+ * factory: () => new Date()
1574
+ * });
1575
+ * ```
933
1576
  */
934
1577
  function bindEntry(container, entry, options) {
935
1578
  if (options === void 0) {
936
1579
  options = {};
937
1580
  }
938
1581
  if (typeof entry === "function") {
939
- return bindService(container, entry, options);
1582
+ bindService(container, entry, options);
1583
+ return;
940
1584
  }
941
1585
  if (!entry.bindingType || entry.bindingType === inversify.bindingTypeValues.ConstantValue) {
942
- return bindConstant(container, entry);
1586
+ bindConstant(container, entry);
1587
+ return;
943
1588
  }
944
1589
  if (entry.bindingType === inversify.bindingTypeValues.DynamicValue) {
945
- return bindDynamicValue(container, entry);
1590
+ bindDynamicValue(container, entry);
1591
+ return;
946
1592
  }
947
1593
  // Default: treat as class descriptor (Instance binding).
948
- return bindService(container, entry.value, options);
1594
+ bindService(container, entry.value, options);
949
1595
  }
950
1596
 
951
1597
  /**
952
- * Returns the container token for a service entry.
953
- * For plain service classes the class itself is the token;
954
- * for descriptors the `id` field is used.
1598
+ * Resolves the identifier for a given entry.
1599
+ *
1600
+ * @remarks
1601
+ * Handles both plain service classes and injectable descriptors:
1602
+ * - If `entry` is a class constructor, it is returned as the identifier.
1603
+ * - If `entry` is an {@link InjectableDescriptor}, its `id` field is returned.
1604
+ *
1605
+ * @group Bind
1606
+ *
1607
+ * @template T - Type of the injectable object.
1608
+ *
1609
+ * @param entry - Class constructor or descriptor to get the identifier for.
1610
+ * @returns Identifier token for Inversify.
955
1611
  *
956
- * @param entry - entry descriptor to get service identifier for
957
- * @returns injectable identifier token
1612
+ * @example
1613
+ * ```typescript
1614
+ * class MyService {}
1615
+ *
1616
+ * getEntryToken(MyService); // returns MyService
1617
+ *
1618
+ * getEntryToken({ id: "my-service" }); // returns "my-service"
1619
+ * ```
958
1620
  */
959
1621
  function getEntryToken(entry) {
960
1622
  return typeof entry === "function" ? entry : entry.id;
961
1623
  }
962
1624
 
963
1625
  /**
964
- * Creates an IoC container with framework essentials.
1626
+ * Applies targeted seeds to the container's internal seed map.
1627
+ *
1628
+ * @remarks
1629
+ * This function updates the existing {@link SeedsMap} instance instead of replacing it.
1630
+ * This ensures that multiple providers can co-exist and contribute their own seeds
1631
+ * without overwriting each other's data.
1632
+ *
1633
+ * @group Seeds
1634
+ *
1635
+ * @param container - The Inversify {@link Container} where seeds should be applied.
1636
+ * @param seeds - An array of {@link SeedEntries} to add to the container.
965
1637
  *
966
- * @param options - container configuration
967
- * @returns new IoC container
1638
+ * @example
1639
+ * ```typescript
1640
+ * applySeeds(container, [
1641
+ * [UserService, { initialUser: "admin" }],
1642
+ * ["API_KEY", "12345"]
1643
+ * ]);
1644
+ * ```
968
1645
  */
969
- function createIocContainer(options) {
970
- var _a;
971
- if (options === void 0) {
972
- options = {};
1646
+ function applySeeds(container, seeds) {
1647
+ var existing = container.get(SEEDS_TOKEN);
1648
+ for (var _i = 0, seeds_1 = seeds; _i < seeds_1.length; _i++) {
1649
+ var _a = seeds_1[_i],
1650
+ key = _a[0],
1651
+ state = _a[1];
1652
+ existing.set(key, state);
973
1653
  }
1654
+ }
1655
+
1656
+ /**
1657
+ * Creates the foundational {@link Container} used by Wirestate.
1658
+ *
1659
+ * @remarks
1660
+ * This helper configures the core container primitives shared by higher-level
1661
+ * container factories:
1662
+ * - sets the default scope to `Singleton`
1663
+ * - binds the core buses: {@link EventBus}, {@link QueryBus}, and {@link CommandBus}
1664
+ * - registers the seed map tokens: `SEEDS_TOKEN` and `SEED_TOKEN`
1665
+ * - applies any targeted seed entries passed in `options.seeds`
1666
+ *
1667
+ * @group Container
1668
+ * @internal
1669
+ *
1670
+ * @param options - Base container configuration.
1671
+ * @returns A configured {@link Container} instance.
1672
+ *
1673
+ * @example
1674
+ * ```typescript
1675
+ * const SOME_TOKEN: unique symbol = Symbol("SOME_TOKEN");
1676
+ *
1677
+ * const container: Container = createBaseContainer({
1678
+ * seed: { environment: "test" },
1679
+ * seeds: [
1680
+ * [SOME_TOKEN, { value: 123 }],
1681
+ * ],
1682
+ * });
1683
+ *
1684
+ * const rootSeed = container.get(SEED_TOKEN);
1685
+ * ```
1686
+ */
1687
+ function createBaseContainer(options) {
1688
+ var _a;
974
1689
  var container = new inversify.Container({
975
- defaultScope: "Singleton",
976
- parent: options.parent
1690
+ parent: options.parent,
1691
+ defaultScope: "Singleton"
977
1692
  });
978
1693
  container.bind(EventBus).toConstantValue(new EventBus());
979
1694
  container.bind(QueryBus).toConstantValue(new QueryBus());
980
1695
  container.bind(CommandBus).toConstantValue(new CommandBus());
981
1696
  container.bind(SEEDS_TOKEN).toConstantValue(new Map());
982
1697
  container.bind(SEED_TOKEN).toConstantValue((_a = options.seed) !== null && _a !== void 0 ? _a : {});
1698
+ if (options.seeds) {
1699
+ applySeeds(container, options.seeds);
1700
+ }
1701
+ return container;
1702
+ }
1703
+
1704
+ /**
1705
+ * Creates an Inversify IoC container pre-configured with Wirestate essentials.
1706
+ *
1707
+ * @remarks
1708
+ * The container is initialized with:
1709
+ * - State management tokens: `SEEDS_TOKEN` and `SEED_TOKEN`.
1710
+ * - Messaging buses: {@link EventBus}, {@link QueryBus}, {@link CommandBus}.
1711
+ * - Service bridge: {@link WireScope} (bound in transient scope).
1712
+ * - Default scope set to `Singleton`.
1713
+ *
1714
+ * @group Container
1715
+ *
1716
+ * @param options - {@link CreateContainerOptions} configuration.
1717
+ * @returns A new Inversify {@link Container} instance.
1718
+ *
1719
+ * @example
1720
+ * ```typescript
1721
+ * const container: Container = createContainer({
1722
+ * seeds: [
1723
+ * [CounterService, { count: 1000 }],
1724
+ * ["SOME_KEY", "VALUE"],
1725
+ * ],
1726
+ * entries: [CounterService, LoggerService],
1727
+ * activate: [LoggerService]
1728
+ * });
1729
+ *
1730
+ * bindService(container, MyService);
1731
+ * ```
1732
+ */
1733
+ function createContainer(options) {
1734
+ var _a;
1735
+ if (options === void 0) {
1736
+ options = {};
1737
+ }
1738
+ if (options.activate && options.activate.length) {
1739
+ if (!((_a = options.entries) === null || _a === void 0 ? void 0 : _a.length)) {
1740
+ throw new WirestateError(ERROR_CODE_VALIDATION_ERROR, "Supplied activation list while entries for binding are not provided.");
1741
+ }
1742
+ var entryTokens = options.entries.map(getEntryToken);
1743
+ for (var _i = 0, _b = options.activate; _i < _b.length; _i++) {
1744
+ var eager = _b[_i];
1745
+ if (!entryTokens.includes(eager)) {
1746
+ throw new WirestateError(ERROR_CODE_VALIDATION_ERROR, "createInjectablesProvider: '".concat(String(eager), "' is listed in 'activate' but was not provided in 'entries'."));
1747
+ }
1748
+ }
1749
+ }
1750
+ var container = new inversify.Container({
1751
+ defaultScope: "Singleton",
1752
+ parent: createBaseContainer(options)
1753
+ });
983
1754
  container.bind(WireScope).toResolvedValue(function () {
984
1755
  return new WireScope(container);
985
1756
  }).inTransientScope();
1757
+ if (options.entries) {
1758
+ for (var _c = 0, _d = options.entries; _c < _d.length; _c++) {
1759
+ var entry = _d[_c];
1760
+ bindEntry(container, entry);
1761
+ }
1762
+ }
1763
+ if (options.activate) {
1764
+ for (var _e = 0, _f = options.activate; _e < _f.length; _e++) {
1765
+ var entry = _f[_e];
1766
+ container.get(entry);
1767
+ }
1768
+ }
986
1769
  return container;
987
1770
  }
988
1771
 
@@ -999,9 +1782,11 @@ exports.SEEDS_TOKEN = SEEDS_TOKEN;
999
1782
  exports.SEED_TOKEN = SEED_TOKEN;
1000
1783
  exports.WireScope = WireScope;
1001
1784
  exports.WirestateError = WirestateError;
1785
+ exports.applySeeds = applySeeds;
1002
1786
  exports.bindConstant = bindConstant;
1787
+ exports.bindDynamicValue = bindDynamicValue;
1003
1788
  exports.bindEntry = bindEntry;
1004
1789
  exports.bindService = bindService;
1005
- exports.createIocContainer = createIocContainer;
1790
+ exports.createContainer = createContainer;
1006
1791
  exports.getEntryToken = getEntryToken;
1007
1792
  //# sourceMappingURL=lib.js.map