@adaas/a-utils 0.1.17 → 0.1.19

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 (47) hide show
  1. package/dist/index.d.mts +964 -354
  2. package/dist/index.d.ts +964 -354
  3. package/dist/index.js +1426 -714
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1426 -714
  6. package/dist/index.mjs.map +1 -1
  7. package/examples/A-Channel-examples.ts +13 -11
  8. package/examples/A-Command-examples-2.ts +429 -0
  9. package/examples/A-Command-examples.ts +487 -202
  10. package/examples/A-StateMachine-examples.ts +609 -0
  11. package/package.json +3 -2
  12. package/src/index.ts +1 -2
  13. package/src/lib/A-Channel/A-Channel.component.ts +14 -74
  14. package/src/lib/A-Channel/A-Channel.error.ts +5 -5
  15. package/src/lib/A-Channel/A-Channel.types.ts +2 -10
  16. package/src/lib/A-Channel/A-ChannelRequest.context.ts +25 -74
  17. package/src/lib/A-Command/A-Command.constants.ts +78 -23
  18. package/src/lib/A-Command/A-Command.entity.ts +447 -119
  19. package/src/lib/A-Command/A-Command.error.ts +11 -0
  20. package/src/lib/A-Command/A-Command.types.ts +96 -20
  21. package/src/lib/A-Command/A-CommandExecution.context.ts +0 -0
  22. package/src/lib/A-Command/README.md +164 -68
  23. package/src/lib/A-Config/A-Config.container.ts +2 -2
  24. package/src/lib/A-Config/A-Config.context.ts +19 -5
  25. package/src/lib/A-Config/components/ConfigReader.component.ts +1 -1
  26. package/src/lib/A-Logger/A-Logger.component.ts +211 -35
  27. package/src/lib/A-Logger/A-Logger.constants.ts +50 -10
  28. package/src/lib/A-Logger/A-Logger.env.ts +17 -1
  29. package/src/lib/A-Memory/A-Memory.component.ts +440 -0
  30. package/src/lib/A-Memory/A-Memory.constants.ts +49 -0
  31. package/src/lib/A-Memory/A-Memory.context.ts +14 -118
  32. package/src/lib/A-Memory/A-Memory.error.ts +21 -0
  33. package/src/lib/A-Memory/A-Memory.types.ts +21 -0
  34. package/src/lib/A-Operation/A-Operation.context.ts +58 -0
  35. package/src/lib/A-Operation/A-Operation.types.ts +47 -0
  36. package/src/lib/A-StateMachine/A-StateMachine.component.ts +258 -0
  37. package/src/lib/A-StateMachine/A-StateMachine.constants.ts +18 -0
  38. package/src/lib/A-StateMachine/A-StateMachine.error.ts +10 -0
  39. package/src/lib/A-StateMachine/A-StateMachine.types.ts +20 -0
  40. package/src/lib/A-StateMachine/A-StateMachineTransition.context.ts +41 -0
  41. package/src/lib/A-StateMachine/README.md +391 -0
  42. package/tests/A-Channel.test.ts +17 -14
  43. package/tests/A-Command.test.ts +548 -460
  44. package/tests/A-Logger.test.ts +8 -4
  45. package/tests/A-Memory.test.ts +151 -115
  46. package/tests/A-Schedule.test.ts +2 -2
  47. package/tests/A-StateMachine.test.ts +760 -0
@@ -1,270 +1,555 @@
1
+
1
2
  /**
2
- * A-Command Examples
3
+ * A-Command Multi-Service Processing Example
4
+ *
5
+ * This example demonstrates the core concepts of A-Command:
6
+ *
7
+ * 1. **Multi-Service Processing**: Commands can be executed across different services
8
+ * 2. **Serialization**: Commands can be serialized and transmitted between services
9
+ * 3. **Component-Based Behavior**: Different components can extend command behavior
10
+ * 4. **Dependency Injection**: Commands use DI for accessing services and resources
11
+ * 5. **Lifecycle Management**: Commands follow a structured execution lifecycle
3
12
  *
4
- * This file contains practical examples of using A-Command for various scenarios.
5
- * Run with: npx ts-node examples/command-examples.ts
13
+ * The example shows:
14
+ * - Service A starts command execution and delegates to Service B
15
+ * - Service B processes the command with access to shared memory
16
+ * - A simple channel routes commands between services
17
+ * - Each service has its own component extending command behavior
6
18
  */
7
19
 
8
- import { A_Command } from '../src/lib/A-Command/A-Command.entity';
9
- import { A_CommandFeatures } 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, A_Dependency } from '@adaas/a-concept';
20
+ import { A_Caller, A_Component, A_Concept, A_Container, A_Error, A_Feature, A_FormatterHelper, A_Inject } from "@adaas/a-concept"
21
+ import { A_ChannelRequest } from "@adaas/a-utils/lib/A-Channel/A-ChannelRequest.context";
22
+ import { A_MemoryContext } from "@adaas/a-utils/lib/A-Memory/A-Memory.context";
23
+ import { A_OperationContext } from "@adaas/a-utils/lib/A-Operation/A-Operation.context";
24
+ import { A_StateMachine } from "@adaas/a-utils/lib/A-StateMachine/A-StateMachine.component";
25
+ import { A_Channel, A_Command, A_Command_Status, A_CommandFeatures, A_Logger, A_Memory, A_TYPES__Command_Serialized } from "src"
12
26
 
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
27
 
22
- A_Context.root.register(command);
28
+ // ============================================================================
29
+ // ====================== Command Definition =================================
30
+ // ============================================================================
23
31
 
24
- // Add event listeners
25
- command.on(A_CommandFeatures.onInit, () => console.log('Command initializing...'));
26
- command.on(A_CommandFeatures.onComplete, () => console.log('Command completed!'));
32
+ /**
33
+ * Command parameter type definition
34
+ * Defines the input data structure required to execute the command
35
+ */
36
+ type myCommandParams = { userId: string };
27
37
 
28
- await command.execute();
38
+ /**
39
+ * Command result type definition
40
+ * Defines the output data structure produced by successful execution
41
+ */
42
+ type myCommandResult = { success: boolean };
29
43
 
30
- console.log(`Status: ${command.status}`);
31
- console.log(`Duration: ${command.duration}ms`);
32
- console.log(`Code: ${command.code}`);
44
+ /**
45
+ * Custom Command Implementation
46
+ *
47
+ * This command demonstrates:
48
+ * - Type-safe parameter and result definitions
49
+ * - Custom properties for storing runtime data
50
+ * - Custom serialization extending the base toJSON method
51
+ * - Cross-service data transmission capabilities
52
+ */
53
+ class myCommand extends A_Command<myCommandParams, myCommandResult> {
54
+
55
+ /** Runtime property to store user data fetched during execution */
56
+ user?: { id: string };
57
+
58
+ /**
59
+ * Custom serialization method
60
+ *
61
+ * Extends the base toJSON to include additional properties
62
+ * for cross-service transmission. This allows other services
63
+ * to receive not just the standard command data but also
64
+ * custom fields relevant to the business logic.
65
+ */
66
+ toJSON(): A_TYPES__Command_Serialized<myCommandParams, myCommandResult> & { userId: string } {
67
+ return {
68
+ ...super.toJSON(),
69
+ userId: this.params.userId,
70
+ }
71
+ }
33
72
  }
34
73
 
35
- // Example 2: Typed Command with Custom Logic
36
- interface UserCreateParams {
37
- name: string;
38
- email: string;
39
- role: 'admin' | 'user';
40
- }
41
74
 
42
- interface UserCreateResult {
43
- userId: string;
44
- createdAt: string;
45
- profileCreated: boolean;
46
- }
75
+ // ============================================================================
76
+ // ====================== Service A Component ===============================
77
+ // ============================================================================
47
78
 
48
- class CreateUserCommand extends A_Command<UserCreateParams, UserCreateResult> { }
79
+ /**
80
+ * Service A Command Processor
81
+ *
82
+ * This component extends the command lifecycle in Service A by implementing
83
+ * custom behavior at different execution phases. It demonstrates:
84
+ *
85
+ * - Pre-execution setup (storing data in shared memory)
86
+ * - Main execution logic (delegating to Service B via channel)
87
+ * - Post-execution cleanup and logging
88
+ * - Inter-service communication patterns
89
+ */
90
+ class ServiceA_MyCommandProcessor extends A_Component {
91
+
92
+ /**
93
+ * Pre-execution phase handler
94
+ *
95
+ * Runs before the main command execution begins.
96
+ * Used for:
97
+ * - Initial setup and preparation
98
+ * - Storing data in shared memory for other services
99
+ * - Validation and pre-processing
100
+ *
101
+ * @param command - The command instance being executed
102
+ * @param memory - Shared memory for cross-service data storage
103
+ * @param logger - Logger instance for tracking execution
104
+ */
105
+ @A_Feature.Extend()
106
+ async [A_CommandFeatures.onBeforeExecute](
107
+ @A_Inject(A_Caller) command: myCommand,
108
+ @A_Inject(A_Memory) memory: A_Memory<{ user: { id: string } }>,
109
+ @A_Inject(A_Logger) logger: A_Logger,
110
+ ) {
111
+ logger.info('Starting command execution in Service A');
49
112
 
50
- class UserCreationService extends A_Component {
113
+ // Store user data in shared memory for Service B to access
114
+ await memory.set('user', { id: '555' });
115
+ }
51
116
 
52
- @A_Feature.Extend({ scope: [CreateUserCommand] })
117
+ /**
118
+ * Main execution phase handler
119
+ *
120
+ * Contains the core business logic for Service A.
121
+ * In this example, it delegates processing to Service B
122
+ * by sending the serialized command through a channel.
123
+ *
124
+ * @param command - The command instance being executed
125
+ * @param channel - Communication channel for inter-service requests
126
+ * @param logger - Logger instance for tracking execution
127
+ */
128
+ @A_Feature.Extend()
53
129
  async [A_CommandFeatures.onExecute](
54
- @A_Inject(A_Memory) memory: A_Memory<UserCreateResult>
130
+ @A_Inject(A_Caller) command: myCommand,
131
+ @A_Inject(A_Channel) channel: A_Channel,
132
+ @A_Inject(A_Logger) logger: A_Logger,
55
133
  ) {
56
- const command = A_Context.scope(this).resolve(CreateUserCommand)!;
57
- const { name, email, role } = command.params;
58
134
 
59
- console.log(`Creating user: ${name} (${email}) with role: ${role}`);
60
135
 
61
- // Simulate user creation
62
- const userId = `user_${Date.now()}`;
63
- const createdAt = new Date().toISOString();
136
+ // Serialize command and send to Service B for processing
137
+ const response = await channel.request<any, A_TYPES__Command_Serialized<myCommandParams, myCommandResult>>({
138
+ container: 'ServiceB',
139
+ command: command.toJSON()
140
+ });
64
141
 
65
- // Store results in memory
66
- await memory.set('userId', userId);
67
- await memory.set('createdAt', createdAt);
68
- await memory.set('profileCreated', true);
142
+ command.fromJSON(response.data!);
69
143
 
70
- console.log(`User created with ID: ${userId}`);
71
144
  }
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
145
 
86
- A_Context.root.register(command);
87
- await command.execute();
146
+ /**
147
+ * Post-execution phase handler
148
+ *
149
+ * Runs after the main execution completes (success or failure).
150
+ * Used for:
151
+ * - Cleanup operations
152
+ * - Final logging and metrics
153
+ * - Notification sending
154
+ *
155
+ * @param command - The command instance that was executed
156
+ * @param logger - Logger instance for tracking execution
157
+ */
158
+ @A_Feature.Extend()
159
+ async [A_CommandFeatures.onAfterExecute](
160
+ @A_Inject(A_Caller) command: myCommand,
161
+ @A_Inject(A_Logger) logger: A_Logger,
162
+ ) {
163
+ logger.info('Finishing command execution in Service A');
88
164
 
89
- console.log('User creation result:', command.result);
165
+ }
90
166
  }
91
167
 
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
168
 
113
- // Simulate storage and retrieval
114
- const serializedJson = JSON.stringify(serialized);
115
- const parsedData = JSON.parse(serializedJson);
169
+ // ============================================================================
170
+ // ====================== Service B Component ===============================
171
+ // ============================================================================
116
172
 
117
- // Restore command from serialized data
118
- const restoredCommand = new CreateUserCommand(parsedData);
173
+ /**
174
+ * Service B Command Processor
175
+ *
176
+ * This component handles command processing in Service B after receiving
177
+ * the command from Service A. It demonstrates:
178
+ *
179
+ * - Accessing shared memory data from other services
180
+ * - Processing commands with context from previous services
181
+ * - Stateful command execution across service boundaries
182
+ */
183
+ class ServiceB_MyCommandProcessor extends A_Component {
184
+
185
+ /**
186
+ * Pre-execution setup in Service B
187
+ *
188
+ * Retrieves data from shared memory that was stored by Service A
189
+ * and populates the command with additional context needed for processing.
190
+ *
191
+ * This shows how commands can accumulate state and data as they
192
+ * move through different services in a distributed system.
193
+ *
194
+ * @param command - The command instance being executed
195
+ * @param memory - Shared memory for accessing cross-service data
196
+ * @param logger - Logger instance for tracking execution
197
+ */
198
+ @A_Feature.Extend()
199
+ async [A_CommandFeatures.onBeforeExecute](
200
+ @A_Inject(A_Caller) command: myCommand,
201
+ @A_Inject(A_Memory) memory: A_Memory<{ user: { id: string } }>,
202
+ @A_Inject(A_Logger) logger: A_Logger,
203
+ ) {
204
+ logger.info('Starting command execution in Service B');
119
205
 
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
- }
206
+ // Retrieve user data that was stored by Service A
207
+ const user = await memory.get('user');
126
208
 
127
- // Example 4: Error Handling
128
- class FailingCommand extends A_Command<{ shouldFail: boolean }, { success: boolean }> { }
209
+ logger.info('Retrieved user from memory:', user);
129
210
 
130
- class FailingService extends A_Component {
211
+ // Populate command with additional context
212
+ command.user = user;
213
+ // throw new Error('Simulated error in Service B');
214
+ }
131
215
 
132
- @A_Feature.Extend({ scope: [FailingCommand] })
216
+ /**
217
+ * Main execution logic in Service B
218
+ *
219
+ * Handles the actual business logic processing for this command
220
+ * in Service B. This is where the final processing occurs after
221
+ * the command has been prepared by Service A.
222
+ *
223
+ * @param command - The command instance being executed
224
+ * @param logger - Logger instance for tracking execution
225
+ */
226
+ @A_Feature.Extend()
133
227
  async [A_CommandFeatures.onExecute](
134
- @A_Inject(A_Memory) memory: A_Memory<{ success: boolean }>
228
+ @A_Inject(A_Caller) command: myCommand,
229
+ @A_Inject(A_Logger) logger: A_Logger,
135
230
  ) {
136
- const command = A_Context.scope(this).resolve(FailingCommand)!;
231
+ logger.info('Executing command in Service B', command.status);
137
232
 
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
- }));
233
+ // Perform the actual business logic processing
234
+ // In a real scenario, this might involve:
235
+ // - Database operations
236
+ // - External API calls
237
+ // - Complex business logic calculations
238
+ // - Result generation
145
239
 
146
- throw new Error('Command failed as requested');
147
- }
240
+ // For this example, we'll just set a success result
241
+ // Uncomment the next line to see result handling:
242
+ // command.result = { success: true };
243
+ // await command.complete({success: true});
244
+
245
+ throw new Error('Simulated error in Service B');
148
246
 
149
- await memory.set('success', true);
150
247
  }
151
248
  }
152
249
 
153
- async function errorHandlingExample() {
154
- console.log('\n=== Error Handling Example ===');
155
250
 
156
- A_Context.reset();
157
- A_Context.root.register(FailingService);
251
+ // ============================================================================
252
+ // ====================== Inter-Service Communication ========================
253
+ // ============================================================================
158
254
 
159
- // Test successful command
160
- const successCommand = new FailingCommand({ shouldFail: false });
161
- A_Context.root.register(successCommand);
162
- await successCommand.execute();
255
+ /**
256
+ * Simple Channel Implementation
257
+ *
258
+ * A basic channel for routing commands between different services/containers.
259
+ * This demonstrates:
260
+ *
261
+ * - Command routing based on container names
262
+ * - Command deserialization and reconstruction in target service
263
+ * - Command execution in the target service context
264
+ * - Result serialization and response handling
265
+ *
266
+ * In production, this might be replaced with more sophisticated
267
+ * message queues, HTTP APIs, or service mesh communications.
268
+ */
269
+ class SimpleChannel extends A_Channel {
270
+
271
+ /**
272
+ * Handle incoming command routing requests
273
+ *
274
+ * This method:
275
+ * 1. Finds the target container by name
276
+ * 2. Resolves the command constructor in the target scope
277
+ * 3. Reconstructs the command from serialized data
278
+ * 4. Executes the command in the target service
279
+ * 5. Returns the serialized result
280
+ *
281
+ * @param memory - Shared memory containing registered containers
282
+ * @param context - Operation context with routing parameters
283
+ * @param logger - Logger for tracking routing operations
284
+ */
285
+ async onRequest(
286
+ @A_Inject(A_Memory) memory: A_Memory<{ containers: Array<A_Container> }>,
287
+ @A_Inject(A_ChannelRequest) context: A_ChannelRequest<{ container: string, command: A_TYPES__Command_Serialized }>,
288
+ @A_Inject(A_Logger) logger: A_Logger,
289
+ ): Promise<void> {
290
+
291
+ logger.info(`Channel: Routing command ${context.params.command.code} to container ${context.params.container}`);
292
+
293
+ // Get all registered containers from shared memory
294
+ const containers = await memory.get('containers') || [];
295
+
296
+ // Find target container by name (supports both exact match and camelCase conversion)
297
+ const target = containers
298
+ .find(c => A_FormatterHelper.toCamelCase(c.name) === A_FormatterHelper.toCamelCase(context.params.container)
299
+ || c.name === context.params.container
300
+ )
301
+
302
+ // Resolve the command constructor in the target container's scope
303
+ const commandConstructor = target?.scope.resolveConstructor<A_Command>(context.params.command.code);
304
+
305
+ if (!commandConstructor) {
306
+ throw new A_Error(`Channel: Unable to find command constructor for ${context.params.command.code} in container ${context.params.container}`);
307
+ }
163
308
 
164
- console.log(`Success command - Status: ${successCommand.status}`);
165
- console.log(`Success command - Result:`, successCommand.result);
309
+ // Reconstruct the command from serialized data
310
+ const command = new commandConstructor(context.params.command);
166
311
 
167
- // Test failing command
168
- const failCommand = new FailingCommand({ shouldFail: true });
169
- A_Context.root.register(failCommand);
170
- await failCommand.execute();
312
+ // Register the command in the target container's scope
313
+ target?.scope.register(command);
171
314
 
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
- }
315
+ // Execute the command in the target service
316
+ await command.execute();
176
317
 
177
- // Example 5: Custom Events
178
- type FileProcessEvents = 'validation-started' | 'processing' | 'cleanup';
318
+ // Serialize the result and send it back
319
+ const serialized = command.toJSON();
179
320
 
180
- class FileProcessCommand extends A_Command<
181
- { filePath: string; operation: string },
182
- { outputPath: string; size: number },
183
- FileProcessEvents
184
- > { }
321
+ context.succeed(serialized);
322
+ }
323
+ }
185
324
 
186
- class FileProcessor extends A_Component {
187
325
 
188
- @A_Feature.Extend({ scope: [FileProcessCommand] })
189
- async [A_CommandFeatures.onExecute](
190
- @A_Inject(A_Memory) memory: A_Memory<{ outputPath: string; size: number }>,
326
+ // ============================================================================
327
+ // ====================== Service Container Definition =======================
328
+ // ============================================================================
191
329
 
192
- @A_Dependency.Required()
193
- @A_Inject(FileProcessCommand) command: FileProcessCommand
330
+ /**
331
+ * Base Service Container
332
+ *
333
+ * A reusable container class that automatically registers itself
334
+ * in shared memory during the concept loading phase. This enables
335
+ * the channel to discover and route commands to different services.
336
+ *
337
+ * Each service instance:
338
+ * - Registers itself in shared memory during startup
339
+ * - Makes itself discoverable for command routing
340
+ * - Provides a scope for command execution
341
+ */
342
+ class Service extends A_Container {
343
+
344
+ /**
345
+ * Container initialization during concept loading
346
+ *
347
+ * This method runs during the concept loading phase and ensures
348
+ * that all service containers are registered in shared memory
349
+ * so they can be discovered by the routing channel.
350
+ *
351
+ * @param memory - Shared memory for storing container registry
352
+ * @param logger - Logger for tracking service registration
353
+ */
354
+ @A_Concept.Load()
355
+ async init(
356
+ @A_Inject(A_Memory) memory: A_Memory<{ containers: Array<A_Container> }>,
357
+ @A_Inject(A_Logger) logger: A_Logger,
194
358
  ) {
195
- const { filePath, operation } = command.params;
359
+ logger.info(`Registering container ${this.name} in shared memory`);
196
360
 
197
- // Emit custom events during processing
198
- command.emit('validation-started');
199
- console.log(`Validating file: ${filePath}`);
200
- await new Promise(resolve => setTimeout(resolve, 100));
361
+ // Get existing container registry or create new one
362
+ const containers = await memory.get('containers') || [];
201
363
 
202
- command.emit('processing');
203
- console.log(`Processing file with operation: ${operation}`);
204
- await new Promise(resolve => setTimeout(resolve, 200));
364
+ // Add this container to the registry
365
+ containers.push(this);
205
366
 
206
- command.emit('cleanup');
207
- console.log('Cleaning up temporary files');
208
- await new Promise(resolve => setTimeout(resolve, 50));
209
-
210
- await memory.set('outputPath', `processed_${filePath}`);
211
- await memory.set('size', 1024);
367
+ // Store updated registry in shared memory
368
+ await memory.set('containers', containers);
212
369
  }
213
370
  }
214
371
 
215
- async function customEventsExample() {
216
- console.log('\n=== Custom Events Example ===');
217
-
218
- A_Context.reset();
219
- A_Context.root.register(FileProcessor);
372
+ // ============================================================================
373
+ // ====================== Application Setup and Execution ===================
374
+ // ============================================================================
220
375
 
221
- const command = new FileProcessCommand({
222
- filePath: 'document.pdf',
223
- operation: 'compress'
376
+ /**
377
+ * Multi-Service Command Processing Demonstration
378
+ *
379
+ * This example demonstrates how to set up and execute commands
380
+ * across multiple services using the A_Concept architecture.
381
+ *
382
+ * Architecture Overview:
383
+ * - Two separate service containers (ServiceA and ServiceB)
384
+ * - Shared memory context for inter-service communication
385
+ * - Distributed command processing with lifecycle management
386
+ * - State tracking and result aggregation
387
+ */
388
+ (async () => {
389
+ // ============================================================================
390
+ // ====================== Shared Memory Configuration ========================
391
+ // ============================================================================
392
+
393
+ /**
394
+ * Shared Memory Context
395
+ *
396
+ * Creates a shared memory space that will be accessible by both services.
397
+ * This enables inter-service communication and state sharing during
398
+ * command execution.
399
+ */
400
+ const sharedMemory = new A_MemoryContext();
401
+
402
+ // ============================================================================
403
+ // ====================== Service Container Setup ============================
404
+ // ============================================================================
405
+
406
+ /**
407
+ * Service A Container
408
+ *
409
+ * Specialized service for handling the initial phases of command processing.
410
+ * Contains its own processor, routing channel, and shared dependencies.
411
+ *
412
+ * Components:
413
+ * - ServiceA_MyCommandProcessor: Handles pre-processing and main logic
414
+ * - SimpleChannel: Routes commands between services
415
+ * - A_Memory: Provides access to shared state
416
+ * - A_StateMachine: Manages command lifecycle transitions
417
+ * - A_Logger: Provides scoped logging
418
+ */
419
+ const containerA = new Service({
420
+ name: 'ServiceA',
421
+ fragments: [sharedMemory], // Share memory context between services
422
+ components: [
423
+ ServiceA_MyCommandProcessor, // Service-specific command processor
424
+ SimpleChannel, // Inter-service communication channel
425
+ A_Memory, // Memory management
426
+ A_StateMachine, // State machine for command lifecycle
427
+ A_Logger // Scoped logging
428
+ ],
429
+ entities: [myCommand], // Register command entity for this service
224
430
  });
225
431
 
226
- // Subscribe to custom events
227
- command.on('validation-started', () => console.log('šŸ“‹ Validation phase started'));
228
- command.on('processing', () => console.log('āš™ļø Processing phase started'));
229
- command.on('cleanup', () => console.log('🧹 Cleanup phase started'));
432
+ /**
433
+ * Service B Container
434
+ *
435
+ * Specialized service for handling secondary processing and finalization.
436
+ * Shares memory context with Service A but has its own processor logic.
437
+ *
438
+ * Note: Service B doesn't include SimpleChannel as it's primarily
439
+ * a target for routed commands rather than an initiator.
440
+ */
441
+ const containerB = new Service({
442
+ name: 'ServiceB',
443
+ fragments: [sharedMemory], // Same shared memory as Service A
444
+ components: [
445
+ ServiceB_MyCommandProcessor, // Service-specific command processor
446
+ A_Memory, // Memory management (shared)
447
+ A_StateMachine, // State machine for command lifecycle
448
+ A_Logger // Scoped logging
449
+ ],
450
+ entities: [myCommand], // Register command entity for this service
451
+ });
230
452
 
231
- // Subscribe to lifecycle events
232
- command.on('onComplete', () => console.log('āœ… File processing completed'));
453
+ // ============================================================================
454
+ // ====================== Concept Architecture Setup =========================
455
+ // ============================================================================
456
+
457
+ /**
458
+ * A_Concept - Application Architecture
459
+ *
460
+ * Defines the overall application architecture by combining:
461
+ * - Multiple service containers
462
+ * - Shared components available across all services
463
+ * - Global dependency injection configuration
464
+ *
465
+ * This creates a distributed system where commands can be processed
466
+ * across multiple services while maintaining shared state and communication.
467
+ */
468
+ const concept = new A_Concept({
469
+ containers: [containerA, containerB], // Register both service containers
470
+ components: [
471
+ SimpleChannel, // Global routing channel
472
+ A_Memory, // Global memory management
473
+ A_Logger // Global logging system
474
+ ],
475
+ });
233
476
 
234
- A_Context.root.register(command);
477
+ console.log('šŸ›ļø Concept architecture defined with distributed services');
478
+
479
+ // ============================================================================
480
+ // ====================== System Initialization ==============================
481
+ // ============================================================================
482
+
483
+ /**
484
+ * Load and Initialize the Distributed System
485
+ *
486
+ * This triggers:
487
+ * 1. Container registration in shared memory
488
+ * 2. Component dependency resolution
489
+ * 3. Service discovery and routing table setup
490
+ * 4. Shared state initialization
491
+ */
492
+ console.log('⚔ Loading and initializing distributed system...');
493
+ await concept.load();
494
+ console.log('āœ… System loaded - all services are ready\n');
495
+
496
+ // ============================================================================
497
+ // ====================== Command Creation and Execution =====================
498
+ // ============================================================================
499
+
500
+ /**
501
+ * Create Command Instance
502
+ *
503
+ * Instantiate the command with initial parameters.
504
+ * The command will go through the complete lifecycle:
505
+ * CREATED → INITIALIZED → COMPILED → EXECUTING → COMPLETED/FAILED
506
+ */
507
+ const command = new myCommand({ userId: '123' });
508
+ console.log(`šŸ“ Created command: ${command.id} for user: 123`);
509
+ console.log(` Initial status: ${command.status}`);
510
+
511
+ /**
512
+ * Register Command in Service A
513
+ *
514
+ * Register the command in Service A's scope, making it available
515
+ * for dependency injection and lifecycle management within that service.
516
+ */
517
+ containerA.scope.register(command);
518
+ console.log('šŸ”— Command registered in ServiceA scope');
519
+
520
+ /**
521
+ * Execute Distributed Command
522
+ *
523
+ * This will trigger:
524
+ * 1. ServiceA_MyCommandProcessor.pre() - Pre-processing setup
525
+ * 2. ServiceA_MyCommandProcessor.main() - Route to ServiceB
526
+ * 3. ServiceB_MyCommandProcessor processing - Secondary processing
527
+ * 4. ServiceA_MyCommandProcessor.post() - Result aggregation
528
+ * 5. State transitions and result compilation
529
+ */
530
+ console.log('šŸš€ Executing distributed command across services...\n');
235
531
  await command.execute();
236
532
 
237
- console.log('Final result:', command.result);
238
- }
533
+ // ============================================================================
534
+ // ====================== Results and Logging ================================
535
+ // ============================================================================
239
536
 
240
- // Run all examples
241
- async function runAllExamples() {
242
- console.log('šŸš€ Running A-Command Examples\n');
537
+ /**
538
+ * Result Analysis and Logging
539
+ *
540
+ * After execution, analyze the command state and results.
541
+ * The logger is resolved from the concept scope to provide
542
+ * centralized logging across all services.
543
+ */
544
+ const logger = concept.scope.resolve(A_Logger)!;
243
545
 
244
- try {
245
- await basicCommandExample();
246
- await typedCommandExample();
247
- await serializationExample();
248
- await errorHandlingExample();
249
- await customEventsExample();
546
+ // Log final execution status
547
+ logger.info('✨ Command execution completed');
548
+ logger.info(` Final status: ${command.status}`);
549
+ logger.info(' Command state:', command.toJSON());
250
550
 
251
- console.log('\nāœ… All examples completed successfully!');
252
- } catch (error) {
253
- console.error('\nāŒ Example failed:', error);
254
- }
255
- }
551
+ console.log('\nšŸŽ‰ Multi-service command processing example completed!');
552
+ console.log('Check the logs above to see the distributed processing flow.');
553
+
554
+ })();
256
555
 
257
- // Export for use as module or run directly
258
- export {
259
- basicCommandExample,
260
- typedCommandExample,
261
- serializationExample,
262
- errorHandlingExample,
263
- customEventsExample,
264
- runAllExamples
265
- };
266
-
267
- // Run if this file is executed directly
268
- if (require.main === module) {
269
- runAllExamples();
270
- }