@adaas/a-utils 0.1.11 → 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.
@@ -0,0 +1,268 @@
1
+ /**
2
+ * A-Command Examples
3
+ *
4
+ * This file contains practical examples of using A-Command for various scenarios.
5
+ * Run with: npx ts-node examples/command-examples.ts
6
+ */
7
+
8
+ import { A_Command } from '../src/lib/A-Command/A-Command.entity';
9
+ import { A_CONSTANTS_A_Command_Features } from '../src/lib/A-Command/A-Command.constants';
10
+ import { A_Memory } from '../src/lib/A-Memory/A-Memory.context';
11
+ import { A_Component, A_Context, A_Feature, A_Inject, A_Error } from '@adaas/a-concept';
12
+
13
+ // Example 1: Basic Command Usage
14
+ async function basicCommandExample() {
15
+ console.log('\n=== Basic Command Example ===');
16
+
17
+ const command = new A_Command({
18
+ action: 'greet',
19
+ name: 'World'
20
+ });
21
+
22
+ A_Context.root.register(command);
23
+
24
+ // Add event listeners
25
+ command.on('init', () => console.log('Command initializing...'));
26
+ command.on('complete', () => console.log('Command completed!'));
27
+
28
+ await command.execute();
29
+
30
+ console.log(`Status: ${command.status}`);
31
+ console.log(`Duration: ${command.duration}ms`);
32
+ console.log(`Code: ${command.code}`);
33
+ }
34
+
35
+ // Example 2: Typed Command with Custom Logic
36
+ interface UserCreateParams {
37
+ name: string;
38
+ email: string;
39
+ role: 'admin' | 'user';
40
+ }
41
+
42
+ interface UserCreateResult {
43
+ userId: string;
44
+ createdAt: string;
45
+ profileCreated: boolean;
46
+ }
47
+
48
+ class CreateUserCommand extends A_Command<UserCreateParams, UserCreateResult> {}
49
+
50
+ class UserCreationService extends A_Component {
51
+
52
+ @A_Feature.Extend({ scope: [CreateUserCommand] })
53
+ async [A_CONSTANTS_A_Command_Features.EXECUTE](
54
+ @A_Inject(A_Memory) memory: A_Memory<UserCreateResult>
55
+ ) {
56
+ const command = A_Context.scope(this).resolve(CreateUserCommand);
57
+ const { name, email, role } = command.params;
58
+
59
+ console.log(`Creating user: ${name} (${email}) with role: ${role}`);
60
+
61
+ // Simulate user creation
62
+ const userId = `user_${Date.now()}`;
63
+ const createdAt = new Date().toISOString();
64
+
65
+ // Store results in memory
66
+ await memory.set('userId', userId);
67
+ await memory.set('createdAt', createdAt);
68
+ await memory.set('profileCreated', true);
69
+
70
+ console.log(`User created with ID: ${userId}`);
71
+ }
72
+ }
73
+
74
+ async function typedCommandExample() {
75
+ console.log('\n=== Typed Command with Custom Logic Example ===');
76
+
77
+ A_Context.reset();
78
+ A_Context.root.register(UserCreationService);
79
+
80
+ const command = new CreateUserCommand({
81
+ name: 'John Doe',
82
+ email: 'john@example.com',
83
+ role: 'user'
84
+ });
85
+
86
+ A_Context.root.register(command);
87
+ await command.execute();
88
+
89
+ console.log('User creation result:', command.result);
90
+ }
91
+
92
+ // Example 3: Command Serialization and Persistence
93
+ async function serializationExample() {
94
+ console.log('\n=== Command Serialization Example ===');
95
+
96
+ A_Context.reset();
97
+ A_Context.root.register(UserCreationService);
98
+
99
+ // Create and execute original command
100
+ const originalCommand = new CreateUserCommand({
101
+ name: 'Jane Smith',
102
+ email: 'jane@example.com',
103
+ role: 'admin'
104
+ });
105
+
106
+ A_Context.root.register(originalCommand);
107
+ await originalCommand.execute();
108
+
109
+ // Serialize command
110
+ const serialized = originalCommand.toJSON();
111
+ console.log('Command serialized for storage/transmission');
112
+
113
+ // Simulate storage and retrieval
114
+ const serializedJson = JSON.stringify(serialized);
115
+ const parsedData = JSON.parse(serializedJson);
116
+
117
+ // Restore command from serialized data
118
+ const restoredCommand = new CreateUserCommand(parsedData);
119
+
120
+ console.log('Command restored from serialization:');
121
+ console.log(`- Status: ${restoredCommand.status}`);
122
+ console.log(`- Duration: ${restoredCommand.duration}ms`);
123
+ console.log(`- User ID: ${restoredCommand.result?.userId}`);
124
+ console.log(`- Created At: ${restoredCommand.result?.createdAt}`);
125
+ }
126
+
127
+ // Example 4: Error Handling
128
+ class FailingCommand extends A_Command<{ shouldFail: boolean }, { success: boolean }> {}
129
+
130
+ class FailingService extends A_Component {
131
+
132
+ @A_Feature.Extend({ scope: [FailingCommand] })
133
+ async [A_CONSTANTS_A_Command_Features.EXECUTE](
134
+ @A_Inject(A_Memory) memory: A_Memory<{ success: boolean }>
135
+ ) {
136
+ const command = A_Context.scope(this).resolve(FailingCommand);
137
+
138
+ if (command.params.shouldFail) {
139
+ // Add error to memory
140
+ await memory.error(new A_Error({
141
+ title: 'Intentional Failure',
142
+ message: 'This command was designed to fail',
143
+ code: 'INTENTIONAL_FAIL'
144
+ }));
145
+
146
+ throw new Error('Command failed as requested');
147
+ }
148
+
149
+ await memory.set('success', true);
150
+ }
151
+ }
152
+
153
+ async function errorHandlingExample() {
154
+ console.log('\n=== Error Handling Example ===');
155
+
156
+ A_Context.reset();
157
+ A_Context.root.register(FailingService);
158
+
159
+ // Test successful command
160
+ const successCommand = new FailingCommand({ shouldFail: false });
161
+ A_Context.root.register(successCommand);
162
+ await successCommand.execute();
163
+
164
+ console.log(`Success command - Status: ${successCommand.status}`);
165
+ console.log(`Success command - Result:`, successCommand.result);
166
+
167
+ // Test failing command
168
+ const failCommand = new FailingCommand({ shouldFail: true });
169
+ A_Context.root.register(failCommand);
170
+ await failCommand.execute();
171
+
172
+ console.log(`Fail command - Status: ${failCommand.status}`);
173
+ console.log(`Fail command - Is Failed: ${failCommand.isFailed}`);
174
+ console.log(`Fail command - Errors:`, Array.from(failCommand.errors?.values() || []));
175
+ }
176
+
177
+ // Example 5: Custom Events
178
+ type FileProcessEvents = 'validation-started' | 'processing' | 'cleanup';
179
+
180
+ class FileProcessCommand extends A_Command<
181
+ { filePath: string; operation: string },
182
+ { outputPath: string; size: number },
183
+ FileProcessEvents
184
+ > {}
185
+
186
+ class FileProcessor extends A_Component {
187
+
188
+ @A_Feature.Extend({ scope: [FileProcessCommand] })
189
+ async [A_CONSTANTS_A_Command_Features.EXECUTE](
190
+ @A_Inject(A_Memory) memory: A_Memory<{ outputPath: string; size: number }>
191
+ ) {
192
+ const command = A_Context.scope(this).resolve(FileProcessCommand);
193
+ const { filePath, operation } = command.params;
194
+
195
+ // Emit custom events during processing
196
+ command.emit('validation-started');
197
+ console.log(`Validating file: ${filePath}`);
198
+ await new Promise(resolve => setTimeout(resolve, 100));
199
+
200
+ command.emit('processing');
201
+ console.log(`Processing file with operation: ${operation}`);
202
+ await new Promise(resolve => setTimeout(resolve, 200));
203
+
204
+ command.emit('cleanup');
205
+ console.log('Cleaning up temporary files');
206
+ await new Promise(resolve => setTimeout(resolve, 50));
207
+
208
+ await memory.set('outputPath', `processed_${filePath}`);
209
+ await memory.set('size', 1024);
210
+ }
211
+ }
212
+
213
+ async function customEventsExample() {
214
+ console.log('\n=== Custom Events Example ===');
215
+
216
+ A_Context.reset();
217
+ A_Context.root.register(FileProcessor);
218
+
219
+ const command = new FileProcessCommand({
220
+ filePath: 'document.pdf',
221
+ operation: 'compress'
222
+ });
223
+
224
+ // Subscribe to custom events
225
+ command.on('validation-started', () => console.log('📋 Validation phase started'));
226
+ command.on('processing', () => console.log('⚙️ Processing phase started'));
227
+ command.on('cleanup', () => console.log('🧹 Cleanup phase started'));
228
+
229
+ // Subscribe to lifecycle events
230
+ command.on('complete', () => console.log('✅ File processing completed'));
231
+
232
+ A_Context.root.register(command);
233
+ await command.execute();
234
+
235
+ console.log('Final result:', command.result);
236
+ }
237
+
238
+ // Run all examples
239
+ async function runAllExamples() {
240
+ console.log('🚀 Running A-Command Examples\n');
241
+
242
+ try {
243
+ await basicCommandExample();
244
+ await typedCommandExample();
245
+ await serializationExample();
246
+ await errorHandlingExample();
247
+ await customEventsExample();
248
+
249
+ console.log('\n✅ All examples completed successfully!');
250
+ } catch (error) {
251
+ console.error('\n❌ Example failed:', error);
252
+ }
253
+ }
254
+
255
+ // Export for use as module or run directly
256
+ export {
257
+ basicCommandExample,
258
+ typedCommandExample,
259
+ serializationExample,
260
+ errorHandlingExample,
261
+ customEventsExample,
262
+ runAllExamples
263
+ };
264
+
265
+ // Run if this file is executed directly
266
+ if (require.main === module) {
267
+ runAllExamples();
268
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaas/a-utils",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "A-Utils is a set of utilities that are used across the ADAAS ecosystem. This package is designed to be a collection of utilities that are used across the ADAAS ecosystem.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -5,7 +5,11 @@ export enum A_TYPES__CommandMetaKey {
5
5
  }
6
6
 
7
7
  export enum A_CONSTANTS__A_Command_Status {
8
+ CREATED = 'CREATED',
9
+ INITIALIZATION = 'INITIALIZATION',
8
10
  INITIALIZED = 'INITIALIZED',
11
+ COMPILATION = 'COMPILATION',
12
+ COMPILED = 'COMPILED',
9
13
  IN_PROGRESS = 'IN_PROGRESS',
10
14
  COMPLETED = 'COMPLETED',
11
15
  FAILED = 'FAILED',
@@ -14,8 +14,8 @@ import { A_Memory } from "../A-Memory/A-Memory.context";
14
14
  export class A_Command<
15
15
  InvokeType extends A_TYPES__Command_Init = A_TYPES__Command_Init,
16
16
  ResultType extends Record<string, any> = Record<string, any>,
17
- LifecycleEvents extends string = A_CONSTANTS__A_Command_Event
18
- > extends A_Entity<InvokeType, A_TYPES__Command_Serialized<ResultType>> {
17
+ LifecycleEvents extends string | A_CONSTANTS__A_Command_Event = A_CONSTANTS__A_Command_Event
18
+ > extends A_Entity<InvokeType, A_TYPES__Command_Serialized<InvokeType, ResultType>> {
19
19
 
20
20
  // ====================================================================
21
21
  // ================== Static A-Command Information ====================
@@ -136,7 +136,7 @@ export class A_Command<
136
136
  /**
137
137
  * Command invocation parameters
138
138
  */
139
- params: InvokeType | A_TYPES__Command_Serialized<ResultType> | string
139
+ params: InvokeType | A_TYPES__Command_Serialized<InvokeType, ResultType> | string
140
140
  ) {
141
141
  super(params as any)
142
142
  }
@@ -148,21 +148,32 @@ export class A_Command<
148
148
 
149
149
  // should create a new Task in DB with basic records
150
150
  async init(): Promise<void> {
151
- this._status = A_CONSTANTS__A_Command_Status.IN_PROGRESS;
151
+ // first check statuis if it passed then - skip
152
+ if (this._status !== A_CONSTANTS__A_Command_Status.CREATED) {
153
+ return;
154
+ }
155
+
156
+ this._status = A_CONSTANTS__A_Command_Status.INITIALIZATION;
152
157
  this._startTime = new Date();
153
158
  if (!this.scope.isInheritedFrom(A_Context.scope(this))) {
154
159
  this.scope.inherit(A_Context.scope(this));
155
160
  }
156
161
 
157
-
158
162
  this.emit('init');
159
- return await this.call('init', this.scope);
163
+ await this.call('init', this.scope);
164
+ this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
160
165
  }
161
166
 
162
167
  // Should compile everything before execution
163
168
  async compile() {
169
+ if (this._status !== A_CONSTANTS__A_Command_Status.INITIALIZED) {
170
+ return;
171
+ }
172
+
173
+ this._status = A_CONSTANTS__A_Command_Status.COMPILATION;
164
174
  this.emit('compile');
165
- return await this.call('compile', this.scope);
175
+ await this.call('compile', this.scope);
176
+ this._status = A_CONSTANTS__A_Command_Status.COMPILED;
166
177
  }
167
178
 
168
179
  /**
@@ -172,8 +183,11 @@ export class A_Command<
172
183
  try {
173
184
  await this.init();
174
185
  await this.compile();
175
- this.emit('execute');
176
- await this.call('execute', this.scope);
186
+
187
+ if (this._status === A_CONSTANTS__A_Command_Status.COMPILED) {
188
+ this.emit('execute');
189
+ await this.call('execute', this.scope);
190
+ }
177
191
  await this.complete();
178
192
 
179
193
  } catch (error) {
@@ -265,7 +279,7 @@ export class A_Command<
265
279
 
266
280
  this._params = newEntity;
267
281
 
268
- this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
282
+ this._status = A_CONSTANTS__A_Command_Status.CREATED;
269
283
  }
270
284
 
271
285
 
@@ -277,7 +291,7 @@ export class A_Command<
277
291
  *
278
292
  * @param serialized
279
293
  */
280
- fromJSON(serialized: A_TYPES__Command_Serialized<ResultType>): void {
294
+ fromJSON(serialized: A_TYPES__Command_Serialized<InvokeType, ResultType>): void {
281
295
  super.fromJSON(serialized);
282
296
 
283
297
  this._executionScope = new A_Scope();
@@ -303,7 +317,10 @@ export class A_Command<
303
317
  });
304
318
  }
305
319
 
306
- this._status = serialized.status || A_CONSTANTS__A_Command_Status.INITIALIZED;
320
+ this._params = serialized.params
321
+
322
+ this._status = serialized.status || A_CONSTANTS__A_Command_Status.CREATED;
323
+
307
324
  }
308
325
 
309
326
 
@@ -312,11 +329,12 @@ export class A_Command<
312
329
  *
313
330
  * @returns
314
331
  */
315
- toJSON(): A_TYPES__Command_Serialized<ResultType> {
332
+ toJSON(): A_TYPES__Command_Serialized<InvokeType, ResultType> {
316
333
  return {
317
334
  ...super.toJSON(),
318
335
  code: this.code,
319
336
  status: this._status,
337
+ params: this._params,
320
338
  startedAt: this._startTime ? this._startTime.toISOString() : undefined,
321
339
  endedAt: this._endTime ? this._endTime.toISOString() : undefined,
322
340
  duration: this.duration,
@@ -15,11 +15,12 @@ export type A_TYPES__Command_Constructor<T = A_Command> = new (...args: any[]) =
15
15
  /**
16
16
  * Command initialization type
17
17
  */
18
- export type A_TYPES__Command_Init = any;
18
+ export type A_TYPES__Command_Init = Record<string, any>;
19
19
  /**
20
20
  * Command serialized type
21
21
  */
22
22
  export type A_TYPES__Command_Serialized<
23
+ ParamsType extends Record<string, any> = Record<string, any>,
23
24
  ResultType extends Record<string, any> = Record<string, any>
24
25
  > = {
25
26
  /**
@@ -30,6 +31,10 @@ export type A_TYPES__Command_Serialized<
30
31
  * Current status of the command
31
32
  */
32
33
  status: A_CONSTANTS__A_Command_Status;
34
+ /**
35
+ * Parameters used to invoke the command
36
+ */
37
+ params: ParamsType;
33
38
  // --------------------------------------------------
34
39
  /**
35
40
  * The time when the command was created