@adaas/a-utils 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +87 -32
  2. package/dist/index.d.mts +933 -0
  3. package/dist/index.d.ts +933 -27
  4. package/dist/index.js +1786 -90
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1764 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/examples/command-examples.ts +268 -0
  9. package/package.json +5 -3
  10. package/src/index.ts +70 -0
  11. package/src/lib/A-Command/A-Command.constants.ts +4 -0
  12. package/src/lib/A-Command/A-Command.entity.ts +31 -13
  13. package/src/lib/A-Command/A-Command.types.ts +6 -1
  14. package/src/lib/A-Command/README.md +645 -0
  15. package/src/lib/A-Logger/A-Logger.component.ts +10 -3
  16. package/src/lib/A-Memory/A-Memory.context.ts +15 -0
  17. package/src/lib/A-Polyfill/A-Polyfill.component.ts +153 -15
  18. package/src/lib/A-Polyfill/A-Polyfill.types.ts +54 -0
  19. package/src/lib/A-Polyfill/classes/A-Buffer-Polyfill.class.ts +85 -0
  20. package/src/lib/A-Polyfill/classes/A-Crypto-Polyfill.class.ts +87 -0
  21. package/src/lib/A-Polyfill/classes/A-FS-Polyfill.class.ts +61 -0
  22. package/src/lib/A-Polyfill/classes/A-Http-Polyfill.class.ts +100 -0
  23. package/src/lib/A-Polyfill/classes/A-Https-Polyfill.class.ts +100 -0
  24. package/src/lib/A-Polyfill/classes/A-Path-Polyfill.class.ts +97 -0
  25. package/src/lib/A-Polyfill/classes/A-Process-Polyfill.class.ts +73 -0
  26. package/src/lib/A-Polyfill/classes/A-Url-Polyfill.class.ts +88 -0
  27. package/tests/A-Command.test.ts +447 -2
  28. package/tests/A-Config.test.ts +5 -5
  29. package/tests/A-Memory.test.ts +189 -0
  30. package/tests/A-Polyfill.test.ts +446 -29
  31. package/tsconfig.json +1 -1
  32. package/tsup.config.ts +15 -0
  33. package/dist/src/constants/errors.constants.d.ts +0 -0
  34. package/dist/src/constants/errors.constants.js +0 -2
  35. package/dist/src/constants/errors.constants.js.map +0 -1
  36. package/dist/src/lib/A-Channel/A-Channel.component.d.ts +0 -22
  37. package/dist/src/lib/A-Channel/A-Channel.component.js +0 -84
  38. package/dist/src/lib/A-Channel/A-Channel.component.js.map +0 -1
  39. package/dist/src/lib/A-Channel/A-Channel.error.d.ts +0 -4
  40. package/dist/src/lib/A-Channel/A-Channel.error.js +0 -9
  41. package/dist/src/lib/A-Channel/A-Channel.error.js.map +0 -1
  42. package/dist/src/lib/A-Channel/A-Channel.types.d.ts +0 -0
  43. package/dist/src/lib/A-Channel/A-Channel.types.js +0 -2
  44. package/dist/src/lib/A-Channel/A-Channel.types.js.map +0 -1
  45. package/dist/src/lib/A-Command/A-Command.constants.d.ts +0 -22
  46. package/dist/src/lib/A-Command/A-Command.constants.js +0 -28
  47. package/dist/src/lib/A-Command/A-Command.constants.js.map +0 -1
  48. package/dist/src/lib/A-Command/A-Command.entity.d.ts +0 -133
  49. package/dist/src/lib/A-Command/A-Command.entity.js +0 -273
  50. package/dist/src/lib/A-Command/A-Command.entity.js.map +0 -1
  51. package/dist/src/lib/A-Command/A-Command.error.d.ts +0 -3
  52. package/dist/src/lib/A-Command/A-Command.error.js +0 -8
  53. package/dist/src/lib/A-Command/A-Command.error.js.map +0 -1
  54. package/dist/src/lib/A-Command/A-Command.types.d.ts +0 -73
  55. package/dist/src/lib/A-Command/A-Command.types.js +0 -4
  56. package/dist/src/lib/A-Command/A-Command.types.js.map +0 -1
  57. package/dist/src/lib/A-Config/A-Config.constants.d.ts +0 -3
  58. package/dist/src/lib/A-Config/A-Config.constants.js +0 -6
  59. package/dist/src/lib/A-Config/A-Config.constants.js.map +0 -1
  60. package/dist/src/lib/A-Config/A-Config.container.d.ts +0 -6
  61. package/dist/src/lib/A-Config/A-Config.container.js +0 -77
  62. package/dist/src/lib/A-Config/A-Config.container.js.map +0 -1
  63. package/dist/src/lib/A-Config/A-Config.context.d.ts +0 -29
  64. package/dist/src/lib/A-Config/A-Config.context.js +0 -63
  65. package/dist/src/lib/A-Config/A-Config.context.js.map +0 -1
  66. package/dist/src/lib/A-Config/A-Config.error.d.ts +0 -4
  67. package/dist/src/lib/A-Config/A-Config.error.js +0 -9
  68. package/dist/src/lib/A-Config/A-Config.error.js.map +0 -1
  69. package/dist/src/lib/A-Config/A-Config.types.d.ts +0 -19
  70. package/dist/src/lib/A-Config/A-Config.types.js +0 -7
  71. package/dist/src/lib/A-Config/A-Config.types.js.map +0 -1
  72. package/dist/src/lib/A-Config/components/ConfigReader.component.d.ts +0 -30
  73. package/dist/src/lib/A-Config/components/ConfigReader.component.js +0 -103
  74. package/dist/src/lib/A-Config/components/ConfigReader.component.js.map +0 -1
  75. package/dist/src/lib/A-Config/components/ENVConfigReader.component.d.ts +0 -14
  76. package/dist/src/lib/A-Config/components/ENVConfigReader.component.js +0 -72
  77. package/dist/src/lib/A-Config/components/ENVConfigReader.component.js.map +0 -1
  78. package/dist/src/lib/A-Config/components/FileConfigReader.component.d.ts +0 -11
  79. package/dist/src/lib/A-Config/components/FileConfigReader.component.js +0 -47
  80. package/dist/src/lib/A-Config/components/FileConfigReader.component.js.map +0 -1
  81. package/dist/src/lib/A-Logger/A-Logger.component.d.ts +0 -29
  82. package/dist/src/lib/A-Logger/A-Logger.component.js +0 -152
  83. package/dist/src/lib/A-Logger/A-Logger.component.js.map +0 -1
  84. package/dist/src/lib/A-Logger/A-Logger.types.d.ts +0 -0
  85. package/dist/src/lib/A-Logger/A-Logger.types.js +0 -2
  86. package/dist/src/lib/A-Logger/A-Logger.types.js.map +0 -1
  87. package/dist/src/lib/A-Manifest/A-Manifest.context.d.ts +0 -52
  88. package/dist/src/lib/A-Manifest/A-Manifest.context.js +0 -154
  89. package/dist/src/lib/A-Manifest/A-Manifest.context.js.map +0 -1
  90. package/dist/src/lib/A-Manifest/A-Manifest.error.d.ts +0 -4
  91. package/dist/src/lib/A-Manifest/A-Manifest.error.js +0 -9
  92. package/dist/src/lib/A-Manifest/A-Manifest.error.js.map +0 -1
  93. package/dist/src/lib/A-Manifest/A-Manifest.types.d.ts +0 -43
  94. package/dist/src/lib/A-Manifest/A-Manifest.types.js +0 -3
  95. package/dist/src/lib/A-Manifest/A-Manifest.types.js.map +0 -1
  96. package/dist/src/lib/A-Manifest/classes/A-ManifestChecker.class.d.ts +0 -14
  97. package/dist/src/lib/A-Manifest/classes/A-ManifestChecker.class.js +0 -24
  98. package/dist/src/lib/A-Manifest/classes/A-ManifestChecker.class.js.map +0 -1
  99. package/dist/src/lib/A-Memory/A-Memory.context.d.ts +0 -64
  100. package/dist/src/lib/A-Memory/A-Memory.context.js +0 -105
  101. package/dist/src/lib/A-Memory/A-Memory.context.js.map +0 -1
  102. package/dist/src/lib/A-Polyfill/A-Polyfill.component.d.ts +0 -20
  103. package/dist/src/lib/A-Polyfill/A-Polyfill.component.js +0 -53
  104. package/dist/src/lib/A-Polyfill/A-Polyfill.component.js.map +0 -1
  105. package/dist/src/lib/A-Polyfill/A-Polyfill.types.d.ts +0 -9
  106. package/dist/src/lib/A-Polyfill/A-Polyfill.types.js +0 -3
  107. package/dist/src/lib/A-Polyfill/A-Polyfill.types.js.map +0 -1
  108. package/dist/src/lib/A-Polyfill/A-Polyfills.class.d.ts +0 -11
  109. package/dist/src/lib/A-Polyfill/A-Polyfills.class.js +0 -123
  110. package/dist/src/lib/A-Polyfill/A-Polyfills.class.js.map +0 -1
  111. package/dist/src/lib/A-Schedule/A-Deferred.class.d.ts +0 -12
  112. package/dist/src/lib/A-Schedule/A-Deferred.class.js +0 -23
  113. package/dist/src/lib/A-Schedule/A-Deferred.class.js.map +0 -1
  114. package/dist/src/lib/A-Schedule/A-Schedule.component.d.ts +0 -57
  115. package/dist/src/lib/A-Schedule/A-Schedule.component.js +0 -49
  116. package/dist/src/lib/A-Schedule/A-Schedule.component.js.map +0 -1
  117. package/dist/src/lib/A-Schedule/A-Schedule.types.d.ts +0 -10
  118. package/dist/src/lib/A-Schedule/A-Schedule.types.js +0 -3
  119. package/dist/src/lib/A-Schedule/A-Schedule.types.js.map +0 -1
  120. package/dist/src/lib/A-Schedule/A-ScheduleObject.class.d.ts +0 -29
  121. package/dist/src/lib/A-Schedule/A-ScheduleObject.class.js +0 -58
  122. package/dist/src/lib/A-Schedule/A-ScheduleObject.class.js.map +0 -1
  123. package/index.ts +0 -71
  124. package/src/lib/A-Polyfill/A-Polyfills.class.ts +0 -99
  125. package/tsconfig.build.json +0 -56
@@ -16,7 +16,7 @@ describe('A-Command tests', () => {
16
16
  expect(command.code).toBe('a-command');
17
17
  expect(command.id).toBeDefined();
18
18
  expect(command.aseid).toBeDefined();
19
- expect(command.status).toBe(A_CONSTANTS__A_Command_Status.INITIALIZED);
19
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.CREATED);
20
20
  expect(command.scope).toBeInstanceOf(A_Scope);
21
21
  expect(command.scope.resolve(A_Memory)).toBeInstanceOf(A_Memory);
22
22
  });
@@ -30,6 +30,30 @@ describe('A-Command tests', () => {
30
30
  expect(command.startedAt).toBeInstanceOf(Date);
31
31
  expect(command.endedAt).toBeInstanceOf(Date);
32
32
  });
33
+ it('Should Allow to create a command with custom generic types', async () => {
34
+ type LifecycleEvents = 'A_CUSTOM_EVENT_1' | 'A_CUSTOM_EVENT_2';
35
+
36
+ class MyCommand extends A_Command<
37
+ { foo: string },
38
+ { bar: string },
39
+ LifecycleEvents
40
+ > { }
41
+
42
+ const command = new MyCommand({ foo: 'baz' });
43
+
44
+ A_Context.root.register(command);
45
+
46
+ command.emit('A_CUSTOM_EVENT_1');
47
+ command.emit('compile');
48
+
49
+ expect(command).toBeInstanceOf(A_Command);
50
+ expect(command.code).toBe('my-command');
51
+ expect(command.id).toBeDefined();
52
+ expect(command.aseid).toBeDefined();
53
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.CREATED);
54
+ expect(command.scope).toBeInstanceOf(A_Scope);
55
+ expect(command.scope.resolve(A_Memory)).toBeInstanceOf(A_Memory);
56
+ });
33
57
  it('Should allow to serialize and deserialize a command', async () => {
34
58
  const command = new A_Command({});
35
59
  A_Context.root.register(command);
@@ -53,7 +77,7 @@ describe('A-Command tests', () => {
53
77
  expect(deserializedCommand.startedAt?.toISOString()).toBe(command.startedAt?.toISOString());
54
78
  expect(deserializedCommand.duration).toBe(command.duration);
55
79
  });
56
-
80
+
57
81
  it('Should allow to execute a command with custom logic', async () => {
58
82
 
59
83
  // 1) create a scope
@@ -131,4 +155,425 @@ describe('A-Command tests', () => {
131
155
  expect(command.errors?.size).toBe(1);
132
156
  expect(Array.from(command.errors?.values() || [])[0].message).toBe('Test error');
133
157
  });
158
+
159
+ describe('Command Lifecycle Tests', () => {
160
+ beforeEach(() => {
161
+ A_Context.reset();
162
+ });
163
+
164
+ it('Should follow correct lifecycle sequence during execution', async () => {
165
+ const lifecycleOrder: string[] = [];
166
+
167
+ class TestCommand extends A_Command<{ input: string }, { output: string }> {}
168
+
169
+ const command = new TestCommand({ input: 'test' });
170
+ A_Context.root.register(command);
171
+
172
+ // Track lifecycle events
173
+ command.on('init', () => lifecycleOrder.push('init'));
174
+ command.on('compile', () => lifecycleOrder.push('compile'));
175
+ command.on('execute', () => lifecycleOrder.push('execute'));
176
+ command.on('complete', () => lifecycleOrder.push('complete'));
177
+ command.on('fail', () => lifecycleOrder.push('fail'));
178
+
179
+ await command.execute();
180
+
181
+ expect(lifecycleOrder).toEqual(['init', 'compile', 'execute', 'complete']);
182
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.COMPLETED);
183
+ });
184
+
185
+ it('Should track status changes through lifecycle', async () => {
186
+ const statusChanges: A_CONSTANTS__A_Command_Status[] = [];
187
+
188
+ class TestCommand extends A_Command<{ input: string }, { output: string }> {}
189
+
190
+ const command = new TestCommand({ input: 'test' });
191
+ A_Context.root.register(command);
192
+
193
+ // Initial status
194
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.CREATED);
195
+ statusChanges.push(command.status);
196
+
197
+ await command.init();
198
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.INITIALIZED);
199
+ statusChanges.push(command.status);
200
+
201
+ await command.compile();
202
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.COMPILED);
203
+ statusChanges.push(command.status);
204
+
205
+ await command.complete();
206
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.COMPLETED);
207
+ statusChanges.push(command.status);
208
+
209
+ expect(statusChanges).toEqual([
210
+ A_CONSTANTS__A_Command_Status.CREATED,
211
+ A_CONSTANTS__A_Command_Status.INITIALIZED,
212
+ A_CONSTANTS__A_Command_Status.COMPILED,
213
+ A_CONSTANTS__A_Command_Status.COMPLETED
214
+ ]);
215
+ });
216
+
217
+ it('Should handle failed lifecycle correctly', async () => {
218
+ A_Context.reset();
219
+
220
+ class FailingCommand extends A_Command<{ input: string }, { output: string }> {}
221
+
222
+ class FailingComponent extends A_Component {
223
+ @A_Feature.Extend({ scope: [FailingCommand] })
224
+ async [A_CONSTANTS_A_Command_Features.EXECUTE]() {
225
+ throw new A_Error({ title: 'Execution failed' });
226
+ }
227
+ }
228
+
229
+ A_Context.root.register(FailingComponent);
230
+
231
+ const command = new FailingCommand({ input: 'test' });
232
+ A_Context.root.register(command);
233
+
234
+ const lifecycleOrder: string[] = [];
235
+ command.on('init', () => lifecycleOrder.push('init'));
236
+ command.on('compile', () => lifecycleOrder.push('compile'));
237
+ command.on('execute', () => lifecycleOrder.push('execute'));
238
+ command.on('complete', () => lifecycleOrder.push('complete'));
239
+ command.on('fail', () => lifecycleOrder.push('fail'));
240
+
241
+ await command.execute();
242
+
243
+ expect(lifecycleOrder).toEqual(['init', 'compile', 'execute', 'fail']);
244
+ expect(command.status).toBe(A_CONSTANTS__A_Command_Status.FAILED);
245
+ expect(command.isFailed).toBe(true);
246
+ expect(command.isCompleted).toBe(false);
247
+ });
248
+
249
+ it('Should track execution timing correctly', async () => {
250
+ const command = new A_Command({});
251
+ A_Context.root.register(command);
252
+
253
+ expect(command.startedAt).toBeUndefined();
254
+ expect(command.endedAt).toBeUndefined();
255
+ expect(command.duration).toBeUndefined();
256
+
257
+ const startTime = Date.now();
258
+ await command.execute();
259
+ const endTime = Date.now();
260
+
261
+ expect(command.startedAt).toBeInstanceOf(Date);
262
+ expect(command.endedAt).toBeInstanceOf(Date);
263
+ expect(command.duration).toBeGreaterThanOrEqual(0);
264
+ expect(command.startedAt!.getTime()).toBeGreaterThanOrEqual(startTime);
265
+ expect(command.endedAt!.getTime()).toBeLessThanOrEqual(endTime);
266
+ expect(command.duration).toBe(command.endedAt!.getTime() - command.startedAt!.getTime());
267
+ });
268
+ });
269
+
270
+ describe('Command Subscribers/Event Listeners Tests', () => {
271
+ beforeEach(() => {
272
+ A_Context.reset();
273
+ });
274
+
275
+ it('Should allow multiple listeners for the same event', async () => {
276
+ const command = new A_Command({});
277
+ A_Context.root.register(command);
278
+
279
+ const listener1Calls: number[] = [];
280
+ const listener2Calls: number[] = [];
281
+
282
+ command.on('init', () => listener1Calls.push(1));
283
+ command.on('init', () => listener2Calls.push(2));
284
+
285
+ await command.init();
286
+
287
+ expect(listener1Calls).toEqual([1]);
288
+ expect(listener2Calls).toEqual([2]);
289
+ });
290
+
291
+ it('Should support custom lifecycle events', async () => {
292
+ type CustomEvents = 'custom-event-1' | 'custom-event-2';
293
+
294
+ class CustomCommand extends A_Command<{}, {}, CustomEvents> {}
295
+
296
+ const command = new CustomCommand({});
297
+ A_Context.root.register(command);
298
+
299
+ const customEvent1Calls: number[] = [];
300
+ const customEvent2Calls: number[] = [];
301
+
302
+ command.on('custom-event-1', () => customEvent1Calls.push(1));
303
+ command.on('custom-event-2', () => customEvent2Calls.push(2));
304
+
305
+ command.emit('custom-event-1');
306
+ command.emit('custom-event-2');
307
+ command.emit('custom-event-1');
308
+
309
+ expect(customEvent1Calls).toEqual([1, 1]);
310
+ expect(customEvent2Calls).toEqual([2]);
311
+ });
312
+
313
+ it('Should allow removing event listeners', async () => {
314
+ const command = new A_Command({});
315
+ A_Context.root.register(command);
316
+
317
+ const listenerCalls: number[] = [];
318
+ const listener = () => listenerCalls.push(1);
319
+
320
+ command.on('init', listener);
321
+ await command.init();
322
+ expect(listenerCalls).toEqual([1]);
323
+
324
+ // Remove listener and verify it's not called again
325
+ command.off('init', listener);
326
+
327
+ // Reset to call init again
328
+ (command as any)._status = A_CONSTANTS__A_Command_Status.CREATED;
329
+ await command.init();
330
+ expect(listenerCalls).toEqual([1]); // Should still be 1, not 2
331
+ });
332
+
333
+ it('Should pass command instance to event listeners', async () => {
334
+ const command = new A_Command({ testParam: 'value' });
335
+ A_Context.root.register(command);
336
+
337
+ let receivedCommand: A_Command<any, any, any> | undefined = undefined;
338
+
339
+ command.on('init', (cmd) => {
340
+ receivedCommand = cmd;
341
+ });
342
+
343
+ await command.init();
344
+
345
+ expect(receivedCommand).toBe(command);
346
+ expect((receivedCommand as any)?.params).toEqual({ testParam: 'value' });
347
+ });
348
+
349
+ it('Should propagate listener errors during event emission', async () => {
350
+ const command = new A_Command({});
351
+ A_Context.root.register(command);
352
+
353
+ const successfulCalls: number[] = [];
354
+
355
+ command.on('init', () => {
356
+ throw new Error('Listener error');
357
+ });
358
+ command.on('init', () => successfulCalls.push(1));
359
+
360
+ // Listener errors are propagated and will cause the command to fail
361
+ await expect(command.init()).rejects.toThrow('Listener error');
362
+ // The second listener may not be called due to the error
363
+ });
364
+ });
365
+
366
+ describe('Parameter Serialization and Transmission Tests', () => {
367
+ beforeEach(() => {
368
+ A_Context.reset();
369
+ });
370
+
371
+ it('Should preserve complex parameter types during serialization', async () => {
372
+ interface ComplexParams {
373
+ stringParam: string;
374
+ numberParam: number;
375
+ booleanParam: boolean;
376
+ objectParam: {
377
+ nested: string;
378
+ array: number[];
379
+ };
380
+ arrayParam: string[];
381
+ dateParam: string; // ISO string representation
382
+ nullParam: null;
383
+ undefinedParam?: undefined;
384
+ }
385
+
386
+ const complexParams: ComplexParams = {
387
+ stringParam: 'test string',
388
+ numberParam: 42,
389
+ booleanParam: true,
390
+ objectParam: {
391
+ nested: 'nested value',
392
+ array: [1, 2, 3]
393
+ },
394
+ arrayParam: ['a', 'b', 'c'],
395
+ dateParam: new Date('2023-01-01').toISOString(),
396
+ nullParam: null
397
+ };
398
+
399
+ class ComplexCommand extends A_Command<ComplexParams, { result: string }> {}
400
+
401
+ const command = new ComplexCommand(complexParams);
402
+ A_Context.root.register(command);
403
+
404
+ await command.execute();
405
+
406
+ const serialized = command.toJSON();
407
+ expect(serialized.params).toEqual(complexParams);
408
+
409
+ // Test deserialization
410
+ const deserializedCommand = new ComplexCommand(serialized);
411
+ expect(deserializedCommand.params).toEqual(complexParams);
412
+ expect(deserializedCommand.params.objectParam.nested).toBe('nested value');
413
+ expect(deserializedCommand.params.arrayParam).toEqual(['a', 'b', 'c']);
414
+ });
415
+
416
+ it('Should handle result serialization correctly', async () => {
417
+ A_Context.reset();
418
+
419
+ interface TestResult {
420
+ processedData: string;
421
+ count: number;
422
+ metadata: {
423
+ timestamp: string;
424
+ version: number;
425
+ };
426
+ }
427
+
428
+ class ResultCommand extends A_Command<{ input: string }, TestResult> {}
429
+
430
+ class ResultProcessor extends A_Component {
431
+ @A_Feature.Extend({ scope: [ResultCommand] })
432
+ async [A_CONSTANTS_A_Command_Features.EXECUTE](
433
+ @A_Inject(A_Memory) memory: A_Memory<TestResult>
434
+ ) {
435
+ memory.set('processedData', 'processed-input');
436
+ memory.set('count', 100);
437
+ memory.set('metadata', {
438
+ timestamp: new Date().toISOString(),
439
+ version: 1
440
+ });
441
+ }
442
+ }
443
+
444
+ A_Context.root.register(ResultProcessor);
445
+
446
+ const command = new ResultCommand({ input: 'test-input' });
447
+ A_Context.root.register(command);
448
+
449
+ await command.execute();
450
+
451
+ const serialized = command.toJSON();
452
+ expect(serialized.result).toBeDefined();
453
+ expect(serialized.result?.processedData).toBe('processed-input');
454
+ expect(serialized.result?.count).toBe(100);
455
+ expect(serialized.result?.metadata).toBeDefined();
456
+ expect(serialized.result?.metadata.version).toBe(1);
457
+
458
+ // Test deserialization - result is restored to memory and accessible through get method
459
+ const deserializedCommand = new ResultCommand(serialized);
460
+ const deserializedMemory = deserializedCommand.scope.resolve(A_Memory);
461
+ expect(deserializedMemory.get('processedData')).toBe('processed-input');
462
+ expect(deserializedMemory.get('count')).toBe(100);
463
+ expect(deserializedMemory.get('metadata')).toEqual(serialized.result?.metadata);
464
+ });
465
+
466
+ it('Should handle error serialization correctly', async () => {
467
+ A_Context.reset();
468
+
469
+ class ErrorCommand extends A_Command<{ input: string }, { output: string }> {}
470
+
471
+ class ErrorComponent extends A_Component {
472
+ @A_Feature.Extend({ scope: [ErrorCommand] })
473
+ async [A_CONSTANTS_A_Command_Features.EXECUTE](
474
+ @A_Inject(A_Memory) memory: A_Memory<{ output: string }>
475
+ ) {
476
+ memory.error(new A_Error({
477
+ title: 'First error',
478
+ message: 'First error message'
479
+ }));
480
+ memory.error(new A_Error({
481
+ title: 'Second error',
482
+ message: 'Second error message'
483
+ }));
484
+ throw new A_Error({ title: 'Thrown error' });
485
+ }
486
+ }
487
+
488
+ A_Context.root.register(ErrorComponent);
489
+
490
+ const command = new ErrorCommand({ input: 'test' });
491
+ A_Context.root.register(command);
492
+
493
+ await command.execute();
494
+
495
+ expect(command.isFailed).toBe(true);
496
+ expect(command.errors?.size).toBe(2);
497
+
498
+ const serialized = command.toJSON();
499
+ expect(serialized.errors).toBeDefined();
500
+ expect(serialized.errors?.length).toBe(2);
501
+ expect(serialized.errors?.[0].title).toBe('First error');
502
+ expect(serialized.errors?.[1].title).toBe('Second error');
503
+
504
+ // Test deserialization - errors are restored to memory
505
+ const deserializedCommand = new ErrorCommand(serialized);
506
+ const deserializedMemory = deserializedCommand.scope.resolve(A_Memory);
507
+ expect(deserializedMemory.Errors?.size).toBe(2);
508
+ const errorArray = Array.from(deserializedMemory.Errors?.values() || []);
509
+ expect(errorArray[0].title).toBe('First error');
510
+ expect(errorArray[1].title).toBe('Second error');
511
+ });
512
+
513
+ it('Should maintain parameter integrity across command transmission', async () => {
514
+ // Simulate command transmission across network/storage
515
+ const originalParams = {
516
+ userId: '12345',
517
+ action: 'update',
518
+ data: {
519
+ email: 'test@example.com',
520
+ preferences: {
521
+ theme: 'dark',
522
+ notifications: true
523
+ }
524
+ },
525
+ timestamp: new Date().toISOString()
526
+ };
527
+
528
+ class TransmissionCommand extends A_Command<typeof originalParams, { success: boolean }> {}
529
+
530
+ // Step 1: Create and execute original command
531
+ const originalCommand = new TransmissionCommand(originalParams);
532
+ A_Context.root.register(originalCommand);
533
+ await originalCommand.execute();
534
+
535
+ // Step 2: Serialize for transmission
536
+ const serializedForTransmission = JSON.stringify(originalCommand.toJSON());
537
+
538
+ // Step 3: Deserialize from transmission
539
+ const deserializedData = JSON.parse(serializedForTransmission);
540
+ const restoredCommand = new TransmissionCommand(deserializedData);
541
+
542
+ // Step 4: Verify parameter integrity
543
+ expect(restoredCommand.params).toEqual(originalParams);
544
+ expect(restoredCommand.params.data.email).toBe('test@example.com');
545
+ expect(restoredCommand.params.data.preferences.theme).toBe('dark');
546
+ expect(restoredCommand.aseid.toString()).toBe(originalCommand.aseid.toString());
547
+ expect(restoredCommand.code).toBe(originalCommand.code);
548
+ });
549
+
550
+ it('Should handle empty and edge case parameters', async () => {
551
+ const edgeCaseParams = {
552
+ emptyString: '',
553
+ emptyArray: [],
554
+ emptyObject: {},
555
+ zeroNumber: 0,
556
+ falseBoolean: false,
557
+ nullValue: null
558
+ };
559
+
560
+ class EdgeCaseCommand extends A_Command<typeof edgeCaseParams, {}> {}
561
+
562
+ const command = new EdgeCaseCommand(edgeCaseParams);
563
+ A_Context.root.register(command);
564
+ await command.execute();
565
+
566
+ const serialized = command.toJSON();
567
+ expect(serialized.params).toEqual(edgeCaseParams);
568
+
569
+ const deserializedCommand = new EdgeCaseCommand(serialized);
570
+ expect(deserializedCommand.params).toEqual(edgeCaseParams);
571
+ expect(deserializedCommand.params.emptyString).toBe('');
572
+ expect(deserializedCommand.params.emptyArray).toEqual([]);
573
+ expect(deserializedCommand.params.emptyObject).toEqual({});
574
+ expect(deserializedCommand.params.zeroNumber).toBe(0);
575
+ expect(deserializedCommand.params.falseBoolean).toBe(false);
576
+ expect(deserializedCommand.params.nullValue).toBe(null);
577
+ });
578
+ });
134
579
  });
@@ -9,7 +9,7 @@ import { A_Polyfill } from '@adaas/a-utils/lib/A-Polyfill/A-Polyfill.component';
9
9
  import { A_ConfigLoader } from '@adaas/a-utils/lib/A-Config/A-Config.container';
10
10
  import { ENVConfigReader } from '@adaas/a-utils/lib/A-Config/components/ENVConfigReader.component';
11
11
  import { FileConfigReader } from '@adaas/a-utils/lib/A-Config/components/FileConfigReader.component';
12
- import { A_TYPES__ComponentMetaKey } from '@adaas/a-concept/dist/src/global/A-Component/A-Component.constants';
12
+ import { A_Logger } from '@adaas/a-utils/lib/A-Logger/A-Logger.component';
13
13
 
14
14
  jest.retryTimes(0);
15
15
 
@@ -51,7 +51,7 @@ describe('A-Config tests', () => {
51
51
  const configLoader = new A_ConfigLoader({
52
52
  name: 'test-config-loader',
53
53
  fragments: [config],
54
- components: [A_Polyfill, FileConfigReader, ENVConfigReader]
54
+ components: [A_Logger, A_Polyfill, FileConfigReader, ENVConfigReader]
55
55
  })
56
56
 
57
57
  const concept = new A_Concept({
@@ -81,7 +81,7 @@ describe('A-Config tests', () => {
81
81
  const configLoader = new A_ConfigLoader({
82
82
  name: 'test-config-loader',
83
83
  fragments: [config],
84
- components: [A_Polyfill, ENVConfigReader]
84
+ components: [A_Logger, A_Polyfill, ENVConfigReader]
85
85
  })
86
86
 
87
87
  const concept = new A_Concept({
@@ -130,7 +130,7 @@ describe('A-Config tests', () => {
130
130
  const configLoader = new A_ConfigLoader({
131
131
  name: 'test-config-loader',
132
132
  fragments: [config],
133
- components: [A_Polyfill, FileConfigReader]
133
+ components: [A_Logger,A_Polyfill, FileConfigReader]
134
134
  })
135
135
 
136
136
  const concept = new A_Concept({
@@ -163,7 +163,7 @@ describe('A-Config tests', () => {
163
163
  const configLoader = new A_ConfigLoader({
164
164
  name: 'test-config-loader',
165
165
  fragments: [config],
166
- components: [A_Polyfill, FileConfigReader]
166
+ components: [A_Logger,A_Polyfill, FileConfigReader]
167
167
  })
168
168
 
169
169
  const concept = new A_Concept({