-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathexecutionEngine.ts
More file actions
122 lines (109 loc) · 3.57 KB
/
executionEngine.ts
File metadata and controls
122 lines (109 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { TraceableEngine } from './traceableEngine';
import { EngineTrace } from '../common/models/engineTrace.model';
/**
* Represents a Contextual Execution with traceability features.
*
* @template CXT - Type of the context object.
*/
export class ExecutionEngine<
CXT extends { [key: string]: unknown } = {
[key: string]: unknown;
}
> extends TraceableEngine {
protected context: CXT;
protected executionDate: Date;
protected executionId: string;
/**
* Creates an instance of ContextualExecution.
*
* @param {Object} [options] - Options for initializing the execution.
* @param {Date} [options.executionDate] - Date of the execution.
* @param {string} [options.executionId] - Unique identifier for the execution.
* @param {string} [options.initialTrace] - The initial trace for the execution.
*/
constructor(options?: { executionDate?: Date; executionId?: string; initialTrace?: EngineTrace }) {
super(options?.initialTrace);
this.executionDate = options?.executionDate ?? new Date();
this.executionId =
options?.executionId ??
[
'exec',
this.executionDate
.toISOString()
.replace(/[-:.Z]/g, '')
.replace('T', '_'),
crypto.randomUUID()
].join('_');
return this;
}
/**
* Get the current options of the Execution Engine.
*
* @returns {Object} An object containing the execution date and ID.
* @public
*/
getOptions(): { executionDate: Date; executionId: string } {
return { executionDate: this.executionDate, executionId: this.executionId };
}
setContext(value: CXT): ExecutionEngine<CXT> {
this.context = this.deepClone(value);
return this;
}
getContext(): CXT {
return this.context;
}
/**
* Update the context of the execution with partial information.
*
* @param {Partial<CXT>} partialContext - Partial context information to update.
* @returns {ExecutionEngine} - The updated ContextualExecution instance.
*/
updateContext(partialContext: Partial<CXT>): ExecutionEngine {
this.context = {
...this.context,
...partialContext
};
return this;
}
/**
* Update a specific attribute of the context object.
*
* @param {K} key - The key of the attribute to update.
* @param {CXT[K]} partialContextAttribute - Partial information to update for the attribute.
* @returns {ExecutionEngine} - The updated ContextualExecution instance.
*/
updateContextAttribute<K extends keyof CXT>(key: K, partialContextAttribute: CXT[K]): ExecutionEngine {
if (partialContextAttribute === null || typeof partialContextAttribute !== 'object') {
// If the provided attribute is not an object or is null,
// directly update the attribute in the context.
this.context[key] = partialContextAttribute;
} else {
// If the provided attribute is an object, merge it with the existing attribute.
this.context[key] = {
...(this.context?.[key] ?? {}),
...partialContextAttribute
};
}
return this;
}
/**
* Deep clone function to copy nested objects.
*
* @private
* @template T - Type of the object to clone.
* @param {T} obj - The object to clone.
* @returns {T} - The cloned object.
*/
private deepClone<T>(obj: T): T {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => this.deepClone(item)) as T;
}
return Object.entries(obj).reduce((acc, [key, value]) => {
acc[key] = this.deepClone(value);
return acc;
}, {} as T);
}
}