@adaas/a-utils 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -7
- package/dist/index.d.mts +429 -8
- package/dist/index.d.ts +429 -8
- package/dist/index.js +369 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +370 -40
- package/dist/index.mjs.map +1 -1
- package/examples/channel-examples.ts +518 -0
- package/package.json +1 -1
- package/src/lib/A-Channel/A-Channel.component.ts +516 -34
- package/src/lib/A-Channel/A-Channel.constants.ts +76 -0
- package/src/lib/A-Channel/A-Channel.error.ts +42 -1
- package/src/lib/A-Channel/A-Channel.types.ts +11 -0
- package/src/lib/A-Channel/A-ChannelRequest.context.ts +91 -0
- package/src/lib/A-Channel/README.md +864 -0
- package/src/lib/A-Command/A-Command.entity.ts +49 -8
- package/src/lib/A-Command/A-Command.error.ts +2 -0
- package/tests/A-Channel.test.ts +483 -5
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A_Feature, A_Inject, A_Scope, A_Concept, A_Container, A_Error, A_Component, A_Fragment, A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_CommonHelper, A_FormatterHelper, A_Context, A_Entity, A_ScopeError
|
|
1
|
+
import { A_Feature, A_Inject, A_Scope, A_Concept, A_Container, A_Error, A_TypeGuards, A_Component, A_Fragment, A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_CommonHelper, A_FormatterHelper, A_Context, A_IdentityHelper, A_Entity, A_ScopeError } from '@adaas/a-concept';
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -11,27 +11,149 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
11
11
|
return result;
|
|
12
12
|
};
|
|
13
13
|
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
14
|
+
var A_ChannelRequestContext = class extends A_Fragment {
|
|
15
|
+
constructor(params = {}) {
|
|
16
|
+
super();
|
|
17
|
+
this._errors = /* @__PURE__ */ new Set();
|
|
18
|
+
this._status = "PENDING" /* PENDING */;
|
|
19
|
+
this._params = params;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the status of the request
|
|
23
|
+
*/
|
|
24
|
+
get status() {
|
|
25
|
+
return this._status;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns the parameters of the request
|
|
29
|
+
*/
|
|
30
|
+
get failed() {
|
|
31
|
+
return this._errors.size > 0;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the Params of the Request
|
|
35
|
+
*/
|
|
36
|
+
get params() {
|
|
37
|
+
return this._params;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the Result of the Request
|
|
41
|
+
*/
|
|
42
|
+
get data() {
|
|
43
|
+
return this._result;
|
|
44
|
+
}
|
|
45
|
+
get errors() {
|
|
46
|
+
return this._errors.size > 0 ? this._errors : void 0;
|
|
47
|
+
}
|
|
48
|
+
// ==========================================================
|
|
49
|
+
// ==================== Mutations ===========================
|
|
50
|
+
// ==========================================================
|
|
51
|
+
/**
|
|
52
|
+
* Adds an error to the context
|
|
53
|
+
*
|
|
54
|
+
* @param error
|
|
55
|
+
*/
|
|
56
|
+
fail(error) {
|
|
57
|
+
this._status = "FAILED" /* FAILED */;
|
|
58
|
+
this._errors.add(error);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Sets the result of the request
|
|
62
|
+
*
|
|
63
|
+
* @param result
|
|
64
|
+
*/
|
|
65
|
+
succeed(result) {
|
|
66
|
+
this._status = "SUCCESS" /* SUCCESS */;
|
|
67
|
+
this._result = result;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Serializes the context to a JSON object
|
|
71
|
+
*
|
|
72
|
+
* @returns
|
|
73
|
+
*/
|
|
74
|
+
toJSON() {
|
|
75
|
+
return {
|
|
76
|
+
params: this._params,
|
|
77
|
+
result: this._result,
|
|
78
|
+
status: this._status,
|
|
79
|
+
errors: this.errors ? Array.from(this._errors).map((err) => err.toString()) : void 0
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// src/lib/A-Channel/A-Channel.error.ts
|
|
14
85
|
var A_ChannelError = class extends A_Error {
|
|
86
|
+
/**
|
|
87
|
+
* Channel Error allows to keep track of errors within a channel if something goes wrong
|
|
88
|
+
*
|
|
89
|
+
*
|
|
90
|
+
* @param originalError
|
|
91
|
+
* @param context
|
|
92
|
+
*/
|
|
93
|
+
constructor(originalError, context) {
|
|
94
|
+
if (A_TypeGuards.isString(context))
|
|
95
|
+
super(originalError, context);
|
|
96
|
+
else
|
|
97
|
+
super(originalError);
|
|
98
|
+
if (context instanceof A_ChannelRequestContext)
|
|
99
|
+
this._context = context;
|
|
100
|
+
}
|
|
101
|
+
/***
|
|
102
|
+
* Returns Context of the error
|
|
103
|
+
*/
|
|
104
|
+
get context() {
|
|
105
|
+
return this._context;
|
|
106
|
+
}
|
|
15
107
|
};
|
|
108
|
+
// ==========================================================
|
|
109
|
+
// ==================== Error Types =========================
|
|
110
|
+
// ==========================================================
|
|
16
111
|
A_ChannelError.MethodNotImplemented = "A-Channel Method Not Implemented";
|
|
17
112
|
|
|
18
113
|
// src/lib/A-Channel/A-Channel.component.ts
|
|
19
114
|
var A_Channel = class extends A_Component {
|
|
115
|
+
/**
|
|
116
|
+
* Creates a new A_Channel instance.
|
|
117
|
+
*
|
|
118
|
+
* The channel must be registered with A_Context before use:
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const channel = new A_Channel();
|
|
121
|
+
* A_Context.root.register(channel);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
20
124
|
constructor() {
|
|
21
|
-
super(
|
|
125
|
+
super();
|
|
22
126
|
/**
|
|
23
|
-
* Indicates whether the channel is processing requests
|
|
127
|
+
* Indicates whether the channel is currently processing requests.
|
|
128
|
+
* This flag is managed automatically during request/send operations.
|
|
129
|
+
*
|
|
130
|
+
* @readonly
|
|
24
131
|
*/
|
|
25
132
|
this._processing = false;
|
|
133
|
+
/**
|
|
134
|
+
* Internal cache storage for channel-specific data.
|
|
135
|
+
* Can be used by custom implementations for caching responses,
|
|
136
|
+
* connection pools, or other channel-specific state.
|
|
137
|
+
*
|
|
138
|
+
* @protected
|
|
139
|
+
*/
|
|
140
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
26
141
|
}
|
|
27
142
|
/**
|
|
28
|
-
|
|
29
|
-
|
|
143
|
+
* Indicates whether the channel is currently processing requests.
|
|
144
|
+
*
|
|
145
|
+
* @returns {boolean} True if channel is processing, false otherwise
|
|
146
|
+
*/
|
|
30
147
|
get processing() {
|
|
31
148
|
return this._processing;
|
|
32
149
|
}
|
|
33
150
|
/**
|
|
34
|
-
*
|
|
151
|
+
* Promise that resolves when the channel is fully initialized.
|
|
152
|
+
*
|
|
153
|
+
* Automatically calls the onConnect lifecycle hook if not already called.
|
|
154
|
+
* This ensures the channel is ready for communication operations.
|
|
155
|
+
*
|
|
156
|
+
* @returns {Promise<void>} Promise that resolves when initialization is complete
|
|
35
157
|
*/
|
|
36
158
|
get initialize() {
|
|
37
159
|
if (!this._initialized) {
|
|
@@ -39,48 +161,228 @@ var A_Channel = class extends A_Component {
|
|
|
39
161
|
}
|
|
40
162
|
return this._initialized;
|
|
41
163
|
}
|
|
164
|
+
async onConnect(...args) {
|
|
165
|
+
}
|
|
166
|
+
async onDisconnect(...args) {
|
|
167
|
+
}
|
|
168
|
+
async onBeforeRequest(...args) {
|
|
169
|
+
}
|
|
170
|
+
async onRequest(...args) {
|
|
171
|
+
}
|
|
172
|
+
async onAfterRequest(...args) {
|
|
173
|
+
}
|
|
174
|
+
async onError(...args) {
|
|
175
|
+
}
|
|
176
|
+
async onSend(...args) {
|
|
177
|
+
}
|
|
178
|
+
// ==========================================================
|
|
179
|
+
// ================= Public API Methods ===================
|
|
180
|
+
// ==========================================================
|
|
42
181
|
/**
|
|
43
|
-
* Initializes the channel
|
|
182
|
+
* Initializes the channel by calling the onConnect lifecycle hook.
|
|
183
|
+
*
|
|
184
|
+
* This method is called automatically when accessing the `initialize` property.
|
|
185
|
+
* You can also call it manually if needed.
|
|
186
|
+
*
|
|
187
|
+
* @returns {Promise<void>} Promise that resolves when connection is established
|
|
44
188
|
*/
|
|
45
189
|
async connect() {
|
|
46
|
-
|
|
47
|
-
A_ChannelError.MethodNotImplemented,
|
|
48
|
-
`The connect method is not implemented in ${this.constructor.name} channel. This method is required to initialize the channel before use. So please implement it in the derived class.`
|
|
49
|
-
);
|
|
190
|
+
await this.call("onConnect" /* onConnect */);
|
|
50
191
|
}
|
|
51
192
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
193
|
+
* Disconnects the channel by calling the onDisconnect lifecycle hook.
|
|
194
|
+
*
|
|
195
|
+
* Use this method to properly cleanup resources when the channel is no longer needed.
|
|
196
|
+
*
|
|
197
|
+
* @returns {Promise<void>} Promise that resolves when cleanup is complete
|
|
198
|
+
*/
|
|
199
|
+
async disconnect() {
|
|
200
|
+
await this.call("onDisconnect" /* onDisconnect */);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Sends a request and waits for a response (Request/Response pattern).
|
|
204
|
+
*
|
|
205
|
+
* This method follows the complete request lifecycle:
|
|
206
|
+
* 1. Ensures channel is initialized
|
|
207
|
+
* 2. Creates request scope and context
|
|
208
|
+
* 3. Calls onBeforeRequest hook
|
|
209
|
+
* 4. Calls onRequest hook (main processing)
|
|
210
|
+
* 5. Calls onAfterRequest hook
|
|
211
|
+
* 6. Returns the response context
|
|
212
|
+
*
|
|
213
|
+
* If any step fails, the onError hook is called and the error is captured
|
|
214
|
+
* in the returned context.
|
|
215
|
+
*
|
|
216
|
+
* @template _ParamsType The type of request parameters
|
|
217
|
+
* @template _ResultType The type of response data
|
|
218
|
+
* @param params The request parameters
|
|
219
|
+
* @returns {Promise<A_ChannelRequestContext<_ParamsType, _ResultType>>} Request context with response
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* // Basic usage
|
|
224
|
+
* const response = await channel.request({ action: 'getData', id: 123 });
|
|
225
|
+
*
|
|
226
|
+
* // Typed usage
|
|
227
|
+
* interface UserRequest { userId: string; }
|
|
228
|
+
* interface UserResponse { name: string; email: string; }
|
|
229
|
+
*
|
|
230
|
+
* const userResponse = await channel.request<UserRequest, UserResponse>({
|
|
231
|
+
* userId: 'user-123'
|
|
232
|
+
* });
|
|
233
|
+
*
|
|
234
|
+
* if (!userResponse.failed) {
|
|
235
|
+
* console.log('User:', userResponse.data.name);
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
56
238
|
*/
|
|
57
239
|
async request(params) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
240
|
+
await this.initialize;
|
|
241
|
+
this._processing = true;
|
|
242
|
+
const requestScope = new A_Scope({
|
|
243
|
+
name: `a-channel@scope:request:${A_IdentityHelper.generateTimeId()}`
|
|
244
|
+
});
|
|
245
|
+
const context = new A_ChannelRequestContext(params);
|
|
246
|
+
try {
|
|
247
|
+
requestScope.inherit(A_Context.scope(this));
|
|
248
|
+
requestScope.register(context);
|
|
249
|
+
await this.call("onBeforeRequest" /* onBeforeRequest */, requestScope);
|
|
250
|
+
await this.call("onRequest" /* onRequest */, requestScope);
|
|
251
|
+
await this.call("onAfterRequest" /* onAfterRequest */, requestScope);
|
|
252
|
+
this._processing = false;
|
|
253
|
+
return context;
|
|
254
|
+
} catch (error) {
|
|
255
|
+
this._processing = false;
|
|
256
|
+
const channelError = new A_ChannelError(error);
|
|
257
|
+
context.fail(channelError);
|
|
258
|
+
await this.call("onError" /* onError */, requestScope);
|
|
259
|
+
return context;
|
|
260
|
+
}
|
|
62
261
|
}
|
|
63
262
|
/**
|
|
64
|
-
*
|
|
263
|
+
* Sends a fire-and-forget message (Send pattern).
|
|
264
|
+
*
|
|
265
|
+
* This method is used for one-way communication where no response is expected:
|
|
266
|
+
* - Event broadcasting
|
|
267
|
+
* - Notification sending
|
|
268
|
+
* - Message queuing
|
|
269
|
+
* - Logging operations
|
|
270
|
+
*
|
|
271
|
+
* The method follows this lifecycle:
|
|
272
|
+
* 1. Ensures channel is initialized
|
|
273
|
+
* 2. Creates send scope and context
|
|
274
|
+
* 3. Calls onSend hook
|
|
275
|
+
* 4. Completes without returning data
|
|
65
276
|
*
|
|
66
|
-
*
|
|
277
|
+
* If the operation fails, the onError hook is called but no error is thrown
|
|
278
|
+
* to the caller (fire-and-forget semantics).
|
|
279
|
+
*
|
|
280
|
+
* @template _ParamsType The type of message parameters
|
|
281
|
+
* @param message The message to send
|
|
282
|
+
* @returns {Promise<void>} Promise that resolves when send is complete
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* // Send notification
|
|
287
|
+
* await channel.send({
|
|
288
|
+
* type: 'user.login',
|
|
289
|
+
* userId: 'user-123',
|
|
290
|
+
* timestamp: new Date().toISOString()
|
|
291
|
+
* });
|
|
292
|
+
*
|
|
293
|
+
* // Send to message queue
|
|
294
|
+
* await channel.send({
|
|
295
|
+
* queue: 'email-queue',
|
|
296
|
+
* payload: {
|
|
297
|
+
* to: 'user@example.com',
|
|
298
|
+
* subject: 'Welcome!',
|
|
299
|
+
* body: 'Welcome to our service!'
|
|
300
|
+
* }
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
67
303
|
*/
|
|
68
304
|
async send(message) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
305
|
+
await this.initialize;
|
|
306
|
+
this._processing = true;
|
|
307
|
+
const requestScope = new A_Scope({
|
|
308
|
+
name: `a-channel@scope:send:${A_IdentityHelper.generateTimeId()}`
|
|
309
|
+
});
|
|
310
|
+
const context = new A_ChannelRequestContext(message);
|
|
311
|
+
try {
|
|
312
|
+
requestScope.inherit(A_Context.scope(this));
|
|
313
|
+
requestScope.register(context);
|
|
314
|
+
await this.call("onSend" /* onSend */, requestScope);
|
|
315
|
+
this._processing = false;
|
|
316
|
+
} catch (error) {
|
|
317
|
+
this._processing = false;
|
|
318
|
+
const channelError = new A_ChannelError(error);
|
|
319
|
+
context.fail(channelError);
|
|
320
|
+
await this.call("onError" /* onError */, requestScope);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* @deprecated This method is deprecated and will be removed in future versions.
|
|
325
|
+
* Use request() or send() methods instead depending on your communication pattern.
|
|
326
|
+
*
|
|
327
|
+
* For request/response pattern: Use request()
|
|
328
|
+
* For fire-and-forget pattern: Use send()
|
|
329
|
+
* For consumer patterns: Implement custom consumer logic using request() in a loop
|
|
330
|
+
*/
|
|
331
|
+
async consume() {
|
|
332
|
+
await this.initialize;
|
|
333
|
+
this._processing = true;
|
|
334
|
+
const requestScope = new A_Scope({ name: `a-channel@scope:consume:${A_IdentityHelper.generateTimeId()}` });
|
|
335
|
+
const context = new A_ChannelRequestContext();
|
|
336
|
+
try {
|
|
337
|
+
requestScope.inherit(A_Context.scope(this));
|
|
338
|
+
requestScope.register(context);
|
|
339
|
+
await this.call("onConsume" /* onConsume */, requestScope);
|
|
340
|
+
this._processing = false;
|
|
341
|
+
return context;
|
|
342
|
+
} catch (error) {
|
|
343
|
+
this._processing = false;
|
|
344
|
+
const channelError = new A_ChannelError(error);
|
|
345
|
+
context.fail(channelError);
|
|
346
|
+
await this.call("onError" /* onError */, requestScope);
|
|
347
|
+
return context;
|
|
348
|
+
}
|
|
73
349
|
}
|
|
74
350
|
};
|
|
75
351
|
__decorateClass([
|
|
76
|
-
A_Feature.
|
|
77
|
-
|
|
352
|
+
A_Feature.Extend({
|
|
353
|
+
name: "onConnect" /* onConnect */
|
|
354
|
+
})
|
|
355
|
+
], A_Channel.prototype, "onConnect", 1);
|
|
356
|
+
__decorateClass([
|
|
357
|
+
A_Feature.Extend({
|
|
358
|
+
name: "onDisconnect" /* onDisconnect */
|
|
359
|
+
})
|
|
360
|
+
], A_Channel.prototype, "onDisconnect", 1);
|
|
361
|
+
__decorateClass([
|
|
362
|
+
A_Feature.Extend({
|
|
363
|
+
name: "onBeforeRequest" /* onBeforeRequest */
|
|
364
|
+
})
|
|
365
|
+
], A_Channel.prototype, "onBeforeRequest", 1);
|
|
78
366
|
__decorateClass([
|
|
79
|
-
A_Feature.
|
|
80
|
-
|
|
367
|
+
A_Feature.Extend({
|
|
368
|
+
name: "onRequest" /* onRequest */
|
|
369
|
+
})
|
|
370
|
+
], A_Channel.prototype, "onRequest", 1);
|
|
81
371
|
__decorateClass([
|
|
82
|
-
A_Feature.
|
|
83
|
-
|
|
372
|
+
A_Feature.Extend({
|
|
373
|
+
name: "onAfterRequest" /* onAfterRequest */
|
|
374
|
+
})
|
|
375
|
+
], A_Channel.prototype, "onAfterRequest", 1);
|
|
376
|
+
__decorateClass([
|
|
377
|
+
A_Feature.Extend({
|
|
378
|
+
name: "onError" /* onError */
|
|
379
|
+
})
|
|
380
|
+
], A_Channel.prototype, "onError", 1);
|
|
381
|
+
__decorateClass([
|
|
382
|
+
A_Feature.Extend({
|
|
383
|
+
name: "onSend" /* onSend */
|
|
384
|
+
})
|
|
385
|
+
], A_Channel.prototype, "onSend", 1);
|
|
84
386
|
|
|
85
387
|
// src/lib/A-Command/A-Command.constants.ts
|
|
86
388
|
var A_TYPES__CommandMetaKey = /* @__PURE__ */ ((A_TYPES__CommandMetaKey2) => {
|
|
@@ -186,6 +488,9 @@ var A_Memory = class extends A_Fragment {
|
|
|
186
488
|
return obj;
|
|
187
489
|
}
|
|
188
490
|
};
|
|
491
|
+
var A_CommandError = class extends A_Error {
|
|
492
|
+
};
|
|
493
|
+
A_CommandError.CommandScopeBindingError = "A-Command Scope Binding Error";
|
|
189
494
|
|
|
190
495
|
// src/lib/A-Command/A-Command.entity.ts
|
|
191
496
|
var A_Command = class extends A_Entity {
|
|
@@ -291,9 +596,7 @@ var A_Command = class extends A_Entity {
|
|
|
291
596
|
}
|
|
292
597
|
this._status = "INITIALIZATION" /* INITIALIZATION */;
|
|
293
598
|
this._startTime = /* @__PURE__ */ new Date();
|
|
294
|
-
|
|
295
|
-
this.scope.inherit(A_Context.scope(this));
|
|
296
|
-
}
|
|
599
|
+
this.checkScopeInheritance();
|
|
297
600
|
this.emit("init");
|
|
298
601
|
await this.call("init", this.scope);
|
|
299
602
|
this._status = "INITIALIZED" /* INITIALIZED */;
|
|
@@ -303,22 +606,34 @@ var A_Command = class extends A_Entity {
|
|
|
303
606
|
if (this._status !== "INITIALIZED" /* INITIALIZED */) {
|
|
304
607
|
return;
|
|
305
608
|
}
|
|
609
|
+
this.checkScopeInheritance();
|
|
306
610
|
this._status = "COMPILATION" /* COMPILATION */;
|
|
307
611
|
this.emit("compile");
|
|
308
612
|
await this.call("compile", this.scope);
|
|
309
613
|
this._status = "COMPILED" /* COMPILED */;
|
|
310
614
|
}
|
|
615
|
+
/**
|
|
616
|
+
* Processes the command execution
|
|
617
|
+
*
|
|
618
|
+
* @returns
|
|
619
|
+
*/
|
|
620
|
+
async process() {
|
|
621
|
+
if (this._status !== "COMPILED" /* COMPILED */)
|
|
622
|
+
return;
|
|
623
|
+
this._status = "IN_PROGRESS" /* IN_PROGRESS */;
|
|
624
|
+
this.checkScopeInheritance();
|
|
625
|
+
this.emit("execute");
|
|
626
|
+
await this.call("execute", this.scope);
|
|
627
|
+
}
|
|
311
628
|
/**
|
|
312
629
|
* Executes the command logic.
|
|
313
630
|
*/
|
|
314
631
|
async execute() {
|
|
632
|
+
this.checkScopeInheritance();
|
|
315
633
|
try {
|
|
316
634
|
await this.init();
|
|
317
635
|
await this.compile();
|
|
318
|
-
|
|
319
|
-
this.emit("execute");
|
|
320
|
-
await this.call("execute", this.scope);
|
|
321
|
-
}
|
|
636
|
+
await this.process();
|
|
322
637
|
await this.complete();
|
|
323
638
|
} catch (error) {
|
|
324
639
|
await this.fail();
|
|
@@ -328,6 +643,7 @@ var A_Command = class extends A_Entity {
|
|
|
328
643
|
* Marks the command as completed
|
|
329
644
|
*/
|
|
330
645
|
async complete() {
|
|
646
|
+
this.checkScopeInheritance();
|
|
331
647
|
this._status = "COMPLETED" /* COMPLETED */;
|
|
332
648
|
this._endTime = /* @__PURE__ */ new Date();
|
|
333
649
|
this._result = this.scope.resolve(A_Memory).toJSON();
|
|
@@ -338,6 +654,7 @@ var A_Command = class extends A_Entity {
|
|
|
338
654
|
* Marks the command as failed
|
|
339
655
|
*/
|
|
340
656
|
async fail() {
|
|
657
|
+
this.checkScopeInheritance();
|
|
341
658
|
this._status = "FAILED" /* FAILED */;
|
|
342
659
|
this._endTime = /* @__PURE__ */ new Date();
|
|
343
660
|
this._errors = this.scope.resolve(A_Memory).Errors;
|
|
@@ -440,8 +757,21 @@ var A_Command = class extends A_Entity {
|
|
|
440
757
|
errors: this.errors ? Array.from(this.errors).map((err) => err.toJSON()) : void 0
|
|
441
758
|
};
|
|
442
759
|
}
|
|
443
|
-
|
|
444
|
-
|
|
760
|
+
checkScopeInheritance() {
|
|
761
|
+
let attachedScope;
|
|
762
|
+
try {
|
|
763
|
+
attachedScope = A_Context.scope(this);
|
|
764
|
+
} catch (error) {
|
|
765
|
+
throw new A_CommandError({
|
|
766
|
+
title: A_CommandError.CommandScopeBindingError,
|
|
767
|
+
description: `Command ${this.code} is not bound to any context scope. Ensure the command is properly registered within a context before execution.`,
|
|
768
|
+
originalError: error
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
if (!this.scope.isInheritedFrom(A_Context.scope(this))) {
|
|
772
|
+
this.scope.inherit(A_Context.scope(this));
|
|
773
|
+
}
|
|
774
|
+
}
|
|
445
775
|
};
|
|
446
776
|
|
|
447
777
|
// src/lib/A-Config/A-Config.constants.ts
|