@adaas/a-utils 0.1.19 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js DELETED
@@ -1,3110 +0,0 @@
1
- 'use strict';
2
-
3
- var aConcept = require('@adaas/a-concept');
4
-
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __decorateClass = (decorators, target, key, kind) => {
8
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
9
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
10
- if (decorator = decorators[i])
11
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
12
- if (kind && result) __defProp(target, key, result);
13
- return result;
14
- };
15
- var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
16
- var A_OperationContext = class extends aConcept.A_Fragment {
17
- constructor(operation, params) {
18
- super();
19
- this.meta.set("name", operation);
20
- this.meta.set("params", params || {});
21
- }
22
- get name() {
23
- return this._meta.get("name") || this._name;
24
- }
25
- get result() {
26
- return this._meta.get("result");
27
- }
28
- get error() {
29
- return this._meta.get("error");
30
- }
31
- get params() {
32
- return this._meta.get("params") || {};
33
- }
34
- fail(error) {
35
- this._meta.set("error", error);
36
- }
37
- succeed(result) {
38
- this._meta.set("result", result);
39
- }
40
- toJSON() {
41
- return {
42
- name: this.name,
43
- params: this.params,
44
- result: this.result || {},
45
- error: this.error?.toJSON()
46
- };
47
- }
48
- };
49
-
50
- // src/lib/A-Channel/A-Channel.error.ts
51
- var A_ChannelError = class extends aConcept.A_Error {
52
- /**
53
- * Channel Error allows to keep track of errors within a channel if something goes wrong
54
- *
55
- *
56
- * @param originalError
57
- * @param context
58
- */
59
- constructor(originalError, context) {
60
- if (aConcept.A_TypeGuards.isString(context))
61
- super(originalError, context);
62
- else
63
- super(originalError);
64
- if (context instanceof A_OperationContext)
65
- this._context = context;
66
- }
67
- /***
68
- * Returns Context of the error
69
- */
70
- get context() {
71
- return this._context;
72
- }
73
- };
74
- // ==========================================================
75
- // ==================== Error Types =========================
76
- // ==========================================================
77
- A_ChannelError.MethodNotImplemented = "A-Channel Method Not Implemented";
78
-
79
- // src/lib/A-Channel/A-Channel.constants.ts
80
- var A_ChannelFeatures = /* @__PURE__ */ ((A_ChannelFeatures2) => {
81
- A_ChannelFeatures2["onTimeout"] = "onTimeout";
82
- A_ChannelFeatures2["onRetry"] = "onRetry";
83
- A_ChannelFeatures2["onCircuitBreakerOpen"] = "onCircuitBreakerOpen";
84
- A_ChannelFeatures2["onCache"] = "onCache";
85
- A_ChannelFeatures2["onConnect"] = "onConnect";
86
- A_ChannelFeatures2["onDisconnect"] = "onDisconnect";
87
- A_ChannelFeatures2["onBeforeRequest"] = "onBeforeRequest";
88
- A_ChannelFeatures2["onRequest"] = "onRequest";
89
- A_ChannelFeatures2["onAfterRequest"] = "onAfterRequest";
90
- A_ChannelFeatures2["onError"] = "onError";
91
- A_ChannelFeatures2["onSend"] = "onSend";
92
- A_ChannelFeatures2["onConsume"] = "onConsume";
93
- return A_ChannelFeatures2;
94
- })(A_ChannelFeatures || {});
95
- var A_ChannelRequestStatuses = /* @__PURE__ */ ((A_ChannelRequestStatuses2) => {
96
- A_ChannelRequestStatuses2["PENDING"] = "PENDING";
97
- A_ChannelRequestStatuses2["SUCCESS"] = "SUCCESS";
98
- A_ChannelRequestStatuses2["FAILED"] = "FAILED";
99
- return A_ChannelRequestStatuses2;
100
- })(A_ChannelRequestStatuses || {});
101
-
102
- // src/lib/A-Channel/A-ChannelRequest.context.ts
103
- var A_ChannelRequest = class extends A_OperationContext {
104
- constructor(params) {
105
- super("request", params);
106
- }
107
- get status() {
108
- return this.result?.status;
109
- }
110
- get data() {
111
- return this.result?.data;
112
- }
113
- succeed(result) {
114
- const existed = this.result;
115
- super.succeed({
116
- ...existed,
117
- data: result,
118
- status: "SUCCESS" /* SUCCESS */
119
- });
120
- }
121
- };
122
-
123
- // src/lib/A-Channel/A-Channel.component.ts
124
- var A_Channel = class extends aConcept.A_Component {
125
- /**
126
- * Creates a new A_Channel instance.
127
- *
128
- * The channel must be registered with A_Context before use:
129
- * ```typescript
130
- * const channel = new A_Channel();
131
- * A_Context.root.register(channel);
132
- * ```
133
- */
134
- constructor() {
135
- super();
136
- /**
137
- * Indicates whether the channel is currently processing requests.
138
- * This flag is managed automatically during request/send operations.
139
- *
140
- * @readonly
141
- */
142
- this._processing = false;
143
- /**
144
- * Internal cache storage for channel-specific data.
145
- * Can be used by custom implementations for caching responses,
146
- * connection pools, or other channel-specific state.
147
- *
148
- * @protected
149
- */
150
- this._cache = /* @__PURE__ */ new Map();
151
- }
152
- /**
153
- * Indicates whether the channel is currently processing requests.
154
- *
155
- * @returns {boolean} True if channel is processing, false otherwise
156
- */
157
- get processing() {
158
- return this._processing;
159
- }
160
- /**
161
- * Promise that resolves when the channel is fully initialized.
162
- *
163
- * Automatically calls the onConnect lifecycle hook if not already called.
164
- * This ensures the channel is ready for communication operations.
165
- *
166
- * @returns {Promise<void>} Promise that resolves when initialization is complete
167
- */
168
- get initialize() {
169
- if (!this._initialized) {
170
- this._initialized = this.connect();
171
- }
172
- return this._initialized;
173
- }
174
- async onConnect(...args) {
175
- }
176
- async onDisconnect(...args) {
177
- }
178
- async onBeforeRequest(...args) {
179
- }
180
- async onRequest(...args) {
181
- }
182
- async onAfterRequest(...args) {
183
- }
184
- async onError(...args) {
185
- }
186
- async onSend(...args) {
187
- }
188
- // ==========================================================
189
- // ================= Public API Methods ===================
190
- // ==========================================================
191
- /**
192
- * Initializes the channel by calling the onConnect lifecycle hook.
193
- *
194
- * This method is called automatically when accessing the `initialize` property.
195
- * You can also call it manually if needed.
196
- *
197
- * @returns {Promise<void>} Promise that resolves when connection is established
198
- */
199
- async connect() {
200
- await this.call("onConnect" /* onConnect */);
201
- }
202
- /**
203
- * Disconnects the channel by calling the onDisconnect lifecycle hook.
204
- *
205
- * Use this method to properly cleanup resources when the channel is no longer needed.
206
- *
207
- * @returns {Promise<void>} Promise that resolves when cleanup is complete
208
- */
209
- async disconnect() {
210
- await this.call("onDisconnect" /* onDisconnect */);
211
- }
212
- /**
213
- * Sends a request and waits for a response (Request/Response pattern).
214
- *
215
- * This method follows the complete request lifecycle:
216
- * 1. Ensures channel is initialized
217
- * 2. Creates request scope and context
218
- * 3. Calls onBeforeRequest hook
219
- * 4. Calls onRequest hook (main processing)
220
- * 5. Calls onAfterRequest hook
221
- * 6. Returns the response context
222
- *
223
- * If any step fails, the onError hook is called and the error is captured
224
- * in the returned context.
225
- *
226
- * @template _ParamsType The type of request parameters
227
- * @template _ResultType The type of response data
228
- * @param params The request parameters
229
- * @returns {Promise<A_ChannelRequest<_ParamsType, _ResultType>>} Request context with response
230
- *
231
- * @example
232
- * ```typescript
233
- * // Basic usage
234
- * const response = await channel.request({ action: 'getData', id: 123 });
235
- *
236
- * // Typed usage
237
- * interface UserRequest { userId: string; }
238
- * interface UserResponse { name: string; email: string; }
239
- *
240
- * const userResponse = await channel.request<UserRequest, UserResponse>({
241
- * userId: 'user-123'
242
- * });
243
- *
244
- * if (!userResponse.failed) {
245
- * console.log('User:', userResponse.data.name);
246
- * }
247
- * ```
248
- */
249
- async request(params) {
250
- await this.initialize;
251
- this._processing = true;
252
- const requestScope = new aConcept.A_Scope({
253
- name: `a-channel@scope:request:${aConcept.A_IdentityHelper.generateTimeId()}`
254
- });
255
- const context = new A_ChannelRequest(params);
256
- try {
257
- requestScope.register(context);
258
- await this.call("onBeforeRequest" /* onBeforeRequest */, requestScope);
259
- await this.call("onRequest" /* onRequest */, requestScope);
260
- await this.call("onAfterRequest" /* onAfterRequest */, requestScope);
261
- this._processing = false;
262
- return context;
263
- } catch (error) {
264
- this._processing = false;
265
- const channelError = new A_ChannelError(error);
266
- context.fail(channelError);
267
- requestScope.register(channelError);
268
- await this.call("onError" /* onError */, requestScope);
269
- requestScope.destroy();
270
- throw channelError;
271
- }
272
- }
273
- /**
274
- * Sends a fire-and-forget message (Send pattern).
275
- *
276
- * This method is used for one-way communication where no response is expected:
277
- * - Event broadcasting
278
- * - Notification sending
279
- * - Message queuing
280
- * - Logging operations
281
- *
282
- * The method follows this lifecycle:
283
- * 1. Ensures channel is initialized
284
- * 2. Creates send scope and context
285
- * 3. Calls onSend hook
286
- * 4. Completes without returning data
287
- *
288
- * If the operation fails, the onError hook is called but no error is thrown
289
- * to the caller (fire-and-forget semantics).
290
- *
291
- * @template _ParamsType The type of message parameters
292
- * @param message The message to send
293
- * @returns {Promise<void>} Promise that resolves when send is complete
294
- *
295
- * @example
296
- * ```typescript
297
- * // Send notification
298
- * await channel.send({
299
- * type: 'user.login',
300
- * userId: 'user-123',
301
- * timestamp: new Date().toISOString()
302
- * });
303
- *
304
- * // Send to message queue
305
- * await channel.send({
306
- * queue: 'email-queue',
307
- * payload: {
308
- * to: 'user@example.com',
309
- * subject: 'Welcome!',
310
- * body: 'Welcome to our service!'
311
- * }
312
- * });
313
- * ```
314
- */
315
- async send(message) {
316
- await this.initialize;
317
- this._processing = true;
318
- const requestScope = new aConcept.A_Scope({
319
- name: `a-channel@scope:send:${aConcept.A_IdentityHelper.generateTimeId()}`
320
- });
321
- const context = new A_OperationContext("send", message);
322
- try {
323
- requestScope.inherit(aConcept.A_Context.scope(this));
324
- requestScope.register(context);
325
- await this.call("onSend" /* onSend */, requestScope);
326
- this._processing = false;
327
- } catch (error) {
328
- this._processing = false;
329
- const channelError = new A_ChannelError(error);
330
- requestScope.register(channelError);
331
- context.fail(channelError);
332
- await this.call("onError" /* onError */, requestScope);
333
- requestScope.destroy();
334
- }
335
- }
336
- /**
337
- * @deprecated This method is deprecated and will be removed in future versions.
338
- * Use request() or send() methods instead depending on your communication pattern.
339
- *
340
- * For request/response pattern: Use request()
341
- * For fire-and-forget pattern: Use send()
342
- * For consumer patterns: Implement custom consumer logic using request() in a loop
343
- */
344
- async consume() {
345
- await this.initialize;
346
- this._processing = true;
347
- const requestScope = new aConcept.A_Scope({ name: `a-channel@scope:consume:${aConcept.A_IdentityHelper.generateTimeId()}` });
348
- const context = new A_OperationContext("consume", {});
349
- try {
350
- requestScope.inherit(aConcept.A_Context.scope(this));
351
- requestScope.register(context);
352
- await this.call("onConsume" /* onConsume */, requestScope);
353
- this._processing = false;
354
- return context;
355
- } catch (error) {
356
- this._processing = false;
357
- const channelError = new A_ChannelError(error);
358
- context.fail(channelError);
359
- await this.call("onError" /* onError */, requestScope);
360
- return context;
361
- }
362
- }
363
- };
364
- __decorateClass([
365
- aConcept.A_Feature.Extend({
366
- name: "onConnect" /* onConnect */
367
- })
368
- ], A_Channel.prototype, "onConnect", 1);
369
- __decorateClass([
370
- aConcept.A_Feature.Extend({
371
- name: "onDisconnect" /* onDisconnect */
372
- })
373
- ], A_Channel.prototype, "onDisconnect", 1);
374
- __decorateClass([
375
- aConcept.A_Feature.Extend({
376
- name: "onBeforeRequest" /* onBeforeRequest */
377
- })
378
- ], A_Channel.prototype, "onBeforeRequest", 1);
379
- __decorateClass([
380
- aConcept.A_Feature.Extend({
381
- name: "onRequest" /* onRequest */
382
- })
383
- ], A_Channel.prototype, "onRequest", 1);
384
- __decorateClass([
385
- aConcept.A_Feature.Extend({
386
- name: "onAfterRequest" /* onAfterRequest */
387
- })
388
- ], A_Channel.prototype, "onAfterRequest", 1);
389
- __decorateClass([
390
- aConcept.A_Feature.Extend({
391
- name: "onError" /* onError */
392
- })
393
- ], A_Channel.prototype, "onError", 1);
394
- __decorateClass([
395
- aConcept.A_Feature.Extend({
396
- name: "onSend" /* onSend */
397
- })
398
- ], A_Channel.prototype, "onSend", 1);
399
-
400
- // src/lib/A-Command/A-Command.constants.ts
401
- var A_Command_Status = /* @__PURE__ */ ((A_Command_Status2) => {
402
- A_Command_Status2["CREATED"] = "CREATED";
403
- A_Command_Status2["INITIALIZED"] = "INITIALIZED";
404
- A_Command_Status2["COMPILED"] = "COMPILED";
405
- A_Command_Status2["EXECUTING"] = "EXECUTING";
406
- A_Command_Status2["COMPLETED"] = "COMPLETED";
407
- A_Command_Status2["FAILED"] = "FAILED";
408
- return A_Command_Status2;
409
- })(A_Command_Status || {});
410
- var A_CommandTransitions = /* @__PURE__ */ ((A_CommandTransitions2) => {
411
- A_CommandTransitions2["CREATED_TO_INITIALIZED"] = "created_initialized";
412
- A_CommandTransitions2["INITIALIZED_TO_EXECUTING"] = "initialized_executing";
413
- A_CommandTransitions2["EXECUTING_TO_COMPLETED"] = "executing_completed";
414
- A_CommandTransitions2["EXECUTING_TO_FAILED"] = "executing_failed";
415
- return A_CommandTransitions2;
416
- })(A_CommandTransitions || {});
417
- var A_CommandFeatures = /* @__PURE__ */ ((A_CommandFeatures2) => {
418
- A_CommandFeatures2["onInit"] = "onInit";
419
- A_CommandFeatures2["onBeforeExecute"] = "onBeforeExecute";
420
- A_CommandFeatures2["onExecute"] = "onExecute";
421
- A_CommandFeatures2["onAfterExecute"] = "onAfterExecute";
422
- A_CommandFeatures2["onComplete"] = "onComplete";
423
- A_CommandFeatures2["onFail"] = "onFail";
424
- A_CommandFeatures2["onError"] = "onError";
425
- return A_CommandFeatures2;
426
- })(A_CommandFeatures || {});
427
- var A_CommandError = class extends aConcept.A_Error {
428
- };
429
- A_CommandError.CommandScopeBindingError = "A-Command Scope Binding Error";
430
- A_CommandError.ExecutionError = "A-Command Execution Error";
431
- A_CommandError.ResultProcessingError = "A-Command Result Processing Error";
432
- /**
433
- * Error indicating that the command was interrupted during execution
434
- */
435
- A_CommandError.CommandInterruptedError = "A-Command Interrupted Error";
436
- var A_StateMachineError = class extends aConcept.A_Error {
437
- };
438
- A_StateMachineError.InitializationError = "A-StateMachine Initialization Error";
439
- A_StateMachineError.TransitionError = "A-StateMachine Transition Error";
440
-
441
- // src/lib/A-StateMachine/A-StateMachineTransition.context.ts
442
- var A_StateMachineTransition = class extends A_OperationContext {
443
- constructor(params) {
444
- super(
445
- "a-state-machine-transition",
446
- params
447
- );
448
- this._meta.set("from", params.from);
449
- this._meta.set("to", params.to);
450
- }
451
- get from() {
452
- return this._meta.get("from");
453
- }
454
- get to() {
455
- return this._meta.get("to");
456
- }
457
- };
458
-
459
- // src/lib/A-StateMachine/A-StateMachine.component.ts
460
- var _a, _b, _c, _d;
461
- var A_StateMachine = class extends aConcept.A_Component {
462
- /**
463
- * Gets a promise that resolves when the state machine is fully initialized and ready for transitions.
464
- * This ensures that all initialization hooks have been executed before allowing state transitions.
465
- *
466
- * @returns Promise<void> that resolves when initialization is complete
467
- *
468
- * @example
469
- * ```typescript
470
- * const stateMachine = new MyStateMachine();
471
- * await stateMachine.ready; // Wait for initialization
472
- * await stateMachine.transition('idle', 'running');
473
- * ```
474
- */
475
- get ready() {
476
- if (!this._initialized) {
477
- this._initialized = this.call("onInitialize" /* onInitialize */);
478
- }
479
- return this._initialized;
480
- }
481
- async [_d = "onInitialize" /* onInitialize */](...args) {
482
- }
483
- async [_c = "onBeforeTransition" /* onBeforeTransition */](...args) {
484
- }
485
- async [_b = "onAfterTransition" /* onAfterTransition */](...args) {
486
- }
487
- async [_a = "onError" /* onError */](...args) {
488
- }
489
- /**
490
- * Executes a state transition from one state to another.
491
- * This is the core method of the state machine that handles the complete transition lifecycle.
492
- *
493
- * @param from - The state to transition from (must be a key of T)
494
- * @param to - The state to transition to (must be a key of T)
495
- * @param props - Optional properties to pass to the transition context (should match T[keyof T])
496
- * @returns Promise<void> that resolves when the transition is complete
497
- *
498
- * @throws {A_StateMachineError} When the transition fails for any reason
499
- *
500
- * @example
501
- * ```typescript
502
- * interface OrderStates {
503
- * pending: { orderId: string };
504
- * processing: { orderId: string; processedBy: string };
505
- * }
506
- *
507
- * const orderMachine = new A_StateMachine<OrderStates>();
508
- *
509
- * // Transition with props
510
- * await orderMachine.transition('pending', 'processing', {
511
- * orderId: '12345',
512
- * processedBy: 'user-456'
513
- * });
514
- * ```
515
- *
516
- * The transition process follows this lifecycle:
517
- * 1. Wait for state machine initialization (ready)
518
- * 2. Create transition name in camelCase format (e.g., "pending_processing")
519
- * 3. Create operation context with transition data
520
- * 4. Create isolated scope for the transition
521
- * 5. Call onBeforeTransition hook
522
- * 6. Execute the specific transition method (if defined)
523
- * 7. Call onAfterTransition hook
524
- * 8. Clean up scope and return result
525
- *
526
- * If any step fails, the onError hook is called and a wrapped error is thrown.
527
- */
528
- async transition(from, to, props) {
529
- await this.ready;
530
- const transitionName = `${aConcept.A_FormatterHelper.toCamelCase(String(from))}_${aConcept.A_FormatterHelper.toCamelCase(String(to))}`;
531
- const transition = new A_StateMachineTransition({
532
- from: String(from),
533
- to: String(to),
534
- props
535
- });
536
- const scope = new aConcept.A_Scope({
537
- name: `A-StateMachine-Transition-Scope-${transitionName}`,
538
- fragments: [transition]
539
- });
540
- try {
541
- await this.call("onBeforeTransition" /* onBeforeTransition */, scope);
542
- await this.call(transitionName, scope);
543
- await this.call("onAfterTransition" /* onAfterTransition */, scope);
544
- scope.destroy();
545
- return transition.result;
546
- } catch (error) {
547
- const wrappedError = new A_StateMachineError({
548
- title: A_StateMachineError.TransitionError,
549
- description: `An error occurred while transitioning to "${transitionName}"`,
550
- originalError: error
551
- });
552
- scope.register(wrappedError);
553
- await this.call("onError" /* onError */, scope);
554
- scope.destroy();
555
- throw wrappedError;
556
- }
557
- }
558
- };
559
- __decorateClass([
560
- aConcept.A_Feature.Extend()
561
- ], A_StateMachine.prototype, _d, 1);
562
- __decorateClass([
563
- aConcept.A_Feature.Extend()
564
- ], A_StateMachine.prototype, _c, 1);
565
- __decorateClass([
566
- aConcept.A_Feature.Extend()
567
- ], A_StateMachine.prototype, _b, 1);
568
- __decorateClass([
569
- aConcept.A_Feature.Extend()
570
- ], A_StateMachine.prototype, _a, 1);
571
-
572
- // src/lib/A-Config/A-Config.constants.ts
573
- var A_CONSTANTS__CONFIG_ENV_VARIABLES = {};
574
- var A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY = [];
575
-
576
- // src/lib/A-Config/A-Config.context.ts
577
- var A_Config = class extends aConcept.A_Fragment {
578
- constructor(config) {
579
- super({
580
- name: "A_Config"
581
- });
582
- this.VARIABLES = /* @__PURE__ */ new Map();
583
- this.DEFAULT_ALLOWED_TO_READ_PROPERTIES = [
584
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
585
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
586
- ];
587
- this.config = aConcept.A_CommonHelper.deepCloneAndMerge(config, {
588
- strict: false,
589
- defaults: {},
590
- variables: aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY
591
- });
592
- this.CONFIG_PROPERTIES = this.config.variables ? this.config.variables : [];
593
- this.config.variables.forEach((variable) => {
594
- this.VARIABLES.set(
595
- aConcept.A_FormatterHelper.toUpperSnakeCase(variable),
596
- this.config.defaults[variable]
597
- );
598
- });
599
- }
600
- /**
601
- * This method is used to get the configuration property by name
602
- *
603
- * @param property
604
- * @returns
605
- */
606
- get(property) {
607
- if (this.CONFIG_PROPERTIES.includes(property) || this.DEFAULT_ALLOWED_TO_READ_PROPERTIES.includes(property) || !this.config.strict)
608
- return this.VARIABLES.get(aConcept.A_FormatterHelper.toUpperSnakeCase(property));
609
- throw new Error("Property not exists or not allowed to read");
610
- }
611
- set(property, value) {
612
- const array = Array.isArray(property) ? property : typeof property === "string" ? [{ property, value }] : Object.keys(property).map((key) => ({
613
- property: key,
614
- value: property[key]
615
- }));
616
- for (const { property: property2, value: value2 } of array) {
617
- let targetValue = value2 ? value2 : this.config?.defaults ? this.config.defaults[property2] : void 0;
618
- this.VARIABLES.set(aConcept.A_FormatterHelper.toUpperSnakeCase(property2), targetValue);
619
- }
620
- }
621
- };
622
-
623
- // src/lib/A-Logger/A-Logger.constants.ts
624
- var A_LOGGER_DEFAULT_SCOPE_LENGTH = 20;
625
- var A_LOGGER_COLORS = {
626
- // System colors (reserved for specific purposes)
627
- red: "31",
628
- // Errors, critical issues
629
- yellow: "33",
630
- // Warnings, caution messages
631
- green: "32",
632
- // Success, completion messages
633
- // Safe palette for random selection (grey-blue-violet theme)
634
- blue: "34",
635
- // Info, general messages
636
- cyan: "36",
637
- // Headers, titles
638
- magenta: "35",
639
- // Special highlighting
640
- gray: "90",
641
- // Debug, less important info
642
- brightBlue: "94",
643
- // Bright blue variant
644
- brightCyan: "96",
645
- // Bright cyan variant
646
- brightMagenta: "95",
647
- // Bright magenta variant
648
- darkGray: "30",
649
- // Dark gray
650
- lightGray: "37",
651
- // Light gray (white)
652
- // Extended blue-violet palette
653
- indigo: "38;5;54",
654
- // Deep indigo
655
- violet: "38;5;93",
656
- // Violet
657
- purple: "38;5;129",
658
- // Purple
659
- lavender: "38;5;183",
660
- // Lavender
661
- skyBlue: "38;5;117",
662
- // Sky blue
663
- steelBlue: "38;5;67",
664
- // Steel blue
665
- slateBlue: "38;5;62",
666
- // Slate blue
667
- deepBlue: "38;5;18",
668
- // Deep blue
669
- lightBlue: "38;5;153",
670
- // Light blue
671
- periwinkle: "38;5;111",
672
- // Periwinkle
673
- cornflower: "38;5;69",
674
- // Cornflower blue
675
- powder: "38;5;152",
676
- // Powder blue
677
- // Additional grays for variety
678
- charcoal: "38;5;236",
679
- // Charcoal
680
- silver: "38;5;250",
681
- // Silver
682
- smoke: "38;5;244",
683
- // Smoke gray
684
- slate: "38;5;240"
685
- // Slate gray
686
- };
687
- var A_LOGGER_SAFE_RANDOM_COLORS = [
688
- "blue",
689
- "cyan",
690
- "magenta",
691
- "gray",
692
- "brightBlue",
693
- "brightCyan",
694
- "brightMagenta",
695
- "darkGray",
696
- "lightGray",
697
- "indigo",
698
- "violet",
699
- "purple",
700
- "lavender",
701
- "skyBlue",
702
- "steelBlue",
703
- "slateBlue",
704
- "deepBlue",
705
- "lightBlue",
706
- "periwinkle",
707
- "cornflower",
708
- "powder",
709
- "charcoal",
710
- "silver",
711
- "smoke",
712
- "slate"
713
- ];
714
- var A_LOGGER_ANSI = {
715
- RESET: "\x1B[0m",
716
- PREFIX: "\x1B[",
717
- SUFFIX: "m"
718
- };
719
- var A_LOGGER_TIME_FORMAT = {
720
- MINUTES_PAD: 2,
721
- SECONDS_PAD: 2,
722
- MILLISECONDS_PAD: 3,
723
- SEPARATOR: ":"
724
- };
725
- var A_LOGGER_FORMAT = {
726
- SCOPE_OPEN: "[",
727
- SCOPE_CLOSE: "]",
728
- TIME_OPEN: "|",
729
- TIME_CLOSE: "|",
730
- SEPARATOR: "-------------------------------",
731
- PIPE: "| "
732
- };
733
- var A_LOGGER_ENV_KEYS = {
734
- LOG_LEVEL: "A_LOGGER_LEVEL",
735
- DEFAULT_SCOPE_LENGTH: "A_LOGGER_DEFAULT_SCOPE_LENGTH",
736
- DEFAULT_SCOPE_COLOR: "A_LOGGER_DEFAULT_SCOPE_COLOR",
737
- DEFAULT_LOG_COLOR: "A_LOGGER_DEFAULT_LOG_COLOR"
738
- };
739
-
740
- // src/lib/A-Logger/A-Logger.component.ts
741
- exports.A_Logger = class A_Logger extends aConcept.A_Component {
742
- // =============================================
743
- // Constructor and Initialization
744
- // =============================================
745
- /**
746
- * Initialize A_Logger with dependency injection
747
- * Colors are configured through A_Config or generated randomly if not provided
748
- *
749
- * @param scope - The current scope context for message prefixing
750
- * @param config - Optional configuration for log level filtering and color settings
751
- */
752
- constructor(scope, config) {
753
- super();
754
- this.scope = scope;
755
- this.config = config;
756
- this.COLORS = A_LOGGER_COLORS;
757
- this.STANDARD_SCOPE_LENGTH = config?.get(A_LOGGER_ENV_KEYS.DEFAULT_SCOPE_LENGTH) || A_LOGGER_DEFAULT_SCOPE_LENGTH;
758
- const configScopeColor = config?.get(A_LOGGER_ENV_KEYS.DEFAULT_SCOPE_COLOR);
759
- const configLogColor = config?.get(A_LOGGER_ENV_KEYS.DEFAULT_LOG_COLOR);
760
- if (configScopeColor || configLogColor) {
761
- this.DEFAULT_SCOPE_COLOR = configScopeColor || this.generateColorFromScopeName(this.scope.name);
762
- this.DEFAULT_LOG_COLOR = configLogColor || this.generateColorFromScopeName(this.scope.name);
763
- } else {
764
- const complementaryColors = this.generateComplementaryColorsFromScope(this.scope.name);
765
- this.DEFAULT_SCOPE_COLOR = complementaryColors.scopeColor;
766
- this.DEFAULT_LOG_COLOR = complementaryColors.logColor;
767
- }
768
- }
769
- // =============================================
770
- // Color Generation Utilities
771
- // =============================================
772
- /**
773
- * Generate a simple hash from a string
774
- * Used to create deterministic color selection based on scope name
775
- *
776
- * @param str - The string to hash
777
- * @returns A numeric hash value
778
- */
779
- simpleHash(str) {
780
- let hash = 0;
781
- for (let i = 0; i < str.length; i++) {
782
- const char = str.charCodeAt(i);
783
- hash = (hash << 5) - hash + char;
784
- hash = hash & hash;
785
- }
786
- return Math.abs(hash);
787
- }
788
- /**
789
- * Generate a deterministic color based on scope name
790
- * Same scope names will always get the same color, but uses safe color palette
791
- *
792
- * @param scopeName - The scope name to generate color for
793
- * @returns A color key from the safe colors palette
794
- */
795
- generateColorFromScopeName(scopeName) {
796
- const safeColors = A_LOGGER_SAFE_RANDOM_COLORS;
797
- const hash = this.simpleHash(scopeName);
798
- const colorIndex = hash % safeColors.length;
799
- return safeColors[colorIndex];
800
- }
801
- /**
802
- * Generate a pair of complementary colors based on scope name
803
- * Ensures visual harmony between scope and message colors while being deterministic
804
- *
805
- * @param scopeName - The scope name to base colors on
806
- * @returns Object with scopeColor and logColor that work well together
807
- */
808
- generateComplementaryColorsFromScope(scopeName) {
809
- const colorPairs = [
810
- { scopeColor: "indigo", logColor: "lightBlue" },
811
- { scopeColor: "deepBlue", logColor: "cyan" },
812
- { scopeColor: "purple", logColor: "lavender" },
813
- { scopeColor: "steelBlue", logColor: "skyBlue" },
814
- { scopeColor: "slateBlue", logColor: "periwinkle" },
815
- { scopeColor: "charcoal", logColor: "silver" },
816
- { scopeColor: "violet", logColor: "brightMagenta" },
817
- { scopeColor: "darkGray", logColor: "lightGray" },
818
- { scopeColor: "cornflower", logColor: "powder" },
819
- { scopeColor: "slate", logColor: "smoke" }
820
- ];
821
- const hash = this.simpleHash(scopeName);
822
- const pairIndex = hash % colorPairs.length;
823
- return colorPairs[pairIndex];
824
- }
825
- // =============================================
826
- // Factory Methods
827
- // =============================================
828
- // =============================================
829
- // Scope and Formatting Utilities
830
- // =============================================
831
- /**
832
- * Get the formatted scope length for consistent message alignment
833
- * Uses a standard length to ensure all messages align properly regardless of scope name
834
- *
835
- * @returns The scope length to use for padding calculations
836
- */
837
- get scopeLength() {
838
- return Math.max(this.scope.name.length, this.STANDARD_SCOPE_LENGTH);
839
- }
840
- /**
841
- * Get the formatted scope name with proper padding, centered within the container
842
- * Ensures consistent width for all scope names in log output with centered alignment
843
- *
844
- * @returns Centered and padded scope name for consistent formatting
845
- */
846
- get formattedScope() {
847
- const scopeName = this.scope.name;
848
- const totalLength = this.STANDARD_SCOPE_LENGTH;
849
- if (scopeName.length >= totalLength) {
850
- return scopeName.substring(0, totalLength);
851
- }
852
- const totalPadding = totalLength - scopeName.length;
853
- const leftPadding = Math.floor(totalPadding / 2);
854
- const rightPadding = totalPadding - leftPadding;
855
- return " ".repeat(leftPadding) + scopeName + " ".repeat(rightPadding);
856
- }
857
- // =============================================
858
- // Message Compilation and Formatting
859
- // =============================================
860
- /**
861
- * Compile log arguments into formatted console output with colors and proper alignment
862
- *
863
- * This method handles the core formatting logic for all log messages:
864
- * - Applies separate colors for scope and message content
865
- * - Formats scope names with consistent padding
866
- * - Handles different data types appropriately
867
- * - Maintains proper indentation for multi-line content
868
- *
869
- * @param messageColor - The color key to apply to the message content
870
- * @param args - Variable arguments to format and display
871
- * @returns Array of formatted strings ready for console output
872
- */
873
- compile(messageColor, ...args) {
874
- const timeString = this.getTime();
875
- const scopePadding = " ".repeat(this.scopeLength + 3);
876
- const isMultiArg = args.length > 1;
877
- return [
878
- // Header with separate colors for scope and message content
879
- `${A_LOGGER_ANSI.PREFIX}${this.COLORS[this.DEFAULT_SCOPE_COLOR]}${A_LOGGER_ANSI.SUFFIX}${A_LOGGER_FORMAT.SCOPE_OPEN}${this.formattedScope}${A_LOGGER_FORMAT.SCOPE_CLOSE}${A_LOGGER_ANSI.RESET} ${A_LOGGER_ANSI.PREFIX}${this.COLORS[messageColor]}${A_LOGGER_ANSI.SUFFIX}${A_LOGGER_FORMAT.TIME_OPEN}${timeString}${A_LOGGER_FORMAT.TIME_CLOSE}`,
880
- // Top separator for multi-argument messages
881
- isMultiArg ? `
882
- ${scopePadding}${A_LOGGER_FORMAT.TIME_OPEN}${A_LOGGER_FORMAT.SEPARATOR}` : "",
883
- // Process each argument with appropriate formatting
884
- ...args.map((arg, i) => {
885
- const shouldAddNewline = i > 0 || isMultiArg;
886
- switch (true) {
887
- case arg instanceof aConcept.A_Error:
888
- return this.compile_A_Error(arg);
889
- case arg instanceof Error:
890
- return this.compile_Error(arg);
891
- case (typeof arg === "object" && arg !== null):
892
- return this.formatObject(arg, shouldAddNewline, scopePadding);
893
- default:
894
- return this.formatString(String(arg), shouldAddNewline, scopePadding);
895
- }
896
- }),
897
- // Bottom separator and color reset
898
- isMultiArg ? `
899
- ${scopePadding}${A_LOGGER_FORMAT.TIME_OPEN}${A_LOGGER_FORMAT.SEPARATOR}${A_LOGGER_ANSI.RESET}` : A_LOGGER_ANSI.RESET
900
- ];
901
- }
902
- /**
903
- * Format an object for display with proper JSON indentation
904
- *
905
- * @param obj - The object to format
906
- * @param shouldAddNewline - Whether to add a newline prefix
907
- * @param scopePadding - The padding string for consistent alignment
908
- * @returns Formatted object string
909
- */
910
- formatObject(obj, shouldAddNewline, scopePadding) {
911
- let jsonString;
912
- try {
913
- jsonString = JSON.stringify(obj, null, 2);
914
- } catch (error) {
915
- const seen = /* @__PURE__ */ new WeakSet();
916
- jsonString = JSON.stringify(obj, (key, value) => {
917
- if (typeof value === "object" && value !== null) {
918
- if (seen.has(value)) {
919
- return "[Circular Reference]";
920
- }
921
- seen.add(value);
922
- }
923
- return value;
924
- }, 2);
925
- }
926
- const formatted = jsonString.replace(/\n/g, `
927
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}`);
928
- return shouldAddNewline ? `
929
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}` + formatted : formatted;
930
- }
931
- /**
932
- * Format a string for display with proper indentation
933
- *
934
- * @param str - The string to format
935
- * @param shouldAddNewline - Whether to add a newline prefix
936
- * @param scopePadding - The padding string for consistent alignment
937
- * @returns Formatted string
938
- */
939
- formatString(str, shouldAddNewline, scopePadding) {
940
- const prefix = shouldAddNewline ? "\n" : "";
941
- return (prefix + str).replace(/\n/g, `
942
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}`);
943
- }
944
- // =============================================
945
- // Log Level Management
946
- // =============================================
947
- /**
948
- * Determine if a log message should be output based on configured log level
949
- *
950
- * Log level hierarchy:
951
- * - debug: Shows all messages (debug, info, warning, error)
952
- * - info: Shows info, warning, and error messages
953
- * - warn: Shows warning and error messages only
954
- * - error: Shows error messages only
955
- * - all: Shows all messages (alias for debug)
956
- *
957
- * @param logMethod - The type of log method being called
958
- * @returns True if the message should be logged, false otherwise
959
- */
960
- shouldLog(logMethod) {
961
- const shouldLog = this.config?.get(A_LOGGER_ENV_KEYS.LOG_LEVEL) || "info";
962
- switch (shouldLog) {
963
- case "debug":
964
- return true;
965
- case "info":
966
- return logMethod === "info" || logMethod === "warning" || logMethod === "error";
967
- case "warn":
968
- return logMethod === "warning" || logMethod === "error";
969
- case "error":
970
- return logMethod === "error";
971
- case "all":
972
- return true;
973
- default:
974
- return false;
975
- }
976
- }
977
- debug(param1, ...args) {
978
- if (!this.shouldLog("debug")) return;
979
- if (typeof param1 === "string" && this.COLORS[param1]) {
980
- console.log(...this.compile(param1, ...args));
981
- } else {
982
- console.log(...this.compile(this.DEFAULT_LOG_COLOR, param1, ...args));
983
- }
984
- }
985
- info(param1, ...args) {
986
- if (!this.shouldLog("info")) return;
987
- if (typeof param1 === "string" && this.COLORS[param1]) {
988
- console.log(...this.compile(param1, ...args));
989
- } else {
990
- console.log(...this.compile(this.DEFAULT_LOG_COLOR, param1, ...args));
991
- }
992
- }
993
- log(param1, ...args) {
994
- this.info(param1, ...args);
995
- }
996
- /**
997
- * Log warning messages with yellow color coding
998
- *
999
- * Use for non-critical issues that should be brought to attention
1000
- * but don't prevent normal operation
1001
- *
1002
- * @param args - Arguments to log as warnings
1003
- *
1004
- * @example
1005
- * ```typescript
1006
- * logger.warning('Deprecated method used');
1007
- * logger.warning('Rate limit approaching:', { current: 95, limit: 100 });
1008
- * ```
1009
- */
1010
- warning(...args) {
1011
- if (!this.shouldLog("warning")) return;
1012
- console.log(...this.compile("yellow", ...args));
1013
- }
1014
- /**
1015
- * Log error messages with red color coding
1016
- *
1017
- * Use for critical issues, exceptions, and failures that need immediate attention
1018
- *
1019
- * @param args - Arguments to log as errors
1020
- * @returns void (for compatibility with console.log)
1021
- *
1022
- * @example
1023
- * ```typescript
1024
- * logger.error('Database connection failed');
1025
- * logger.error(new Error('Validation failed'));
1026
- * logger.error('Critical error:', error, { context: 'user-registration' });
1027
- * ```
1028
- */
1029
- error(...args) {
1030
- if (!this.shouldLog("error")) return;
1031
- console.log(...this.compile("red", ...args));
1032
- }
1033
- // =============================================
1034
- // Specialized Error Formatting
1035
- // =============================================
1036
- /**
1037
- * Legacy method for A_Error logging (kept for backward compatibility)
1038
- *
1039
- * @deprecated Use error() method instead which handles A_Error automatically
1040
- * @param error - The A_Error instance to log
1041
- */
1042
- log_A_Error(error) {
1043
- const time = this.getTime();
1044
- const scopePadding = " ".repeat(this.scopeLength + 3);
1045
- console.log(`\x1B[31m[${this.formattedScope}] |${time}| ERROR ${error.code}
1046
- ${scopePadding}| ${error.message}
1047
- ${scopePadding}| ${error.description}
1048
- ${scopePadding}|-------------------------------
1049
- ${scopePadding}| ${error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
1050
- ${scopePadding}|-------------------------------
1051
- \x1B[0m` + (error.originalError ? `\x1B[31m${scopePadding}| Wrapped From ${error.originalError.message}
1052
- ${scopePadding}|-------------------------------
1053
- ${scopePadding}| ${error.originalError.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
1054
- ${scopePadding}|-------------------------------
1055
- \x1B[0m` : "") + (error.link ? `\x1B[31m${scopePadding}| Read in docs: ${error.link}
1056
- ${scopePadding}|-------------------------------
1057
- \x1B[0m` : ""));
1058
- }
1059
- /**
1060
- * Format A_Error instances for inline display within compiled messages
1061
- *
1062
- * Provides detailed formatting for A_Error objects including:
1063
- * - Error code and message
1064
- * - Description and stack trace
1065
- * - Original error information (if wrapped)
1066
- * - Documentation links (if available)
1067
- *
1068
- * @param error - The A_Error instance to format
1069
- * @returns Formatted string ready for display
1070
- */
1071
- compile_A_Error(error) {
1072
- const scopePadding = " ".repeat(this.scopeLength + 3);
1073
- return `
1074
- ${scopePadding}|-------------------------------
1075
- ${scopePadding}| Error: | ${error.code}
1076
- ${scopePadding}|-------------------------------
1077
- ${scopePadding}|${" ".repeat(10)}| ${error.message}
1078
- ${scopePadding}|${" ".repeat(10)}| ${error.description}
1079
- ${scopePadding}|-------------------------------
1080
- ${scopePadding}| ${error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
1081
- ${scopePadding}|-------------------------------` + (error.originalError ? `${scopePadding}| Wrapped From ${error.originalError.message}
1082
- ${scopePadding}|-------------------------------
1083
- ${scopePadding}| ${error.originalError.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
1084
- ${scopePadding}|-------------------------------` : "") + (error.link ? `${scopePadding}| Read in docs: ${error.link}
1085
- ${scopePadding}|-------------------------------` : "");
1086
- }
1087
- /**
1088
- * Format standard Error instances for inline display within compiled messages
1089
- *
1090
- * Converts standard JavaScript Error objects into a readable JSON format
1091
- * with proper indentation and stack trace formatting
1092
- *
1093
- * @param error - The Error instance to format
1094
- * @returns Formatted string ready for display
1095
- */
1096
- compile_Error(error) {
1097
- const scopePadding = " ".repeat(this.scopeLength + 3);
1098
- return JSON.stringify({
1099
- name: error.name,
1100
- message: error.message,
1101
- stack: error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n")
1102
- }, null, 2).replace(/\n/g, `
1103
- ${scopePadding}| `).replace(/\\n/g, "\n");
1104
- }
1105
- // =============================================
1106
- // Utility Methods
1107
- // =============================================
1108
- /**
1109
- * Generate timestamp string for log messages
1110
- *
1111
- * Format: MM:SS:mmm (minutes:seconds:milliseconds)
1112
- * This provides sufficient precision for debugging while remaining readable
1113
- *
1114
- * @returns Formatted timestamp string
1115
- *
1116
- * @example
1117
- * Returns: "15:42:137" for 3:42:15 PM and 137 milliseconds
1118
- */
1119
- getTime() {
1120
- const now = /* @__PURE__ */ new Date();
1121
- const minutes = String(now.getMinutes()).padStart(A_LOGGER_TIME_FORMAT.MINUTES_PAD, "0");
1122
- const seconds = String(now.getSeconds()).padStart(A_LOGGER_TIME_FORMAT.SECONDS_PAD, "0");
1123
- const milliseconds = String(now.getMilliseconds()).padStart(A_LOGGER_TIME_FORMAT.MILLISECONDS_PAD, "0");
1124
- return `${minutes}${A_LOGGER_TIME_FORMAT.SEPARATOR}${seconds}${A_LOGGER_TIME_FORMAT.SEPARATOR}${milliseconds}`;
1125
- }
1126
- };
1127
- exports.A_Logger = __decorateClass([
1128
- __decorateParam(0, aConcept.A_Inject(aConcept.A_Scope)),
1129
- __decorateParam(1, aConcept.A_Inject(A_Config))
1130
- ], exports.A_Logger);
1131
-
1132
- // src/lib/A-Command/A-Command.entity.ts
1133
- var _a2, _b2, _c2, _d2, _e, _f, _g, _h, _i, _j, _k;
1134
- var A_Command = class extends aConcept.A_Entity {
1135
- /**
1136
- *
1137
- * A-Command represents an executable command with a specific code and parameters.
1138
- * It can be executed within a given scope and stores execution results and errors.
1139
- *
1140
- *
1141
- * A-Command should be context independent and execution logic should be based on attached components
1142
- *
1143
- * @param code
1144
- * @param params
1145
- */
1146
- constructor(params) {
1147
- super(params);
1148
- /** Map of event listeners organized by event name */
1149
- this._listeners = /* @__PURE__ */ new Map();
1150
- }
1151
- // ====================================================================
1152
- // ================== Static Command Information ======================
1153
- // ====================================================================
1154
- /**
1155
- * Static command identifier derived from the class name
1156
- * Used for command registration and serialization
1157
- */
1158
- static get code() {
1159
- return super.entity;
1160
- }
1161
- // ====================================================================
1162
- // ================== Public Getter Properties =======================
1163
- // ====================================================================
1164
- /**
1165
- * Total execution duration in milliseconds
1166
- *
1167
- * - If completed/failed: Returns total time from start to end
1168
- * - If currently executing: Returns elapsed time since start
1169
- * - If not started: Returns undefined
1170
- */
1171
- get duration() {
1172
- return this._endTime && this._startTime ? this._endTime.getTime() - this._startTime.getTime() : this._startTime ? (/* @__PURE__ */ new Date()).getTime() - this._startTime.getTime() : void 0;
1173
- }
1174
- /**
1175
- * Idle time before execution started in milliseconds
1176
- *
1177
- * Time between command creation and execution start.
1178
- * Useful for monitoring command queue performance.
1179
- */
1180
- get idleTime() {
1181
- return this._startTime && this._createdAt ? this._startTime.getTime() - this._createdAt.getTime() : void 0;
1182
- }
1183
- /**
1184
- * Command execution scope for dependency injection
1185
- *
1186
- * Provides access to components, services, and shared resources
1187
- * during command execution. Inherits from the scope where the
1188
- * command was registered.
1189
- */
1190
- get scope() {
1191
- return this._executionScope;
1192
- }
1193
- /**
1194
- * Unique command type identifier
1195
- *
1196
- * Derived from the class name and used for:
1197
- * - Command registration and resolution
1198
- * - Serialization and deserialization
1199
- * - Logging and debugging
1200
- *
1201
- * @example 'create-user-command', 'process-order-command'
1202
- */
1203
- get code() {
1204
- return this.constructor.code;
1205
- }
1206
- /**
1207
- * Current lifecycle status of the command
1208
- *
1209
- * Indicates the current phase in the command execution lifecycle.
1210
- * Used to track progress and determine available operations.
1211
- */
1212
- get status() {
1213
- return this._status;
1214
- }
1215
- /**
1216
- * Timestamp when the command was created
1217
- *
1218
- * Marks the initial instantiation time, useful for tracking
1219
- * command age and queue performance metrics.
1220
- */
1221
- get createdAt() {
1222
- return this._createdAt;
1223
- }
1224
- /**
1225
- * Timestamp when command execution started
1226
- *
1227
- * Undefined until execution begins. Used for calculating
1228
- * execution duration and idle time.
1229
- */
1230
- get startedAt() {
1231
- return this._startTime;
1232
- }
1233
- /**
1234
- * Timestamp when command execution ended
1235
- *
1236
- * Set when command reaches COMPLETED or FAILED status.
1237
- * Used for calculating total execution duration.
1238
- */
1239
- get endedAt() {
1240
- return this._endTime;
1241
- }
1242
- /**
1243
- * Result data produced by command execution
1244
- *
1245
- * Contains the output data from successful command execution.
1246
- * Undefined until command completes successfully.
1247
- */
1248
- get result() {
1249
- return this._result;
1250
- }
1251
- /**
1252
- * Array of errors that occurred during execution
1253
- *
1254
- * Automatically wraps native errors in A_Error instances
1255
- * for consistent error handling. Empty array if no errors occurred.
1256
- */
1257
- get error() {
1258
- return this._error;
1259
- }
1260
- /**
1261
- * Command initialization parameters
1262
- *
1263
- * Contains the input data used to create and configure the command.
1264
- * These parameters are immutable during command execution.
1265
- return new A_Error(err);
1266
- }
1267
- });
1268
- }
1269
-
1270
- /**
1271
- * Command initialization parameters
1272
- *
1273
- * Contains the input data used to create and configure the command.
1274
- * These parameters are immutable during command execution.
1275
- */
1276
- get params() {
1277
- return this._params;
1278
- }
1279
- /**
1280
- * Indicates if the command has been processed (completed or failed)
1281
- *
1282
- * Returns true if the command has completed or failed, false otherwise.
1283
- */
1284
- get isProcessed() {
1285
- return this._status === "COMPLETED" /* COMPLETED */ || this._status === "FAILED" /* FAILED */;
1286
- }
1287
- async [_k = "onBeforeTransition" /* onBeforeTransition */](transition, logger, ...args) {
1288
- this.checkScopeInheritance();
1289
- logger?.debug("yellow", `Command ${this.aseid.toString()} transitioning from ${transition.from} to ${transition.to}`);
1290
- }
1291
- async [_j = "created_initialized" /* CREATED_TO_INITIALIZED */](transition, ...args) {
1292
- if (this._status !== "CREATED" /* CREATED */) {
1293
- return;
1294
- }
1295
- this._createdAt = /* @__PURE__ */ new Date();
1296
- this._status = "INITIALIZED" /* INITIALIZED */;
1297
- this.emit("onInit" /* onInit */);
1298
- }
1299
- async [_i = "initialized_executing" /* INITIALIZED_TO_EXECUTING */](transition, ...args) {
1300
- if (this._status !== "INITIALIZED" /* INITIALIZED */ && this._status !== "CREATED" /* CREATED */) {
1301
- return;
1302
- }
1303
- this._startTime = /* @__PURE__ */ new Date();
1304
- this._status = "EXECUTING" /* EXECUTING */;
1305
- this.emit("onExecute" /* onExecute */);
1306
- }
1307
- /**
1308
- * Handles command completion after successful execution
1309
- *
1310
- * EXECUTION -> COMPLETED transition
1311
- */
1312
- async [_h = "executing_completed" /* EXECUTING_TO_COMPLETED */](transition, ...args) {
1313
- this._endTime = /* @__PURE__ */ new Date();
1314
- this._status = "COMPLETED" /* COMPLETED */;
1315
- this.emit("onComplete" /* onComplete */);
1316
- }
1317
- /**
1318
- * Handles command failure during execution
1319
- *
1320
- * EXECUTION -> FAILED transition
1321
- */
1322
- async [_g = "executing_failed" /* EXECUTING_TO_FAILED */](transition, error, ...args) {
1323
- this._endTime = /* @__PURE__ */ new Date();
1324
- this._status = "FAILED" /* FAILED */;
1325
- this.emit("onFail" /* onFail */);
1326
- }
1327
- /**
1328
- * Default behavior for Command Initialization uses StateMachine to transition states
1329
- */
1330
- async [_f = "onInit" /* onInit */](stateMachine, ...args) {
1331
- await stateMachine.transition("CREATED" /* CREATED */, "INITIALIZED" /* INITIALIZED */);
1332
- }
1333
- async [_e = "onBeforeExecute" /* onBeforeExecute */](stateMachine, ...args) {
1334
- await stateMachine.transition("INITIALIZED" /* INITIALIZED */, "EXECUTING" /* EXECUTING */);
1335
- }
1336
- async [_d2 = "onExecute" /* onExecute */](...args) {
1337
- }
1338
- /**
1339
- * By Default on AfterExecute calls the Completion method to mark the command as completed
1340
- *
1341
- * [!] This can be overridden to implement custom behavior using A_Feature overrides
1342
- */
1343
- async [_c2 = "onAfterExecute" /* onAfterExecute */](...args) {
1344
- }
1345
- async [_b2 = "onComplete" /* onComplete */](stateMachine, ...args) {
1346
- await stateMachine.transition("EXECUTING" /* EXECUTING */, "COMPLETED" /* COMPLETED */);
1347
- }
1348
- async [_a2 = "onFail" /* onFail */](stateMachine, operation, ...args) {
1349
- await stateMachine.transition("EXECUTING" /* EXECUTING */, "FAILED" /* FAILED */);
1350
- }
1351
- // --------------------------------------------------------------------------
1352
- // A-Command Lifecycle Methods
1353
- // --------------------------------------------------------------------------
1354
- /**
1355
- * Initializes the command before execution.
1356
- */
1357
- async init() {
1358
- await this.call("onInit" /* onInit */, this.scope);
1359
- }
1360
- /**
1361
- * Executes the command logic.
1362
- */
1363
- async execute() {
1364
- if (this.isProcessed) return;
1365
- try {
1366
- this.checkScopeInheritance();
1367
- const context = new A_OperationContext("execute-command");
1368
- this.scope.register(context);
1369
- await new Promise(async (resolve, reject) => {
1370
- try {
1371
- const onBeforeExecuteFeature = new aConcept.A_Feature({
1372
- name: "onBeforeExecute" /* onBeforeExecute */,
1373
- component: this,
1374
- scope: this.scope
1375
- });
1376
- const onExecuteFeature = new aConcept.A_Feature({
1377
- name: "onExecute" /* onExecute */,
1378
- component: this,
1379
- scope: this.scope
1380
- });
1381
- const onAfterExecuteFeature = new aConcept.A_Feature({
1382
- name: "onAfterExecute" /* onAfterExecute */,
1383
- component: this,
1384
- scope: this.scope
1385
- });
1386
- this.on("onComplete" /* onComplete */, () => {
1387
- onBeforeExecuteFeature.interrupt();
1388
- onExecuteFeature.interrupt();
1389
- onAfterExecuteFeature.interrupt();
1390
- resolve();
1391
- });
1392
- await onBeforeExecuteFeature.process(this.scope);
1393
- await onExecuteFeature.process(this.scope);
1394
- await onAfterExecuteFeature.process(this.scope);
1395
- if (this._origin === "invoked") {
1396
- await this.complete();
1397
- }
1398
- resolve();
1399
- } catch (error) {
1400
- reject(error);
1401
- }
1402
- });
1403
- } catch (error) {
1404
- let targetError = error instanceof aConcept.A_Error ? error : new A_CommandError({
1405
- title: A_CommandError.ExecutionError,
1406
- description: `An error occurred while executing command "${this.aseid.toString()}".`,
1407
- originalError: error
1408
- });
1409
- await this.fail(targetError);
1410
- }
1411
- }
1412
- /**
1413
- * Marks the command as completed
1414
- */
1415
- async complete(result) {
1416
- if (this.isProcessed) return;
1417
- this._status = "COMPLETED" /* COMPLETED */;
1418
- this._result = result;
1419
- await this.call("onComplete" /* onComplete */, this.scope);
1420
- this.scope.destroy();
1421
- }
1422
- /**
1423
- * Marks the command as failed
1424
- */
1425
- async fail(error) {
1426
- if (this.isProcessed) return;
1427
- this._status = "FAILED" /* FAILED */;
1428
- if (error) {
1429
- this._error = error;
1430
- this.scope.register(error);
1431
- }
1432
- await this.call("onFail" /* onFail */, this.scope);
1433
- this.scope.destroy();
1434
- }
1435
- // --------------------------------------------------------------------------
1436
- // A-Command Event-Emitter methods
1437
- // --------------------------------------------------------------------------
1438
- /**
1439
- * Registers an event listener for a specific event
1440
- *
1441
- * @param event
1442
- * @param listener
1443
- */
1444
- on(event, listener) {
1445
- if (!this._listeners.has(event)) {
1446
- this._listeners.set(event, /* @__PURE__ */ new Set());
1447
- }
1448
- this._listeners.get(event).add(listener);
1449
- }
1450
- /**
1451
- * Removes an event listener for a specific event
1452
- *
1453
- * @param event
1454
- * @param listener
1455
- */
1456
- off(event, listener) {
1457
- this._listeners.get(event)?.delete(listener);
1458
- }
1459
- /**
1460
- * Emits an event to all registered listeners
1461
- *
1462
- * @param event
1463
- */
1464
- emit(event) {
1465
- this._listeners.get(event)?.forEach(async (listener) => {
1466
- listener(this);
1467
- });
1468
- }
1469
- // --------------------------------------------------------------------------
1470
- // A-Entity Base Class Overrides
1471
- // --------------------------------------------------------------------------
1472
- // Serialization / Deserialization
1473
- // -------------------------------------------------------------------------
1474
- /**
1475
- * Allows to create a Command instance from new data
1476
- *
1477
- * @param newEntity
1478
- */
1479
- fromNew(newEntity) {
1480
- super.fromNew(newEntity);
1481
- this._origin = "invoked";
1482
- this._executionScope = new aConcept.A_Scope({
1483
- name: `A-Command-Execution-Scope-${this.aseid.toString()}`,
1484
- components: [A_StateMachine]
1485
- });
1486
- this._createdAt = /* @__PURE__ */ new Date();
1487
- this._params = newEntity;
1488
- this._status = "CREATED" /* CREATED */;
1489
- }
1490
- /**
1491
- * Allows to convert serialized data to Command instance
1492
- *
1493
- * [!] By default it omits params as they are not stored in the serialized data
1494
- *
1495
- * @param serialized
1496
- */
1497
- fromJSON(serialized) {
1498
- super.fromJSON(serialized);
1499
- this._origin = "serialized";
1500
- this._executionScope = new aConcept.A_Scope({
1501
- name: `A-Command-Execution-Scope-${this.aseid.toString()}`,
1502
- components: [A_StateMachine]
1503
- });
1504
- if (serialized.createdAt) this._createdAt = new Date(serialized.createdAt);
1505
- if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
1506
- if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
1507
- this._params = serialized.params;
1508
- this._status = serialized.status;
1509
- if (serialized.error)
1510
- this._error = new A_CommandError(serialized.error);
1511
- if (serialized.result)
1512
- this._result = serialized.result;
1513
- }
1514
- /**
1515
- * Converts the Command instance to a plain object
1516
- *
1517
- * @returns
1518
- */
1519
- toJSON() {
1520
- return {
1521
- ...super.toJSON(),
1522
- code: this.code,
1523
- status: this._status,
1524
- params: this._params,
1525
- createdAt: this._createdAt.toISOString(),
1526
- startedAt: this._startTime ? this._startTime.toISOString() : void 0,
1527
- endedAt: this._endTime ? this._endTime.toISOString() : void 0,
1528
- duration: this.duration,
1529
- idleTime: this.idleTime,
1530
- result: this.result,
1531
- error: this.error ? this.error.toJSON() : void 0
1532
- };
1533
- }
1534
- //============================================================================================
1535
- // Helpers Methods
1536
- //============================================================================================
1537
- /**
1538
- * Ensures that the command's execution scope inherits from the context scope
1539
- *
1540
- * Throws an error if the command is not bound to any context scope
1541
- */
1542
- checkScopeInheritance() {
1543
- let attachedScope;
1544
- try {
1545
- attachedScope = aConcept.A_Context.scope(this);
1546
- } catch (error) {
1547
- throw new A_CommandError({
1548
- title: A_CommandError.CommandScopeBindingError,
1549
- description: `Command ${this.aseid.toString()} is not bound to any context scope. Ensure the command is properly registered within a context before execution.`,
1550
- originalError: error
1551
- });
1552
- }
1553
- if (!this.scope.isInheritedFrom(aConcept.A_Context.scope(this))) {
1554
- this.scope.inherit(aConcept.A_Context.scope(this));
1555
- }
1556
- }
1557
- };
1558
- __decorateClass([
1559
- aConcept.A_Feature.Extend(),
1560
- __decorateParam(0, aConcept.A_Inject(A_StateMachineTransition)),
1561
- __decorateParam(1, aConcept.A_Inject(exports.A_Logger))
1562
- ], A_Command.prototype, _k, 1);
1563
- __decorateClass([
1564
- aConcept.A_Feature.Extend(),
1565
- __decorateParam(0, aConcept.A_Inject(A_StateMachineTransition))
1566
- ], A_Command.prototype, _j, 1);
1567
- __decorateClass([
1568
- aConcept.A_Feature.Extend(),
1569
- __decorateParam(0, aConcept.A_Inject(A_StateMachineTransition))
1570
- ], A_Command.prototype, _i, 1);
1571
- __decorateClass([
1572
- aConcept.A_Feature.Extend(),
1573
- __decorateParam(0, aConcept.A_Inject(A_StateMachineTransition))
1574
- ], A_Command.prototype, _h, 1);
1575
- __decorateClass([
1576
- aConcept.A_Feature.Extend(),
1577
- __decorateParam(0, aConcept.A_Inject(A_StateMachineTransition)),
1578
- __decorateParam(1, aConcept.A_Inject(aConcept.A_Error))
1579
- ], A_Command.prototype, _g, 1);
1580
- __decorateClass([
1581
- aConcept.A_Feature.Extend(),
1582
- __decorateParam(0, aConcept.A_Inject(A_StateMachine))
1583
- ], A_Command.prototype, _f, 1);
1584
- __decorateClass([
1585
- aConcept.A_Feature.Extend({
1586
- after: /.*/
1587
- }),
1588
- __decorateParam(0, aConcept.A_Dependency.Required()),
1589
- __decorateParam(0, aConcept.A_Inject(A_StateMachine))
1590
- ], A_Command.prototype, _e, 1);
1591
- __decorateClass([
1592
- aConcept.A_Feature.Extend()
1593
- ], A_Command.prototype, _d2, 1);
1594
- __decorateClass([
1595
- aConcept.A_Feature.Extend()
1596
- ], A_Command.prototype, _c2, 1);
1597
- __decorateClass([
1598
- aConcept.A_Feature.Extend({
1599
- after: /.*/
1600
- }),
1601
- __decorateParam(0, aConcept.A_Inject(A_StateMachine))
1602
- ], A_Command.prototype, _b2, 1);
1603
- __decorateClass([
1604
- aConcept.A_Feature.Extend({
1605
- after: /.*/
1606
- }),
1607
- __decorateParam(0, aConcept.A_Dependency.Required()),
1608
- __decorateParam(0, aConcept.A_Inject(A_StateMachine)),
1609
- __decorateParam(1, aConcept.A_Inject(A_OperationContext))
1610
- ], A_Command.prototype, _a2, 1);
1611
- var A_FSPolyfillClass = class {
1612
- constructor(logger) {
1613
- this.logger = logger;
1614
- this._initialized = false;
1615
- }
1616
- get isInitialized() {
1617
- return this._initialized;
1618
- }
1619
- async get() {
1620
- if (!this._initialized) {
1621
- await this.init();
1622
- }
1623
- return this._fs;
1624
- }
1625
- async init() {
1626
- try {
1627
- if (aConcept.A_Context.environment === "server") {
1628
- await this.initServer();
1629
- } else {
1630
- this.initBrowser();
1631
- }
1632
- this._initialized = true;
1633
- } catch (error) {
1634
- this.initBrowser();
1635
- this._initialized = true;
1636
- }
1637
- }
1638
- async initServer() {
1639
- this._fs = await import('fs');
1640
- }
1641
- initBrowser() {
1642
- this._fs = {
1643
- readFileSync: (path, encoding) => {
1644
- this.logger.warning("fs.readFileSync not available in browser environment");
1645
- return "";
1646
- },
1647
- existsSync: (path) => {
1648
- this.logger.warning("fs.existsSync not available in browser environment");
1649
- return false;
1650
- },
1651
- createReadStream: (path) => {
1652
- this.logger.warning("fs.createReadStream not available in browser environment");
1653
- return null;
1654
- }
1655
- };
1656
- }
1657
- };
1658
- var A_CryptoPolyfillClass = class {
1659
- constructor(logger) {
1660
- this.logger = logger;
1661
- this._initialized = false;
1662
- }
1663
- get isInitialized() {
1664
- return this._initialized;
1665
- }
1666
- async get(fsPolyfill) {
1667
- if (!this._initialized) {
1668
- this._fsPolyfill = fsPolyfill;
1669
- await this.init();
1670
- }
1671
- return this._crypto;
1672
- }
1673
- async init() {
1674
- try {
1675
- if (aConcept.A_Context.environment === "server") {
1676
- await this.initServer();
1677
- } else {
1678
- this.initBrowser();
1679
- }
1680
- this._initialized = true;
1681
- } catch (error) {
1682
- this.initBrowser();
1683
- this._initialized = true;
1684
- }
1685
- }
1686
- async initServer() {
1687
- const crypto2 = await import('crypto');
1688
- this._crypto = {
1689
- createTextHash: (text, algorithm = "sha384") => Promise.resolve(
1690
- `${algorithm}-${crypto2.createHash(algorithm).update(text).digest("base64")}`
1691
- ),
1692
- createFileHash: (filePath, algorithm = "sha384") => new Promise(async (resolve, reject) => {
1693
- try {
1694
- if (!this._fsPolyfill) {
1695
- throw new Error("FS polyfill is required for file hashing");
1696
- }
1697
- const hash = crypto2.createHash(algorithm);
1698
- const fileStream = this._fsPolyfill.createReadStream(filePath);
1699
- fileStream.on("data", (data) => hash.update(data));
1700
- fileStream.on("end", () => resolve(`${algorithm}-${hash.digest("base64")}`));
1701
- fileStream.on("error", (err) => reject(err));
1702
- } catch (error) {
1703
- reject(error);
1704
- }
1705
- })
1706
- };
1707
- }
1708
- initBrowser() {
1709
- this._crypto = {
1710
- createFileHash: () => {
1711
- this.logger.warning("File hash not available in browser environment");
1712
- return Promise.resolve("");
1713
- },
1714
- createTextHash: (text, algorithm = "SHA-384") => new Promise(async (resolve, reject) => {
1715
- try {
1716
- if (!crypto.subtle) {
1717
- throw new Error("SubtleCrypto not available");
1718
- }
1719
- const encoder = new TextEncoder();
1720
- const data = encoder.encode(text);
1721
- const hashBuffer = await crypto.subtle.digest(algorithm, data);
1722
- const hashArray = Array.from(new Uint8Array(hashBuffer));
1723
- const hashBase64 = btoa(String.fromCharCode(...hashArray));
1724
- resolve(`${algorithm}-${hashBase64}`);
1725
- } catch (error) {
1726
- reject(error);
1727
- }
1728
- })
1729
- };
1730
- }
1731
- };
1732
- var A_HttpPolyfillClass = class {
1733
- constructor(logger) {
1734
- this.logger = logger;
1735
- this._initialized = false;
1736
- }
1737
- get isInitialized() {
1738
- return this._initialized;
1739
- }
1740
- async get() {
1741
- if (!this._initialized) {
1742
- await this.init();
1743
- }
1744
- return this._http;
1745
- }
1746
- async init() {
1747
- try {
1748
- if (aConcept.A_Context.environment === "server") {
1749
- await this.initServer();
1750
- } else {
1751
- this.initBrowser();
1752
- }
1753
- this._initialized = true;
1754
- } catch (error) {
1755
- this.initBrowser();
1756
- this._initialized = true;
1757
- }
1758
- }
1759
- async initServer() {
1760
- const httpModule = await import('http');
1761
- this._http = {
1762
- request: httpModule.request,
1763
- get: httpModule.get,
1764
- createServer: httpModule.createServer
1765
- };
1766
- }
1767
- initBrowser() {
1768
- this._http = {
1769
- request: (options, callback) => {
1770
- this.logger.warning("http.request not available in browser/test environment, use fetch instead");
1771
- return this.createMockRequest(options, callback, false);
1772
- },
1773
- get: (url, callback) => {
1774
- this.logger.warning("http.get not available in browser/test environment, use fetch instead");
1775
- return this.createMockRequest(typeof url === "string" ? { hostname: url } : url, callback, false);
1776
- },
1777
- createServer: () => {
1778
- this.logger.error("http.createServer not available in browser/test environment");
1779
- return null;
1780
- }
1781
- };
1782
- }
1783
- createMockRequest(options, callback, isHttps = false) {
1784
- const request = {
1785
- end: () => {
1786
- if (callback) {
1787
- const mockResponse = {
1788
- statusCode: 200,
1789
- headers: {},
1790
- on: (event, handler) => {
1791
- if (event === "data") {
1792
- setTimeout(() => handler("mock data"), 0);
1793
- } else if (event === "end") {
1794
- setTimeout(() => handler(), 0);
1795
- }
1796
- },
1797
- pipe: (dest) => {
1798
- if (dest.write) dest.write("mock data");
1799
- if (dest.end) dest.end();
1800
- }
1801
- };
1802
- setTimeout(() => callback(mockResponse), 0);
1803
- }
1804
- },
1805
- write: (data) => {
1806
- },
1807
- on: (event, handler) => {
1808
- }
1809
- };
1810
- return request;
1811
- }
1812
- };
1813
- var A_HttpsPolyfillClass = class {
1814
- constructor(logger) {
1815
- this.logger = logger;
1816
- this._initialized = false;
1817
- }
1818
- get isInitialized() {
1819
- return this._initialized;
1820
- }
1821
- async get() {
1822
- if (!this._initialized) {
1823
- await this.init();
1824
- }
1825
- return this._https;
1826
- }
1827
- async init() {
1828
- try {
1829
- if (aConcept.A_Context.environment === "server") {
1830
- await this.initServer();
1831
- } else {
1832
- this.initBrowser();
1833
- }
1834
- this._initialized = true;
1835
- } catch (error) {
1836
- this.initBrowser();
1837
- this._initialized = true;
1838
- }
1839
- }
1840
- async initServer() {
1841
- const httpsModule = await import('https');
1842
- this._https = {
1843
- request: httpsModule.request,
1844
- get: httpsModule.get,
1845
- createServer: httpsModule.createServer
1846
- };
1847
- }
1848
- initBrowser() {
1849
- this._https = {
1850
- request: (options, callback) => {
1851
- this.logger.warning("https.request not available in browser/test environment, use fetch instead");
1852
- return this.createMockRequest(options, callback, true);
1853
- },
1854
- get: (url, callback) => {
1855
- this.logger.warning("https.get not available in browser/test environment, use fetch instead");
1856
- return this.createMockRequest(typeof url === "string" ? { hostname: url } : url, callback, true);
1857
- },
1858
- createServer: () => {
1859
- this.logger.error("https.createServer not available in browser/test environment");
1860
- return null;
1861
- }
1862
- };
1863
- }
1864
- createMockRequest(options, callback, isHttps = true) {
1865
- const request = {
1866
- end: () => {
1867
- if (callback) {
1868
- const mockResponse = {
1869
- statusCode: 200,
1870
- headers: {},
1871
- on: (event, handler) => {
1872
- if (event === "data") {
1873
- setTimeout(() => handler("mock data"), 0);
1874
- } else if (event === "end") {
1875
- setTimeout(() => handler(), 0);
1876
- }
1877
- },
1878
- pipe: (dest) => {
1879
- if (dest.write) dest.write("mock data");
1880
- if (dest.end) dest.end();
1881
- }
1882
- };
1883
- setTimeout(() => callback(mockResponse), 0);
1884
- }
1885
- },
1886
- write: (data) => {
1887
- },
1888
- on: (event, handler) => {
1889
- }
1890
- };
1891
- return request;
1892
- }
1893
- };
1894
- var A_PathPolyfillClass = class {
1895
- constructor(logger) {
1896
- this.logger = logger;
1897
- this._initialized = false;
1898
- }
1899
- get isInitialized() {
1900
- return this._initialized;
1901
- }
1902
- async get() {
1903
- if (!this._initialized) {
1904
- await this.init();
1905
- }
1906
- return this._path;
1907
- }
1908
- async init() {
1909
- try {
1910
- if (aConcept.A_Context.environment === "server") {
1911
- await this.initServer();
1912
- } else {
1913
- this.initBrowser();
1914
- }
1915
- this._initialized = true;
1916
- } catch (error) {
1917
- this.initBrowser();
1918
- this._initialized = true;
1919
- }
1920
- }
1921
- async initServer() {
1922
- this._path = await import('path');
1923
- }
1924
- initBrowser() {
1925
- this._path = {
1926
- join: (...paths) => {
1927
- return paths.join("/").replace(/\/+/g, "/");
1928
- },
1929
- resolve: (...paths) => {
1930
- let resolvedPath = "";
1931
- for (const path of paths) {
1932
- if (path.startsWith("/")) {
1933
- resolvedPath = path;
1934
- } else {
1935
- resolvedPath = this._path.join(resolvedPath, path);
1936
- }
1937
- }
1938
- return resolvedPath || "/";
1939
- },
1940
- dirname: (path) => {
1941
- const parts = path.split("/");
1942
- return parts.slice(0, -1).join("/") || "/";
1943
- },
1944
- basename: (path, ext) => {
1945
- const base = path.split("/").pop() || "";
1946
- return ext && base.endsWith(ext) ? base.slice(0, -ext.length) : base;
1947
- },
1948
- extname: (path) => {
1949
- const parts = path.split(".");
1950
- return parts.length > 1 ? "." + parts.pop() : "";
1951
- },
1952
- relative: (from, to) => {
1953
- return to.replace(from, "").replace(/^\//, "");
1954
- },
1955
- normalize: (path) => {
1956
- return path.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
1957
- },
1958
- isAbsolute: (path) => {
1959
- return path.startsWith("/") || /^[a-zA-Z]:/.test(path);
1960
- },
1961
- parse: (path) => {
1962
- const ext = this._path.extname(path);
1963
- const base = this._path.basename(path);
1964
- const name = this._path.basename(path, ext);
1965
- const dir = this._path.dirname(path);
1966
- return { root: "/", dir, base, ext, name };
1967
- },
1968
- format: (pathObject) => {
1969
- return this._path.join(pathObject.dir || "", pathObject.base || "");
1970
- },
1971
- sep: "/",
1972
- delimiter: ":"
1973
- };
1974
- }
1975
- };
1976
- var A_UrlPolyfillClass = class {
1977
- constructor(logger) {
1978
- this.logger = logger;
1979
- this._initialized = false;
1980
- }
1981
- get isInitialized() {
1982
- return this._initialized;
1983
- }
1984
- async get() {
1985
- if (!this._initialized) {
1986
- await this.init();
1987
- }
1988
- return this._url;
1989
- }
1990
- async init() {
1991
- try {
1992
- if (aConcept.A_Context.environment === "server") {
1993
- await this.initServer();
1994
- } else {
1995
- this.initBrowser();
1996
- }
1997
- this._initialized = true;
1998
- } catch (error) {
1999
- this.initBrowser();
2000
- this._initialized = true;
2001
- }
2002
- }
2003
- async initServer() {
2004
- const urlModule = await import('url');
2005
- this._url = {
2006
- parse: urlModule.parse,
2007
- format: urlModule.format,
2008
- resolve: urlModule.resolve,
2009
- URL: urlModule.URL || globalThis.URL,
2010
- URLSearchParams: urlModule.URLSearchParams || globalThis.URLSearchParams
2011
- };
2012
- }
2013
- initBrowser() {
2014
- this._url = {
2015
- parse: (urlString) => {
2016
- try {
2017
- const url = new URL(urlString);
2018
- return {
2019
- protocol: url.protocol,
2020
- hostname: url.hostname,
2021
- port: url.port,
2022
- pathname: url.pathname,
2023
- search: url.search,
2024
- hash: url.hash,
2025
- host: url.host,
2026
- href: url.href
2027
- };
2028
- } catch {
2029
- return {};
2030
- }
2031
- },
2032
- format: (urlObject) => {
2033
- try {
2034
- return new URL("", urlObject.href || `${urlObject.protocol}//${urlObject.host}${urlObject.pathname}${urlObject.search}${urlObject.hash}`).href;
2035
- } catch {
2036
- return "";
2037
- }
2038
- },
2039
- resolve: (from, to) => {
2040
- try {
2041
- return new URL(to, from).href;
2042
- } catch {
2043
- return to;
2044
- }
2045
- },
2046
- URL: globalThis.URL,
2047
- URLSearchParams: globalThis.URLSearchParams
2048
- };
2049
- }
2050
- };
2051
- var A_BufferPolyfillClass = class {
2052
- constructor(logger) {
2053
- this.logger = logger;
2054
- this._initialized = false;
2055
- }
2056
- get isInitialized() {
2057
- return this._initialized;
2058
- }
2059
- async get() {
2060
- if (!this._initialized) {
2061
- await this.init();
2062
- }
2063
- return this._buffer;
2064
- }
2065
- async init() {
2066
- try {
2067
- if (aConcept.A_Context.environment === "server") {
2068
- await this.initServer();
2069
- } else {
2070
- this.initBrowser();
2071
- }
2072
- this._initialized = true;
2073
- } catch (error) {
2074
- this.initBrowser();
2075
- this._initialized = true;
2076
- }
2077
- }
2078
- async initServer() {
2079
- const bufferModule = await import('buffer');
2080
- this._buffer = {
2081
- from: bufferModule.Buffer.from,
2082
- alloc: bufferModule.Buffer.alloc,
2083
- allocUnsafe: bufferModule.Buffer.allocUnsafe,
2084
- isBuffer: bufferModule.Buffer.isBuffer,
2085
- concat: bufferModule.Buffer.concat
2086
- };
2087
- }
2088
- initBrowser() {
2089
- this._buffer = {
2090
- from: (data, encoding) => {
2091
- if (typeof data === "string") {
2092
- return new TextEncoder().encode(data);
2093
- }
2094
- return new Uint8Array(data);
2095
- },
2096
- alloc: (size, fill) => {
2097
- const buffer = new Uint8Array(size);
2098
- if (fill !== void 0) {
2099
- buffer.fill(fill);
2100
- }
2101
- return buffer;
2102
- },
2103
- allocUnsafe: (size) => {
2104
- return new Uint8Array(size);
2105
- },
2106
- isBuffer: (obj) => {
2107
- return obj instanceof Uint8Array || obj instanceof ArrayBuffer;
2108
- },
2109
- concat: (list, totalLength) => {
2110
- const length = totalLength || list.reduce((sum, buf) => sum + buf.length, 0);
2111
- const result = new Uint8Array(length);
2112
- let offset = 0;
2113
- for (const buf of list) {
2114
- result.set(buf, offset);
2115
- offset += buf.length;
2116
- }
2117
- return result;
2118
- }
2119
- };
2120
- }
2121
- };
2122
- var A_ProcessPolyfillClass = class {
2123
- constructor(logger) {
2124
- this.logger = logger;
2125
- this._initialized = false;
2126
- }
2127
- get isInitialized() {
2128
- return this._initialized;
2129
- }
2130
- async get() {
2131
- if (!this._initialized) {
2132
- await this.init();
2133
- }
2134
- return this._process;
2135
- }
2136
- async init() {
2137
- try {
2138
- if (aConcept.A_Context.environment === "server") {
2139
- this.initServer();
2140
- } else {
2141
- this.initBrowser();
2142
- }
2143
- this._initialized = true;
2144
- } catch (error) {
2145
- this.initBrowser();
2146
- this._initialized = true;
2147
- }
2148
- }
2149
- initServer() {
2150
- this._process = {
2151
- env: process.env,
2152
- argv: process.argv,
2153
- platform: process.platform,
2154
- version: process.version,
2155
- versions: process.versions,
2156
- cwd: process.cwd,
2157
- exit: process.exit,
2158
- nextTick: process.nextTick
2159
- };
2160
- }
2161
- initBrowser() {
2162
- this._process = {
2163
- env: {
2164
- NODE_ENV: "browser",
2165
- ...globalThis.process?.env || {}
2166
- },
2167
- argv: ["browser"],
2168
- platform: "browser",
2169
- version: "browser",
2170
- versions: { node: "browser" },
2171
- cwd: () => "/",
2172
- exit: (code) => {
2173
- this.logger.warning("process.exit not available in browser");
2174
- throw new Error(`Process exit with code ${code}`);
2175
- },
2176
- nextTick: (callback, ...args) => {
2177
- setTimeout(() => callback(...args), 0);
2178
- }
2179
- };
2180
- }
2181
- };
2182
-
2183
- // src/lib/A-Polyfill/A-Polyfill.component.ts
2184
- exports.A_Polyfill = class A_Polyfill extends aConcept.A_Component {
2185
- constructor(logger) {
2186
- super();
2187
- this.logger = logger;
2188
- this._initializing = null;
2189
- }
2190
- /**
2191
- * Indicates whether the channel is connected
2192
- */
2193
- get ready() {
2194
- if (!this._initialized) {
2195
- this._initialized = this._loadInternal();
2196
- }
2197
- return this._initialized;
2198
- }
2199
- async load() {
2200
- await this.ready;
2201
- }
2202
- async attachToWindow() {
2203
- if (aConcept.A_Context.environment !== "browser") return;
2204
- globalThis.A_Polyfill = this;
2205
- globalThis.process = { env: { NODE_ENV: "production" }, cwd: () => "/" };
2206
- globalThis.__dirname = "/";
2207
- }
2208
- async _loadInternal() {
2209
- this._fsPolyfill = new A_FSPolyfillClass(this.logger);
2210
- this._cryptoPolyfill = new A_CryptoPolyfillClass(this.logger);
2211
- this._httpPolyfill = new A_HttpPolyfillClass(this.logger);
2212
- this._httpsPolyfill = new A_HttpsPolyfillClass(this.logger);
2213
- this._pathPolyfill = new A_PathPolyfillClass(this.logger);
2214
- this._urlPolyfill = new A_UrlPolyfillClass(this.logger);
2215
- this._bufferPolyfill = new A_BufferPolyfillClass(this.logger);
2216
- this._processPolyfill = new A_ProcessPolyfillClass(this.logger);
2217
- await this._fsPolyfill.get();
2218
- await this._cryptoPolyfill.get(await this._fsPolyfill.get());
2219
- await this._httpPolyfill.get();
2220
- await this._httpsPolyfill.get();
2221
- await this._pathPolyfill.get();
2222
- await this._urlPolyfill.get();
2223
- await this._bufferPolyfill.get();
2224
- await this._processPolyfill.get();
2225
- }
2226
- /**
2227
- * Allows to use the 'fs' polyfill methods regardless of the environment
2228
- * This method loads the 'fs' polyfill and returns its instance
2229
- *
2230
- * @returns
2231
- */
2232
- async fs() {
2233
- await this.ready;
2234
- return await this._fsPolyfill.get();
2235
- }
2236
- /**
2237
- * Allows to use the 'crypto' polyfill methods regardless of the environment
2238
- * This method loads the 'crypto' polyfill and returns its instance
2239
- *
2240
- * @returns
2241
- */
2242
- async crypto() {
2243
- await this.ready;
2244
- return await this._cryptoPolyfill.get();
2245
- }
2246
- /**
2247
- * Allows to use the 'http' polyfill methods regardless of the environment
2248
- * This method loads the 'http' polyfill and returns its instance
2249
- *
2250
- * @returns
2251
- */
2252
- async http() {
2253
- await this.ready;
2254
- return await this._httpPolyfill.get();
2255
- }
2256
- /**
2257
- * Allows to use the 'https' polyfill methods regardless of the environment
2258
- * This method loads the 'https' polyfill and returns its instance
2259
- *
2260
- * @returns
2261
- */
2262
- async https() {
2263
- await this.ready;
2264
- return await this._httpsPolyfill.get();
2265
- }
2266
- /**
2267
- * Allows to use the 'path' polyfill methods regardless of the environment
2268
- * This method loads the 'path' polyfill and returns its instance
2269
- *
2270
- * @returns
2271
- */
2272
- async path() {
2273
- await this.ready;
2274
- return await this._pathPolyfill.get();
2275
- }
2276
- /**
2277
- * Allows to use the 'url' polyfill methods regardless of the environment
2278
- * This method loads the 'url' polyfill and returns its instance
2279
- *
2280
- * @returns
2281
- */
2282
- async url() {
2283
- await this.ready;
2284
- return await this._urlPolyfill.get();
2285
- }
2286
- /**
2287
- * Allows to use the 'buffer' polyfill methods regardless of the environment
2288
- * This method loads the 'buffer' polyfill and returns its instance
2289
- *
2290
- * @returns
2291
- */
2292
- async buffer() {
2293
- await this.ready;
2294
- return await this._bufferPolyfill.get();
2295
- }
2296
- /**
2297
- * Allows to use the 'process' polyfill methods regardless of the environment
2298
- * This method loads the 'process' polyfill and returns its instance
2299
- *
2300
- * @returns
2301
- */
2302
- async process() {
2303
- await this.ready;
2304
- return await this._processPolyfill.get();
2305
- }
2306
- };
2307
- __decorateClass([
2308
- aConcept.A_Concept.Load()
2309
- ], exports.A_Polyfill.prototype, "load", 1);
2310
- __decorateClass([
2311
- aConcept.A_Concept.Load()
2312
- ], exports.A_Polyfill.prototype, "attachToWindow", 1);
2313
- exports.A_Polyfill = __decorateClass([
2314
- __decorateParam(0, aConcept.A_Inject(exports.A_Logger))
2315
- ], exports.A_Polyfill);
2316
- var A_ConfigError = class extends aConcept.A_Error {
2317
- };
2318
- A_ConfigError.InitializationError = "A-Config Initialization Error";
2319
- exports.ConfigReader = class ConfigReader extends aConcept.A_Component {
2320
- constructor(polyfill) {
2321
- super();
2322
- this.polyfill = polyfill;
2323
- }
2324
- async attachContext(container, feature, config) {
2325
- if (!config) {
2326
- config = new A_Config({
2327
- variables: [
2328
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
2329
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
2330
- ],
2331
- defaults: {}
2332
- });
2333
- container.scope.register(config);
2334
- }
2335
- const rootDir = await this.getProjectRoot();
2336
- config.set("A_CONCEPT_ROOT_FOLDER", rootDir);
2337
- }
2338
- async initialize(config) {
2339
- const data = await this.read([
2340
- ...config.CONFIG_PROPERTIES,
2341
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
2342
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
2343
- ]);
2344
- config.set(data);
2345
- }
2346
- /**
2347
- * Get the configuration property by Name
2348
- * @param property
2349
- */
2350
- resolve(property) {
2351
- return property;
2352
- }
2353
- /**
2354
- * This method reads the configuration and sets the values to the context
2355
- *
2356
- * @returns
2357
- */
2358
- async read(variables = []) {
2359
- return {};
2360
- }
2361
- /**
2362
- * Finds the root directory of the project by locating the folder containing package.json
2363
- *
2364
- * @param {string} startPath - The initial directory to start searching from (default is __dirname)
2365
- * @returns {string|null} - The path to the root directory or null if package.json is not found
2366
- */
2367
- async getProjectRoot(startPath = __dirname) {
2368
- return process.cwd();
2369
- }
2370
- };
2371
- __decorateClass([
2372
- aConcept.A_Concept.Load(),
2373
- __decorateParam(0, aConcept.A_Inject(aConcept.A_Container)),
2374
- __decorateParam(1, aConcept.A_Inject(aConcept.A_Feature)),
2375
- __decorateParam(2, aConcept.A_Inject(A_Config))
2376
- ], exports.ConfigReader.prototype, "attachContext", 1);
2377
- __decorateClass([
2378
- aConcept.A_Concept.Load(),
2379
- __decorateParam(0, aConcept.A_Inject(A_Config))
2380
- ], exports.ConfigReader.prototype, "initialize", 1);
2381
- exports.ConfigReader = __decorateClass([
2382
- __decorateParam(0, aConcept.A_Inject(exports.A_Polyfill))
2383
- ], exports.ConfigReader);
2384
-
2385
- // src/lib/A-Config/components/FileConfigReader.component.ts
2386
- var FileConfigReader = class extends exports.ConfigReader {
2387
- constructor() {
2388
- super(...arguments);
2389
- this.FileData = /* @__PURE__ */ new Map();
2390
- }
2391
- /**
2392
- * Get the configuration property Name
2393
- * @param property
2394
- */
2395
- getConfigurationProperty_File_Alias(property) {
2396
- return aConcept.A_FormatterHelper.toCamelCase(property);
2397
- }
2398
- resolve(property) {
2399
- return this.FileData.get(this.getConfigurationProperty_File_Alias(property));
2400
- }
2401
- async read(variables) {
2402
- const fs = await this.polyfill.fs();
2403
- try {
2404
- const data = fs.readFileSync(`${aConcept.A_Context.concept}.conf.json`, "utf8");
2405
- const config = JSON.parse(data);
2406
- this.FileData = new Map(Object.entries(config));
2407
- return config;
2408
- } catch (error) {
2409
- return {};
2410
- }
2411
- }
2412
- };
2413
- var ENVConfigReader = class extends exports.ConfigReader {
2414
- async readEnvFile(config, polyfill, feature) {
2415
- const fs = await polyfill.fs();
2416
- if (fs.existsSync(".env"))
2417
- fs.readFileSync(`${config.get("A_CONCEPT_ROOT_FOLDER")}/.env`, "utf-8").split("\n").forEach((line) => {
2418
- const [key, value] = line.split("=");
2419
- if (key && value) {
2420
- process.env[key.trim()] = value.trim();
2421
- }
2422
- });
2423
- }
2424
- /**
2425
- * Get the configuration property Name
2426
- * @param property
2427
- */
2428
- getConfigurationProperty_ENV_Alias(property) {
2429
- return aConcept.A_FormatterHelper.toUpperSnakeCase(property);
2430
- }
2431
- resolve(property) {
2432
- return process.env[this.getConfigurationProperty_ENV_Alias(property)];
2433
- }
2434
- async read(variables = []) {
2435
- const allVariables = [
2436
- ...variables,
2437
- ...Object.keys(process.env)
2438
- ];
2439
- const config = {};
2440
- allVariables.forEach((variable) => {
2441
- config[variable] = this.resolve(variable);
2442
- });
2443
- return config;
2444
- }
2445
- };
2446
- __decorateClass([
2447
- aConcept.A_Concept.Load({
2448
- before: ["ENVConfigReader.initialize"]
2449
- }),
2450
- __decorateParam(0, aConcept.A_Inject(A_Config)),
2451
- __decorateParam(1, aConcept.A_Inject(exports.A_Polyfill)),
2452
- __decorateParam(2, aConcept.A_Inject(aConcept.A_Feature))
2453
- ], ENVConfigReader.prototype, "readEnvFile", 1);
2454
-
2455
- // src/lib/A-Config/A-Config.container.ts
2456
- var A_ConfigLoader = class extends aConcept.A_Container {
2457
- async prepare(polyfill) {
2458
- if (!this.scope.has(A_Config)) {
2459
- const newConfig = new A_Config({
2460
- variables: [
2461
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
2462
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
2463
- ],
2464
- defaults: {}
2465
- });
2466
- this.scope.register(newConfig);
2467
- }
2468
- const fs = await polyfill.fs();
2469
- try {
2470
- switch (true) {
2471
- case (aConcept.A_Context.environment === "server" && !!fs.existsSync(`${aConcept.A_Context.concept}.conf.json`)):
2472
- this.reader = this.scope.resolve(FileConfigReader);
2473
- break;
2474
- case (aConcept.A_Context.environment === "server" && !fs.existsSync(`${aConcept.A_Context.concept}.conf.json`)):
2475
- this.reader = this.scope.resolve(ENVConfigReader);
2476
- break;
2477
- case aConcept.A_Context.environment === "browser":
2478
- this.reader = this.scope.resolve(ENVConfigReader);
2479
- break;
2480
- default:
2481
- throw new A_ConfigError(
2482
- A_ConfigError.InitializationError,
2483
- `Environment ${aConcept.A_Context.environment} is not supported`
2484
- );
2485
- }
2486
- } catch (error) {
2487
- if (error instanceof aConcept.A_ScopeError) {
2488
- throw new A_ConfigError({
2489
- title: A_ConfigError.InitializationError,
2490
- description: `Failed to initialize A_ConfigLoader. Reader not found for environment ${aConcept.A_Context.environment}`,
2491
- originalError: error
2492
- });
2493
- }
2494
- }
2495
- }
2496
- };
2497
- __decorateClass([
2498
- aConcept.A_Concept.Load({
2499
- before: /.*/
2500
- }),
2501
- __decorateParam(0, aConcept.A_Inject(exports.A_Polyfill))
2502
- ], A_ConfigLoader.prototype, "prepare", 1);
2503
-
2504
- // src/lib/A-Config/A-Config.types.ts
2505
- var A_TYPES__ConfigFeature = /* @__PURE__ */ ((A_TYPES__ConfigFeature2) => {
2506
- return A_TYPES__ConfigFeature2;
2507
- })(A_TYPES__ConfigFeature || {});
2508
- var A_ManifestError = class extends aConcept.A_Error {
2509
- };
2510
- A_ManifestError.ManifestInitializationError = "A-Manifest Initialization Error";
2511
-
2512
- // src/lib/A-Manifest/classes/A-ManifestChecker.class.ts
2513
- var A_ManifestChecker = class {
2514
- constructor(manifest, component, method, checkExclusion = false) {
2515
- this.manifest = manifest;
2516
- this.component = component;
2517
- this.method = method;
2518
- this.checkExclusion = checkExclusion;
2519
- }
2520
- for(target) {
2521
- const result = this.manifest.internal_checkAccess({
2522
- component: this.component,
2523
- method: this.method,
2524
- target
2525
- });
2526
- return this.checkExclusion ? !result : result;
2527
- }
2528
- };
2529
-
2530
- // src/lib/A-Manifest/A-Manifest.context.ts
2531
- var A_Manifest = class extends aConcept.A_Fragment {
2532
- /**
2533
- * A-Manifest is a configuration set that allows to include or exclude component application for the particular methods.
2534
- *
2535
- * For example, if A-Scope provides polymorphic A-Component that applies for All A-Entities in it but you have another component that should be used for only One particular Entity, you can use A-Manifest to specify this behavior.
2536
- *
2537
- *
2538
- * By default if Component is provided in the scope - it applies for all entities in it. However, if you want to exclude some entities or include only some entities for the particular component - you can use A-Manifest to define this behavior.
2539
- *
2540
- * @param config - Array of component configurations
2541
- */
2542
- constructor(config = []) {
2543
- super({
2544
- name: "A-Manifest"
2545
- });
2546
- this.rules = [];
2547
- this.prepare(config);
2548
- }
2549
- /**
2550
- * Should convert received configuration into internal Regexp applicable for internal storage
2551
- */
2552
- prepare(config) {
2553
- if (!aConcept.A_TypeGuards.isArray(config))
2554
- throw new A_ManifestError(
2555
- A_ManifestError.ManifestInitializationError,
2556
- `A-Manifest configuration should be an array of configurations`
2557
- );
2558
- for (const item of config) {
2559
- this.processConfigItem(item);
2560
- }
2561
- }
2562
- /**
2563
- * Process a single configuration item and convert it to internal rules
2564
- */
2565
- processConfigItem(item) {
2566
- if (!aConcept.A_TypeGuards.isComponentConstructor(item.component))
2567
- throw new A_ManifestError(
2568
- A_ManifestError.ManifestInitializationError,
2569
- `A-Manifest configuration item should be a A-Component constructor`
2570
- );
2571
- const componentRegex = this.constructorToRegex(item.component);
2572
- if (item.apply || item.exclude) {
2573
- const methodRegex = /.*/;
2574
- this.rules.push({
2575
- componentRegex,
2576
- methodRegex,
2577
- applyRegex: item.apply ? this.allowedComponentsToRegex(item.apply) : void 0,
2578
- excludeRegex: item.exclude ? this.allowedComponentsToRegex(item.exclude) : void 0
2579
- });
2580
- }
2581
- if (item.methods && item.methods.length > 0) {
2582
- for (const methodConfig of item.methods) {
2583
- const methodRegex = this.methodToRegex(methodConfig.method);
2584
- this.rules.push({
2585
- componentRegex,
2586
- methodRegex,
2587
- applyRegex: methodConfig.apply ? this.allowedComponentsToRegex(methodConfig.apply) : void 0,
2588
- excludeRegex: methodConfig.exclude ? this.allowedComponentsToRegex(methodConfig.exclude) : void 0
2589
- });
2590
- }
2591
- }
2592
- }
2593
- /**
2594
- * Convert a constructor to a regex pattern
2595
- */
2596
- constructorToRegex(ctor) {
2597
- return new RegExp(`^${this.escapeRegex(ctor.name)}$`);
2598
- }
2599
- /**
2600
- * Convert a method name or regex to a regex pattern
2601
- */
2602
- methodToRegex(method) {
2603
- if (method instanceof RegExp) {
2604
- return method;
2605
- }
2606
- return new RegExp(`^${this.escapeRegex(method)}$`);
2607
- }
2608
- /**
2609
- * Convert allowed components array or regex to a single regex
2610
- */
2611
- allowedComponentsToRegex(components) {
2612
- if (components instanceof RegExp) {
2613
- return components;
2614
- }
2615
- const patterns = components.map((ctor) => this.escapeRegex(ctor.name));
2616
- return new RegExp(`^(${patterns.join("|")})$`);
2617
- }
2618
- /**
2619
- * Escape special regex characters in a string
2620
- */
2621
- escapeRegex(str) {
2622
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2623
- }
2624
- configItemToRegexp(item) {
2625
- return this.constructorToRegex(item);
2626
- }
2627
- ID(component, method) {
2628
- return `${component.name}.${method}`;
2629
- }
2630
- /**
2631
- * Check if a component and method combination is allowed for a target
2632
- */
2633
- isAllowed(ctor, method) {
2634
- const componentCtor = typeof ctor === "function" ? ctor : ctor.constructor;
2635
- return new A_ManifestChecker(this, componentCtor, method);
2636
- }
2637
- /**
2638
- * Internal method to check if access is allowed
2639
- */
2640
- internal_checkAccess(query) {
2641
- const componentName = query.component.name;
2642
- const methodName = query.method;
2643
- const targetName = query.target.name;
2644
- const matchingRules = this.rules.filter(
2645
- (rule) => rule.componentRegex.test(componentName) && rule.methodRegex.test(methodName)
2646
- ).sort((a, b) => {
2647
- const aIsGeneral = a.methodRegex.source === ".*";
2648
- const bIsGeneral = b.methodRegex.source === ".*";
2649
- if (aIsGeneral && !bIsGeneral) return 1;
2650
- if (!aIsGeneral && bIsGeneral) return -1;
2651
- return 0;
2652
- });
2653
- if (matchingRules.length === 0) {
2654
- return true;
2655
- }
2656
- for (const rule of matchingRules) {
2657
- if (rule.excludeRegex && rule.excludeRegex.test(targetName)) {
2658
- return false;
2659
- }
2660
- if (rule.applyRegex) {
2661
- return rule.applyRegex.test(targetName);
2662
- }
2663
- }
2664
- return true;
2665
- }
2666
- isExcluded(ctor, method) {
2667
- const componentCtor = typeof ctor === "function" ? ctor : ctor.constructor;
2668
- return new A_ManifestChecker(this, componentCtor, method, true);
2669
- }
2670
- };
2671
- var A_MemoryContext = class extends aConcept.A_Fragment {
2672
- set(param, value) {
2673
- super.set(param, value);
2674
- }
2675
- get(param) {
2676
- return super.get(param);
2677
- }
2678
- };
2679
- var A_MemoryError = class extends aConcept.A_Error {
2680
- };
2681
- A_MemoryError.MemoryInitializationError = "Memory initialization error";
2682
- A_MemoryError.MemoryDestructionError = "Memory destruction error";
2683
- A_MemoryError.MemoryGetError = "Memory GET operation failed";
2684
- A_MemoryError.MemorySetError = "Memory SET operation failed";
2685
- A_MemoryError.MemoryDropError = "Memory DROP operation failed";
2686
- A_MemoryError.MemoryClearError = "Memory CLEAR operation failed";
2687
- A_MemoryError.MemoryHasError = "Memory HAS operation failed";
2688
- A_MemoryError.MemorySerializeError = "Memory toJSON operation failed";
2689
-
2690
- // src/lib/A-Memory/A-Memory.component.ts
2691
- var _a3, _b3, _c3, _d3, _e2, _f2, _g2, _h2, _i2;
2692
- var A_Memory = class extends aConcept.A_Component {
2693
- get ready() {
2694
- if (!this._ready) {
2695
- this._ready = this.init();
2696
- }
2697
- return this._ready;
2698
- }
2699
- /**
2700
- * Handles errors during memory operations
2701
- */
2702
- async [_i2 = "onError" /* onError */](...args) {
2703
- }
2704
- /**
2705
- * Handles memory expiration
2706
- */
2707
- async [_h2 = "onExpire" /* onExpire */](...args) {
2708
- }
2709
- /**
2710
- * Initializes the memory context
2711
- */
2712
- async [_g2 = "onInit" /* onInit */](context, ...args) {
2713
- if (!context) {
2714
- context = new A_MemoryContext();
2715
- aConcept.A_Context.scope(this).register(context);
2716
- }
2717
- }
2718
- async [_f2 = "onDestroy" /* onDestroy */](context, ...args) {
2719
- context.clear();
2720
- }
2721
- /**
2722
- * Handles the 'get' operation for retrieving a value from memory
2723
- */
2724
- async [_e2 = "onGet" /* onGet */](operation, context, ...args) {
2725
- operation.succeed(context.get(operation.params.key));
2726
- }
2727
- /**
2728
- * Handles the 'has' operation for checking existence of a key in memory
2729
- */
2730
- async [_d3 = "onHas" /* onHas */](operation, context, ...args) {
2731
- operation.succeed(context.has(operation.params.key));
2732
- }
2733
- /**
2734
- * Handles the 'set' operation for saving a value in memory
2735
- */
2736
- async [_c3 = "onSet" /* onSet */](operation, context, ...args) {
2737
- context.set(operation.params.key, operation.params.value);
2738
- }
2739
- /**
2740
- * Handles the 'drop' operation for removing a value from memory
2741
- */
2742
- async [_b3 = "onDrop" /* onDrop */](operation, context, ...args) {
2743
- context.drop(operation.params.key);
2744
- }
2745
- /**
2746
- * Handles the 'clear' operation for clearing all values from memory
2747
- */
2748
- async [_a3 = "onClear" /* onClear */](operation, context, ...args) {
2749
- context.clear();
2750
- }
2751
- // ======================================================================
2752
- // =========================A-Memory Methods=============================
2753
- // ======================================================================
2754
- /**
2755
- * Initializes the memory context
2756
- */
2757
- async init() {
2758
- if (this._ready)
2759
- return this._ready;
2760
- const scope = new aConcept.A_Scope({ name: "A-Memory-Init-Scope" }).inherit(aConcept.A_Context.scope(this));
2761
- try {
2762
- await this.call("onInit" /* onInit */, scope);
2763
- } catch (error) {
2764
- const initError = new A_MemoryError({
2765
- title: A_MemoryError.MemoryInitializationError,
2766
- description: "An error occurred during memory initialization",
2767
- originalError: error
2768
- });
2769
- scope.register(initError);
2770
- await this.call("onError" /* onError */, scope);
2771
- scope.destroy();
2772
- throw initError;
2773
- }
2774
- }
2775
- /**
2776
- * Destroys the memory context
2777
- *
2778
- * This method is responsible for cleaning up any resources
2779
- * used by the memory context and resetting its state.
2780
- */
2781
- async destroy() {
2782
- const scope = new aConcept.A_Scope({ name: "A-Memory-Destroy-Scope" }).inherit(aConcept.A_Context.scope(this));
2783
- try {
2784
- this._ready = void 0;
2785
- await this.call("onDestroy" /* onDestroy */, scope);
2786
- } catch (error) {
2787
- const destroyError = new A_MemoryError({
2788
- title: A_MemoryError.MemoryDestructionError,
2789
- description: "An error occurred during memory destruction",
2790
- originalError: error
2791
- });
2792
- scope.register(destroyError);
2793
- await this.call("onError" /* onError */, scope);
2794
- scope.destroy();
2795
- throw destroyError;
2796
- }
2797
- }
2798
- /**
2799
- * Retrieves a value from the context memory
2800
- *
2801
- * @param key - memory key to retrieve
2802
- * @returns - value associated with the key or undefined if not found
2803
- */
2804
- async get(key) {
2805
- const operation = new A_OperationContext("get", { key });
2806
- const scope = new aConcept.A_Scope({
2807
- name: "A-Memory-Get-Operation-Scope",
2808
- fragments: [operation]
2809
- });
2810
- try {
2811
- await this.call("onGet" /* onGet */, scope);
2812
- scope.destroy();
2813
- return operation.result;
2814
- } catch (error) {
2815
- const getError = new A_MemoryError({
2816
- title: A_MemoryError.MemoryGetError,
2817
- description: `An error occurred while getting the value for key "${String(key)}"`,
2818
- originalError: error
2819
- });
2820
- scope.register(getError);
2821
- await this.call("onError" /* onError */, scope);
2822
- scope.destroy();
2823
- throw getError;
2824
- }
2825
- }
2826
- /**
2827
- * Checks if a value exists in the context memory
2828
- *
2829
- * @param key - memory key to check
2830
- * @returns - true if key exists, false otherwise
2831
- */
2832
- async has(key) {
2833
- const operation = new A_OperationContext("has", { key });
2834
- const scope = new aConcept.A_Scope({
2835
- name: "A-Memory-Has-Operation-Scope",
2836
- fragments: [operation]
2837
- });
2838
- try {
2839
- await this.call("onHas" /* onHas */, scope);
2840
- scope.destroy();
2841
- return operation.result;
2842
- } catch (error) {
2843
- const getError = new A_MemoryError({
2844
- title: A_MemoryError.MemoryHasError,
2845
- description: `An error occurred while checking existence for key "${String(key)}"`,
2846
- originalError: error
2847
- });
2848
- scope.register(getError);
2849
- await this.call("onError" /* onError */, scope);
2850
- scope.destroy();
2851
- throw getError;
2852
- }
2853
- }
2854
- /**
2855
- * Saves a value in the context memory
2856
- *
2857
- * @param key
2858
- * @param value
2859
- */
2860
- async set(key, value) {
2861
- const operation = new A_OperationContext("set", { key, value });
2862
- const scope = new aConcept.A_Scope({
2863
- name: "A-Memory-Set-Operation-Scope",
2864
- fragments: [operation]
2865
- });
2866
- try {
2867
- await this.call("onSet" /* onSet */, scope);
2868
- } catch (error) {
2869
- const setError = new A_MemoryError({
2870
- title: A_MemoryError.MemorySetError,
2871
- description: `An error occurred while setting the value for key "${String(key)}"`,
2872
- originalError: error
2873
- });
2874
- scope.register(setError);
2875
- await this.call("onError" /* onError */, scope);
2876
- scope.destroy();
2877
- throw setError;
2878
- }
2879
- }
2880
- /**
2881
- * Removes a value from the context memory by key
2882
- *
2883
- * @param key
2884
- */
2885
- async drop(key) {
2886
- const operation = new A_OperationContext("drop", { key });
2887
- const scope = new aConcept.A_Scope({
2888
- name: "A-Memory-Drop-Operation-Scope",
2889
- fragments: [operation]
2890
- });
2891
- try {
2892
- await this.call("onDrop" /* onDrop */, scope);
2893
- } catch (error) {
2894
- const dropError = new A_MemoryError({
2895
- title: A_MemoryError.MemoryDropError,
2896
- description: `An error occurred while dropping the value for key "${String(key)}"`,
2897
- originalError: error
2898
- });
2899
- scope.register(dropError);
2900
- await this.call("onError" /* onError */, scope);
2901
- scope.destroy();
2902
- throw dropError;
2903
- }
2904
- }
2905
- /**
2906
- * Clears all stored values in the context memory
2907
- */
2908
- async clear() {
2909
- const operation = new A_OperationContext("clear");
2910
- const scope = new aConcept.A_Scope({
2911
- name: "A-Memory-Clear-Operation-Scope",
2912
- fragments: [operation]
2913
- });
2914
- try {
2915
- await this.call("onClear" /* onClear */, scope);
2916
- } catch (error) {
2917
- const clearError = new A_MemoryError({
2918
- title: A_MemoryError.MemoryClearError,
2919
- description: `An error occurred while clearing the memory`,
2920
- originalError: error
2921
- });
2922
- scope.register(clearError);
2923
- await this.call("onError" /* onError */, scope);
2924
- scope.destroy();
2925
- throw clearError;
2926
- }
2927
- }
2928
- /**
2929
- * Serializes the memory context to a JSON object
2930
- *
2931
- * @returns - serialized memory object
2932
- */
2933
- async toJSON() {
2934
- const operation = new A_OperationContext("serialize");
2935
- const scope = new aConcept.A_Scope({
2936
- name: "A-Memory-Serialize-Operation-Scope",
2937
- fragments: [operation]
2938
- });
2939
- try {
2940
- await this.call("onSerialize" /* onSerialize */, scope);
2941
- return operation.result;
2942
- } catch (error) {
2943
- const serializeError = new A_MemoryError({
2944
- title: A_MemoryError.MemorySerializeError,
2945
- description: `An error occurred while serializing the memory`,
2946
- originalError: error
2947
- });
2948
- scope.register(serializeError);
2949
- await this.call("onError" /* onError */, scope);
2950
- scope.destroy();
2951
- throw serializeError;
2952
- }
2953
- }
2954
- };
2955
- __decorateClass([
2956
- aConcept.A_Feature.Extend()
2957
- ], A_Memory.prototype, _i2, 1);
2958
- __decorateClass([
2959
- aConcept.A_Feature.Extend()
2960
- ], A_Memory.prototype, _h2, 1);
2961
- __decorateClass([
2962
- aConcept.A_Feature.Extend(),
2963
- __decorateParam(0, aConcept.A_Inject(A_MemoryContext))
2964
- ], A_Memory.prototype, _g2, 1);
2965
- __decorateClass([
2966
- aConcept.A_Feature.Extend(),
2967
- __decorateParam(0, aConcept.A_Inject(A_MemoryContext))
2968
- ], A_Memory.prototype, _f2, 1);
2969
- __decorateClass([
2970
- aConcept.A_Feature.Extend(),
2971
- __decorateParam(0, aConcept.A_Dependency.Required()),
2972
- __decorateParam(0, aConcept.A_Inject(A_OperationContext)),
2973
- __decorateParam(1, aConcept.A_Inject(A_MemoryContext))
2974
- ], A_Memory.prototype, _e2, 1);
2975
- __decorateClass([
2976
- aConcept.A_Feature.Extend(),
2977
- __decorateParam(0, aConcept.A_Dependency.Required()),
2978
- __decorateParam(0, aConcept.A_Inject(A_OperationContext)),
2979
- __decorateParam(1, aConcept.A_Inject(A_MemoryContext))
2980
- ], A_Memory.prototype, _d3, 1);
2981
- __decorateClass([
2982
- aConcept.A_Feature.Extend(),
2983
- __decorateParam(0, aConcept.A_Dependency.Required()),
2984
- __decorateParam(0, aConcept.A_Inject(A_OperationContext)),
2985
- __decorateParam(1, aConcept.A_Inject(A_MemoryContext))
2986
- ], A_Memory.prototype, _c3, 1);
2987
- __decorateClass([
2988
- aConcept.A_Feature.Extend(),
2989
- __decorateParam(0, aConcept.A_Dependency.Required()),
2990
- __decorateParam(0, aConcept.A_Inject(A_OperationContext)),
2991
- __decorateParam(1, aConcept.A_Inject(A_MemoryContext))
2992
- ], A_Memory.prototype, _b3, 1);
2993
- __decorateClass([
2994
- aConcept.A_Feature.Extend(),
2995
- __decorateParam(0, aConcept.A_Dependency.Required()),
2996
- __decorateParam(0, aConcept.A_Inject(A_OperationContext)),
2997
- __decorateParam(1, aConcept.A_Inject(A_MemoryContext))
2998
- ], A_Memory.prototype, _a3, 1);
2999
-
3000
- // src/lib/A-Schedule/A-Deferred.class.ts
3001
- var A_Deferred = class {
3002
- /**
3003
- * Creates a deferred promise
3004
- * @returns A promise that can be resolved or rejected later
3005
- */
3006
- constructor() {
3007
- this.promise = new Promise((resolve, reject) => {
3008
- this.resolveFn = resolve;
3009
- this.rejectFn = reject;
3010
- });
3011
- }
3012
- resolve(value) {
3013
- this.resolveFn(value);
3014
- }
3015
- reject(reason) {
3016
- this.rejectFn(reason);
3017
- }
3018
- };
3019
- var A_ScheduleObject = class {
3020
- /**
3021
- * Creates a scheduled object that will execute the action after specified milliseconds
3022
- *
3023
- *
3024
- * @param ms - milliseconds to wait before executing the action
3025
- * @param action - the action to execute
3026
- * @param config - configuration options for the schedule object
3027
- */
3028
- constructor(ms, action, config) {
3029
- this.config = {
3030
- /**
3031
- * If the timeout is cleared, should the promise resolve or reject?
3032
- * BY Default it rejects
3033
- *
3034
- * !!!NOTE: If the property is set to true, the promise will resolve with undefined
3035
- */
3036
- resolveOnClear: false
3037
- };
3038
- if (config)
3039
- this.config = { ...this.config, ...config };
3040
- this.deferred = new A_Deferred();
3041
- this.timeout = setTimeout(
3042
- () => action().then((...args) => this.deferred.resolve(...args)).catch((...args) => this.deferred.reject(...args)),
3043
- ms
3044
- );
3045
- }
3046
- get promise() {
3047
- return this.deferred.promise;
3048
- }
3049
- clear() {
3050
- if (this.timeout) {
3051
- clearTimeout(this.timeout);
3052
- if (this.config.resolveOnClear)
3053
- this.deferred.resolve(void 0);
3054
- else
3055
- this.deferred.reject(new aConcept.A_Error("Timeout Cleared"));
3056
- }
3057
- }
3058
- };
3059
-
3060
- // src/lib/A-Schedule/A-Schedule.component.ts
3061
- var A_Schedule = class extends aConcept.A_Component {
3062
- async schedule(date, callback, config) {
3063
- const timestamp = aConcept.A_TypeGuards.isString(date) ? new Date(date).getTime() : date;
3064
- return new A_ScheduleObject(
3065
- timestamp - Date.now(),
3066
- callback,
3067
- config
3068
- );
3069
- }
3070
- /**
3071
- * Allows to execute callback after particular delay in milliseconds
3072
- * So the callback will be executed after the specified delay
3073
- *
3074
- * @param ms
3075
- */
3076
- async delay(ms, callback, config) {
3077
- return new A_ScheduleObject(
3078
- ms,
3079
- callback,
3080
- config
3081
- );
3082
- }
3083
- };
3084
-
3085
- exports.A_CONSTANTS__CONFIG_ENV_VARIABLES = A_CONSTANTS__CONFIG_ENV_VARIABLES;
3086
- exports.A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY = A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY;
3087
- exports.A_Channel = A_Channel;
3088
- exports.A_ChannelError = A_ChannelError;
3089
- exports.A_ChannelFeatures = A_ChannelFeatures;
3090
- exports.A_ChannelRequestStatuses = A_ChannelRequestStatuses;
3091
- exports.A_Command = A_Command;
3092
- exports.A_CommandError = A_CommandError;
3093
- exports.A_CommandFeatures = A_CommandFeatures;
3094
- exports.A_CommandTransitions = A_CommandTransitions;
3095
- exports.A_Command_Status = A_Command_Status;
3096
- exports.A_Config = A_Config;
3097
- exports.A_ConfigError = A_ConfigError;
3098
- exports.A_ConfigLoader = A_ConfigLoader;
3099
- exports.A_Deferred = A_Deferred;
3100
- exports.A_Manifest = A_Manifest;
3101
- exports.A_ManifestChecker = A_ManifestChecker;
3102
- exports.A_ManifestError = A_ManifestError;
3103
- exports.A_Memory = A_Memory;
3104
- exports.A_Schedule = A_Schedule;
3105
- exports.A_ScheduleObject = A_ScheduleObject;
3106
- exports.A_TYPES__ConfigFeature = A_TYPES__ConfigFeature;
3107
- exports.ENVConfigReader = ENVConfigReader;
3108
- exports.FileConfigReader = FileConfigReader;
3109
- //# sourceMappingURL=index.js.map
3110
- //# sourceMappingURL=index.js.map