@nsshunt/stsrunnerframework 1.0.200 → 2.0.2
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/README.md +1059 -1
- package/dist/stsrunnerframework.mjs +8279 -4105
- package/dist/stsrunnerframework.mjs.map +1 -1
- package/dist/stsrunnerframework.umd.js +8304 -4119
- package/dist/stsrunnerframework.umd.js.map +1 -1
- package/package.json +4 -4
- package/types/abstractRunnerExecutionWorker.d.ts +194 -0
- package/types/abstractRunnerExecutionWorker.d.ts.map +1 -0
- package/types/archiveManager.d.ts +172 -0
- package/types/archiveManager.d.ts.map +1 -0
- package/types/asyncRunnerInstanceManager.d.ts +108 -0
- package/types/asyncRunnerInstanceManager.d.ts.map +1 -0
- package/types/commonTypes.d.ts +115 -35
- package/types/commonTypes.d.ts.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/messageBroker.d.ts +324 -0
- package/types/messageBroker.d.ts.map +1 -0
- package/types/runnerInstance.d.ts +245 -0
- package/types/runnerInstance.d.ts.map +1 -0
- package/types/runnerLifecycleManager.d.ts +210 -0
- package/types/runnerLifecycleManager.d.ts.map +1 -0
- package/types/telemetryProcessor.d.ts +67 -0
- package/types/telemetryProcessor.d.ts.map +1 -1
- package/types/testing/mockedWorkerTestRunner01.d.ts +129 -2
- package/types/testing/mockedWorkerTestRunner01.d.ts.map +1 -1
- package/types/testing/testCase01.d.ts +222 -2
- package/types/testing/testCase01.d.ts.map +1 -1
- package/types/testing/testCase02.d.ts +206 -2
- package/types/testing/testCase02.d.ts.map +1 -1
- package/types/testing/wmwokerProcess.test.d.ts +1 -0
- package/types/testing/wmwokerProcess2.test.d.ts +1 -0
- package/types/workerCommandCoordinator.d.ts +152 -0
- package/types/workerCommandCoordinator.d.ts.map +1 -0
- package/types/workerInstance.d.ts +340 -16
- package/types/workerInstance.d.ts.map +1 -1
- package/types/workerInstanceMannager.d.ts +170 -0
- package/types/workerInstanceMannager.d.ts.map +1 -0
- package/types/workerManager.d.ts +335 -24
- package/types/workerManager.d.ts.map +1 -1
- package/types/workerRegistry.d.ts +251 -0
- package/types/workerRegistry.d.ts.map +1 -0
- package/types/workerStateSynchroniser.d.ts +161 -0
- package/types/workerStateSynchroniser.d.ts.map +1 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* RunnerInstance
|
|
4
|
+
* --------------
|
|
5
|
+
* Concrete runtime implementation of {@link IRunnerEx}.
|
|
6
|
+
*
|
|
7
|
+
* A RunnerInstance represents a single executable runner hosted inside a worker.
|
|
8
|
+
*
|
|
9
|
+
* Responsibilities:
|
|
10
|
+
* - Store runner runtime state and metadata
|
|
11
|
+
* - Dispatch runner commands to the owning worker via the message broker
|
|
12
|
+
* - Maintain runner telemetry/instrumentation state
|
|
13
|
+
* - Register runner-level event subscriptions against the owning worker
|
|
14
|
+
* - Expose full and reduced serialisable runner models
|
|
15
|
+
*
|
|
16
|
+
* Design notes:
|
|
17
|
+
* - A RunnerInstance belongs to exactly one {@link IWorkerEx}.
|
|
18
|
+
* - Command execution is brokered through {@link STSMessageBroker}; the runner does
|
|
19
|
+
* not communicate with the worker directly.
|
|
20
|
+
* - Event subscriptions are stored on the owning worker, keyed by runner id.
|
|
21
|
+
*/
|
|
22
|
+
import { IAsyncRunnerContext, IExecuteRunnerActionResult, IRunner, IRunnerCore, IRunnerEx, IRunnerOptions, IRunnerState, IRunnerTelemetry, IWorkerEx, IRunnerHistoryRecord } from './commonTypes';
|
|
23
|
+
import { PublishInstrumentController } from '@nsshunt/stsinstrumentmanagerclient';
|
|
24
|
+
import { STSMessageBroker } from './messageBroker';
|
|
25
|
+
/**
|
|
26
|
+
* Constructor options required to create a {@link RunnerInstance}.
|
|
27
|
+
*
|
|
28
|
+
* Notes:
|
|
29
|
+
* - `workerEx` is the owning live worker instance that hosts this runner.
|
|
30
|
+
* - `workerManagerId` identifies the top-level owning worker manager.
|
|
31
|
+
* - `runnerId` is generated elsewhere and supplied to this instance.
|
|
32
|
+
* - `asyncRunnerContext` contains the logical identity and hierarchy of this runner.
|
|
33
|
+
* - `runnerOptions` contains runtime configuration for the runner.
|
|
34
|
+
* - `messageBroker` is used to dispatch commands and correlate responses.
|
|
35
|
+
* - `publishInstrumentController` is optional and is used when telemetry publishing
|
|
36
|
+
* to an external instrumentation system is enabled.
|
|
37
|
+
*/
|
|
38
|
+
export interface IRunnerInstanceOptions {
|
|
39
|
+
/** Owning live worker instance. */
|
|
40
|
+
workerEx: IWorkerEx;
|
|
41
|
+
/** Id of the top-level owning worker manager. */
|
|
42
|
+
workerManagerId: string;
|
|
43
|
+
/** Unique id for this runner instance. */
|
|
44
|
+
runnerId: string;
|
|
45
|
+
/** Hierarchical runtime context used to identify this runner. */
|
|
46
|
+
asyncRunnerContext: IAsyncRunnerContext;
|
|
47
|
+
/** Runner-specific runtime configuration. */
|
|
48
|
+
runnerOptions: IRunnerOptions;
|
|
49
|
+
/** Broker used for runner command dispatch and callback correlation. */
|
|
50
|
+
messageBroker: STSMessageBroker;
|
|
51
|
+
/** Optional external instrumentation publisher for this runner. */
|
|
52
|
+
publishInstrumentController?: PublishInstrumentController;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Concrete live runner runtime instance.
|
|
56
|
+
*
|
|
57
|
+
* This class owns:
|
|
58
|
+
* - the current runtime state of the runner
|
|
59
|
+
* - its current iteration counter
|
|
60
|
+
* - its telemetry/instrumentation data
|
|
61
|
+
* - its configuration/options
|
|
62
|
+
* - its archived flag and runner history
|
|
63
|
+
*
|
|
64
|
+
* This class delegates command execution to the owning worker via
|
|
65
|
+
* the injected message broker.
|
|
66
|
+
*/
|
|
67
|
+
export declare class RunnerInstance implements IRunnerEx {
|
|
68
|
+
#private;
|
|
69
|
+
/** Unique id for this runner instance. */
|
|
70
|
+
id: string;
|
|
71
|
+
/** Id of the owning worker instance. */
|
|
72
|
+
workerId: string;
|
|
73
|
+
/** Id of the owning worker manager instance. */
|
|
74
|
+
workerManagerId: string;
|
|
75
|
+
/**
|
|
76
|
+
* Current lifecycle state of the runner.
|
|
77
|
+
*
|
|
78
|
+
* Defaults to `IRunnerState.created` when the runner instance is first created.
|
|
79
|
+
*/
|
|
80
|
+
state: IRunnerState;
|
|
81
|
+
/**
|
|
82
|
+
* Current iteration number for the runner.
|
|
83
|
+
*
|
|
84
|
+
* The meaning of this depends on runner behaviour; typically it tracks
|
|
85
|
+
* how many execute cycles/iterations have been completed.
|
|
86
|
+
*/
|
|
87
|
+
iteration: number;
|
|
88
|
+
/**
|
|
89
|
+
* Optional instrumentation publisher used for telemetry integration.
|
|
90
|
+
*
|
|
91
|
+
* This is only populated when external instrumentation publishing is enabled.
|
|
92
|
+
*/
|
|
93
|
+
publishInstrumentController?: PublishInstrumentController;
|
|
94
|
+
/**
|
|
95
|
+
* Hierarchical runtime identity/context for the runner.
|
|
96
|
+
*
|
|
97
|
+
* Typically includes host, agent, worker, and runner identifiers.
|
|
98
|
+
*/
|
|
99
|
+
asyncRunnerContext: IAsyncRunnerContext;
|
|
100
|
+
/** Runtime configuration/options for this runner. */
|
|
101
|
+
options: IRunnerOptions;
|
|
102
|
+
/**
|
|
103
|
+
* Historical runner snapshots/events for this runner.
|
|
104
|
+
*
|
|
105
|
+
* This is intentionally initialised as an empty array and populated elsewhere
|
|
106
|
+
* by lifecycle/state management components.
|
|
107
|
+
*/
|
|
108
|
+
runnerHistory: IRunnerHistoryRecord[];
|
|
109
|
+
/**
|
|
110
|
+
* Live telemetry/instrumentation values for this runner.
|
|
111
|
+
*
|
|
112
|
+
* These values are updated during runtime as telemetry arrives from the worker.
|
|
113
|
+
*/
|
|
114
|
+
instrumentData: IRunnerTelemetry;
|
|
115
|
+
/**
|
|
116
|
+
* Indicates whether this runner has been archived/retired from active in-memory use.
|
|
117
|
+
*
|
|
118
|
+
* This flag is typically managed externally by archive/lifecycle management logic.
|
|
119
|
+
*/
|
|
120
|
+
archived: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Construct a new live runner runtime instance.
|
|
123
|
+
*
|
|
124
|
+
* Behaviour:
|
|
125
|
+
* - Copies supplied identity and configuration values
|
|
126
|
+
* - Derives `workerId` from the supplied owning worker
|
|
127
|
+
* - Stores broker and worker references for later command dispatch
|
|
128
|
+
* - Initialises telemetry counters/metrics to zeroed defaults
|
|
129
|
+
*
|
|
130
|
+
* @param options Construction options and collaborators.
|
|
131
|
+
*/
|
|
132
|
+
constructor(options: IRunnerInstanceOptions);
|
|
133
|
+
/**
|
|
134
|
+
* Send a `StartRunner` command for this runner via the message broker.
|
|
135
|
+
*
|
|
136
|
+
* @returns Action result returned by the worker.
|
|
137
|
+
*/
|
|
138
|
+
Start(): Promise<IExecuteRunnerActionResult>;
|
|
139
|
+
/**
|
|
140
|
+
* Send a `StopRunner` command for this runner via the message broker.
|
|
141
|
+
*
|
|
142
|
+
* @returns Action result returned by the worker.
|
|
143
|
+
*/
|
|
144
|
+
Stop(): Promise<IExecuteRunnerActionResult>;
|
|
145
|
+
/**
|
|
146
|
+
* Send a `PauseRunner` command for this runner via the message broker.
|
|
147
|
+
*
|
|
148
|
+
* @returns Action result returned by the worker.
|
|
149
|
+
*/
|
|
150
|
+
Pause(): Promise<IExecuteRunnerActionResult>;
|
|
151
|
+
/**
|
|
152
|
+
* Send a `ResumeRunner` command for this runner via the message broker.
|
|
153
|
+
*
|
|
154
|
+
* @returns Action result returned by the worker.
|
|
155
|
+
*/
|
|
156
|
+
Resume(): Promise<IExecuteRunnerActionResult>;
|
|
157
|
+
/**
|
|
158
|
+
* Send a `ResetRunner` command for this runner via the message broker.
|
|
159
|
+
*
|
|
160
|
+
* @returns Action result returned by the worker.
|
|
161
|
+
*/
|
|
162
|
+
Reset(): Promise<IExecuteRunnerActionResult>;
|
|
163
|
+
/**
|
|
164
|
+
* Send an `ExecuteRunner` command for this runner via the message broker.
|
|
165
|
+
*
|
|
166
|
+
* @returns Action result returned by the worker.
|
|
167
|
+
*/
|
|
168
|
+
Execute(): Promise<IExecuteRunnerActionResult>;
|
|
169
|
+
/**
|
|
170
|
+
* Send a `TerminateRunner` command for this runner via the message broker.
|
|
171
|
+
*
|
|
172
|
+
* @returns Action result returned by the worker.
|
|
173
|
+
*/
|
|
174
|
+
Terminate(): Promise<IExecuteRunnerActionResult>;
|
|
175
|
+
/**
|
|
176
|
+
* Send an `UpdateRunner` command for this runner via the message broker.
|
|
177
|
+
*
|
|
178
|
+
* Behaviour:
|
|
179
|
+
* - Sends the supplied partial options to the underlying worker
|
|
180
|
+
* - The worker is responsible for applying/merging the update as appropriate
|
|
181
|
+
*
|
|
182
|
+
* @param runnerOptions Partial runner option updates to apply.
|
|
183
|
+
* @returns Action result returned by the worker.
|
|
184
|
+
*/
|
|
185
|
+
Update(runnerOptions: Partial<IRunnerOptions>): Promise<IExecuteRunnerActionResult>;
|
|
186
|
+
/**
|
|
187
|
+
* Register a runner-level event subscription.
|
|
188
|
+
*
|
|
189
|
+
* Behaviour:
|
|
190
|
+
* - Stores the subscription on the owning worker in `runnersEvents`
|
|
191
|
+
* - Creates the per-runner event list lazily if it does not yet exist
|
|
192
|
+
* - Returns this runner instance to support fluent chaining
|
|
193
|
+
*
|
|
194
|
+
* Notes:
|
|
195
|
+
* - Runner event subscriptions are hosted on the worker because the worker is
|
|
196
|
+
* the aggregate owner of all live runner instances.
|
|
197
|
+
*
|
|
198
|
+
* @param eventName Event name to subscribe to.
|
|
199
|
+
* @param cb Callback invoked when the event is emitted for this runner.
|
|
200
|
+
* @returns This runner instance for fluent chaining.
|
|
201
|
+
*/
|
|
202
|
+
on(eventName: string, cb: (args?: any) => void): IRunnerEx;
|
|
203
|
+
/**
|
|
204
|
+
* Convert this live runner runtime instance into a full serialisable runner model.
|
|
205
|
+
*
|
|
206
|
+
* Behaviour:
|
|
207
|
+
* - Copies runner metadata and state
|
|
208
|
+
* - Creates shallow copies of nested objects used by the DTO
|
|
209
|
+
* - Copies telemetry messages into a new array to avoid external mutation
|
|
210
|
+
* - Includes full `runnerHistory`
|
|
211
|
+
*
|
|
212
|
+
* @returns Full serialisable runner model.
|
|
213
|
+
*/
|
|
214
|
+
toJSON(): IRunner;
|
|
215
|
+
/**
|
|
216
|
+
* Convert this runner into a serialisable runner model with optional history exclusion.
|
|
217
|
+
*
|
|
218
|
+
* Behaviour:
|
|
219
|
+
* - When `includeHistory` is `true`, returns the full runner DTO from {@link toJSON}
|
|
220
|
+
* - When `includeHistory` is `false`, removes `runnerHistory` from the returned model
|
|
221
|
+
*
|
|
222
|
+
* This is useful when sending a lighter-weight runner payload over message channels.
|
|
223
|
+
*
|
|
224
|
+
* @param includeHistory Whether to include `runnerHistory` in the returned DTO.
|
|
225
|
+
* @returns Full or reduced serialisable runner model.
|
|
226
|
+
*/
|
|
227
|
+
toRunner(includeHistory?: boolean): IRunner;
|
|
228
|
+
/**
|
|
229
|
+
* Convert this runner into a reduced/core representation.
|
|
230
|
+
*
|
|
231
|
+
* Behaviour:
|
|
232
|
+
* - Includes only the minimal runtime state required for lightweight summaries
|
|
233
|
+
* - Includes `runnerPlan` when present in the runner options
|
|
234
|
+
*
|
|
235
|
+
* Intended use cases:
|
|
236
|
+
* - lightweight dashboards
|
|
237
|
+
* - summary views
|
|
238
|
+
* - state-only synchronisation payloads
|
|
239
|
+
*
|
|
240
|
+
* @returns Reduced/core runner DTO.
|
|
241
|
+
* @throws Re-throws any error after logging.
|
|
242
|
+
*/
|
|
243
|
+
toRunnerCore(): IRunnerCore;
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=runnerInstance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerInstance.d.ts","sourceRoot":"","sources":["../src/runnerInstance.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAEH,mBAAmB,EACnB,0BAA0B,EAE1B,OAAO,EACP,WAAW,EAEX,SAAS,EACT,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,SAAS,EACT,oBAAoB,EACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,sBAAsB;IACnC,mCAAmC;IACnC,QAAQ,EAAE,SAAS,CAAC;IAEpB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;IAExB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IAEjB,iEAAiE;IACjE,kBAAkB,EAAE,mBAAmB,CAAC;IAExC,6CAA6C;IAC7C,aAAa,EAAE,cAAc,CAAC;IAE9B,wEAAwE;IACxE,aAAa,EAAE,gBAAgB,CAAC;IAEhC,mEAAmE;IACnE,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;CAC7D;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,cAAe,YAAW,SAAS;;IAC5C,0CAA0C;IACnC,EAAE,EAAE,MAAM,CAAC;IAElB,wCAAwC;IACjC,QAAQ,EAAE,MAAM,CAAC;IAExB,gDAAgD;IACzC,eAAe,EAAE,MAAM,CAAC;IAE/B;;;;OAIG;IACI,KAAK,EAAE,YAAY,CAAwB;IAElD;;;;;OAKG;IACI,SAAS,SAAK;IAErB;;;;OAIG;IACI,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAEjE;;;;OAIG;IACI,kBAAkB,EAAE,mBAAmB,CAAC;IAE/C,qDAAqD;IAC9C,OAAO,EAAE,cAAc,CAAC;IAE/B;;;;;OAKG;IACI,aAAa,EAAE,oBAAoB,EAAE,CAAO;IAEnD;;;;OAIG;IACI,cAAc,EAAE,gBAAgB,CAAC;IAExC;;;;OAIG;IACI,QAAQ,UAAS;IAQxB;;;;;;;;;;OAUG;gBACS,OAAO,EAAE,sBAAsB;IAmC3C;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI5C;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI3C;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI5C;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI7C;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI5C;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAI9C;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAIhD;;;;;;;;;OASG;IACH,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAInF;;;;;;;;;;;;;;;OAeG;IACH,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,SAAS;IAa1D;;;;;;;;;;OAUG;IACH,MAAM,IAAI,OAAO;IAiBjB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,cAAc,UAAO,GAAG,OAAO;IAUxC;;;;;;;;;;;;;;OAcG;IACH,YAAY,IAAI,WAAW;CA8C9B"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* RunnerLifecycleManager
|
|
4
|
+
* ----------------------
|
|
5
|
+
* Runtime lifecycle/event processor responsible for handling unsolicited
|
|
6
|
+
* runner-related messages received from workers.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - process unsolicited telemetry messages pushed from workers
|
|
10
|
+
* - process unsolicited runner state change messages pushed from workers
|
|
11
|
+
* - update live in-memory runner state in the {@link WorkerRegistry}
|
|
12
|
+
* - trigger telemetry publishing via {@link TelemetryProcessor}
|
|
13
|
+
* - emit runner-level events to registered listeners
|
|
14
|
+
* - provide a message-handler factory suitable for wiring into the message broker
|
|
15
|
+
*
|
|
16
|
+
* High-level role in the architecture:
|
|
17
|
+
* - Workers push unsolicited messages such as telemetry and state changes
|
|
18
|
+
* - The {@link STSMessageBroker} routes those unsolicited messages to a callback
|
|
19
|
+
* - This class provides that callback and applies the updates to live runner instances
|
|
20
|
+
*
|
|
21
|
+
* Important distinction:
|
|
22
|
+
* - Solicited request/response traffic is handled by the message broker
|
|
23
|
+
* - Unsolicited push/event traffic is handled here
|
|
24
|
+
*
|
|
25
|
+
* Typical unsolicited messages handled here:
|
|
26
|
+
* - `InstrumentTelemetry`
|
|
27
|
+
* - `RunnerStateChange`
|
|
28
|
+
*/
|
|
29
|
+
import { IWorkerEx, IRunner, IRunnerEx } from './commonTypes';
|
|
30
|
+
import { WorkerRegistry } from './workerRegistry';
|
|
31
|
+
import { ISTSLogger } from '@nsshunt/stsutils';
|
|
32
|
+
/**
|
|
33
|
+
* Constructor options for {@link RunnerLifecycleManager}.
|
|
34
|
+
*/
|
|
35
|
+
export interface IRunnerLifecycleManagerOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Logger used for diagnostics and error reporting.
|
|
38
|
+
*/
|
|
39
|
+
logger: ISTSLogger;
|
|
40
|
+
/**
|
|
41
|
+
* Shared live worker/runner registry used to resolve and update
|
|
42
|
+
* the current runtime runner instances.
|
|
43
|
+
*/
|
|
44
|
+
workerRegistry: WorkerRegistry;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Manages live runner lifecycle updates for unsolicited worker messages.
|
|
48
|
+
*
|
|
49
|
+
* This class updates the in-memory runtime graph and emits runner events
|
|
50
|
+
* in response to messages pushed by workers.
|
|
51
|
+
*/
|
|
52
|
+
export declare class RunnerLifecycleManager {
|
|
53
|
+
/**
|
|
54
|
+
* Immutable runtime configuration for this lifecycle manager.
|
|
55
|
+
*/
|
|
56
|
+
private readonly options;
|
|
57
|
+
/**
|
|
58
|
+
* Processor used to forward/update external telemetry instrumentation.
|
|
59
|
+
*
|
|
60
|
+
* This is created eagerly in the constructor and used only when a runner
|
|
61
|
+
* has a publish instrument controller attached.
|
|
62
|
+
*/
|
|
63
|
+
private readonly telemetryProcessor;
|
|
64
|
+
/**
|
|
65
|
+
* Construct a new runner lifecycle manager.
|
|
66
|
+
*
|
|
67
|
+
* @param options Logger and worker registry dependencies.
|
|
68
|
+
*/
|
|
69
|
+
constructor(options: IRunnerLifecycleManagerOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Process an unsolicited telemetry message for a runner.
|
|
72
|
+
*
|
|
73
|
+
* Behaviour:
|
|
74
|
+
* - resolves the live runner instance from the registry
|
|
75
|
+
* - updates the live runner state/telemetry using {@link SyncRunnerData}
|
|
76
|
+
* - if the runner has a publish instrument controller, pushes the telemetry
|
|
77
|
+
* through the {@link TelemetryProcessor}
|
|
78
|
+
* - emits a `Telemetry` runner event
|
|
79
|
+
*
|
|
80
|
+
* Notes:
|
|
81
|
+
* - This method only handles unsolicited push telemetry from workers
|
|
82
|
+
* - The incoming payload is expected to contain a serialised `runner`
|
|
83
|
+
* snapshot with updated instrumentation values
|
|
84
|
+
*
|
|
85
|
+
* @param workerEx Worker that produced the telemetry message.
|
|
86
|
+
* @param payloadContents Telemetry payload containing the updated runner snapshot.
|
|
87
|
+
* @throws Re-throws unexpected errors after logging.
|
|
88
|
+
*/
|
|
89
|
+
private _ProcessTelemetry;
|
|
90
|
+
/**
|
|
91
|
+
* Emit a runner-level event for a specific runner.
|
|
92
|
+
*
|
|
93
|
+
* Behaviour:
|
|
94
|
+
* - looks up all registered event handlers for the specified runner id
|
|
95
|
+
* - filters to handlers whose `eventName` matches the supplied event name
|
|
96
|
+
* - resolves the live runner instance from the registry
|
|
97
|
+
* - invokes each matching callback with the live runner instance
|
|
98
|
+
*
|
|
99
|
+
* Notes:
|
|
100
|
+
* - Event subscriptions are stored on the worker in `workerEx.runnersEvents`
|
|
101
|
+
* - The live runner instance is resolved from the registry at emit time so
|
|
102
|
+
* callbacks receive the current runtime object
|
|
103
|
+
*
|
|
104
|
+
* @param eventName Name of the runner event to emit.
|
|
105
|
+
* @param workerEx Owning worker of the runner.
|
|
106
|
+
* @param runnerId Id of the runner whose event should be emitted.
|
|
107
|
+
* @throws Re-throws unexpected errors after logging.
|
|
108
|
+
*/
|
|
109
|
+
private _EmitRunnerEvent;
|
|
110
|
+
/**
|
|
111
|
+
* Process an unsolicited runner state change message.
|
|
112
|
+
*
|
|
113
|
+
* Behaviour:
|
|
114
|
+
* - resolves the live runner instance from the registry
|
|
115
|
+
* - records the previous state for logging/debugging
|
|
116
|
+
* - updates the runner's current state
|
|
117
|
+
* - appends a runner-history entry containing a snapshot of the new state
|
|
118
|
+
* - ensures nested `runnerHistory` is cleared from the history snapshot itself
|
|
119
|
+
* to avoid recursive history growth
|
|
120
|
+
* - updates other live runner fields via {@link SyncRunnerData}
|
|
121
|
+
* - emits a `StateChange` runner event
|
|
122
|
+
*
|
|
123
|
+
* History entry structure:
|
|
124
|
+
* - `eventDate`: timestamp when the state change was processed
|
|
125
|
+
* - `runner`: shallow copy of the inbound runner snapshot
|
|
126
|
+
*
|
|
127
|
+
* Notes:
|
|
128
|
+
* - This is intended for unsolicited push state updates from the worker
|
|
129
|
+
* - The runner history list is lazily initialised if missing
|
|
130
|
+
*
|
|
131
|
+
* @param workerEx Worker that produced the state change.
|
|
132
|
+
* @param payloadContents Payload containing the updated runner snapshot.
|
|
133
|
+
* @throws Re-throws unexpected errors after logging.
|
|
134
|
+
*/
|
|
135
|
+
private _RunnerStateChange;
|
|
136
|
+
/**
|
|
137
|
+
* Synchronise live mutable runner fields from a serialised runner snapshot.
|
|
138
|
+
*
|
|
139
|
+
* Behaviour:
|
|
140
|
+
* - updates iteration
|
|
141
|
+
* - updates state
|
|
142
|
+
* - replaces the current instrumentation payload
|
|
143
|
+
*
|
|
144
|
+
* Intended use:
|
|
145
|
+
* - telemetry processing
|
|
146
|
+
* - worker state synchronisation
|
|
147
|
+
* - state change handling
|
|
148
|
+
*
|
|
149
|
+
* Notes:
|
|
150
|
+
* - This method mutates the live `runnerEx` instance directly
|
|
151
|
+
* - It intentionally updates only the current mutable runtime fields and not
|
|
152
|
+
* the full runner identity/options model
|
|
153
|
+
*
|
|
154
|
+
* @param runnerEx Live runner instance to update.
|
|
155
|
+
* @param runner Serialised runner snapshot containing updated values.
|
|
156
|
+
*/
|
|
157
|
+
SyncRunnerData: (runnerEx: IRunnerEx, runner: IRunner) => void;
|
|
158
|
+
/**
|
|
159
|
+
* Build the list of unsolicited command handlers supported by this lifecycle manager.
|
|
160
|
+
*
|
|
161
|
+
* Current unsolicited commands handled:
|
|
162
|
+
* - `InstrumentTelemetry`
|
|
163
|
+
* - `RunnerStateChange`
|
|
164
|
+
*
|
|
165
|
+
* Each mapping contains:
|
|
166
|
+
* - `command`: the incoming message command
|
|
167
|
+
* - `cb`: the handler to invoke for that command
|
|
168
|
+
*
|
|
169
|
+
* Notes:
|
|
170
|
+
* - This method currently rebuilds the list on each call
|
|
171
|
+
* - Since the mapping is small and static, this is acceptable, though it could
|
|
172
|
+
* be cached later if desired
|
|
173
|
+
*
|
|
174
|
+
* @returns Array of unsolicited command -> handler mappings.
|
|
175
|
+
*/
|
|
176
|
+
private _GetUnsolicitedCommandProcessMap;
|
|
177
|
+
/**
|
|
178
|
+
* Create a message handler function suitable for wiring into a worker's
|
|
179
|
+
* unsolicited-message listener.
|
|
180
|
+
*
|
|
181
|
+
* Behaviour of the returned handler:
|
|
182
|
+
* - interprets the inbound raw data as an {@link IIWMessagePayload}
|
|
183
|
+
* - finds a matching unsolicited command handler from the internal map
|
|
184
|
+
* - if a handler is found, invokes it with:
|
|
185
|
+
* - the specific worker instance for which this handler was created
|
|
186
|
+
* - the inbound message payload cast as `ITestRunnerTelemetryPayload`
|
|
187
|
+
*
|
|
188
|
+
* Typical usage:
|
|
189
|
+
* - one handler is created per worker
|
|
190
|
+
* - that handler is passed into the message broker's port-listener setup
|
|
191
|
+
* - the handler processes only unsolicited push/event traffic
|
|
192
|
+
*
|
|
193
|
+
* Notes:
|
|
194
|
+
* - This method intentionally closes over `stsWorkerEx`, so the returned
|
|
195
|
+
* handler is permanently associated with that worker instance
|
|
196
|
+
* - Solicited request/response messages should already have been handled
|
|
197
|
+
* by the message broker before reaching this handler
|
|
198
|
+
*
|
|
199
|
+
* Future design note:
|
|
200
|
+
* - Runner state changes may eventually be fully embedded in solicited responses,
|
|
201
|
+
* which could make separate `RunnerStateChange` push events redundant and reduce
|
|
202
|
+
* race conditions between awaited commands and subsequent push updates
|
|
203
|
+
*
|
|
204
|
+
* @param stsWorkerEx Worker instance whose unsolicited messages should be processed.
|
|
205
|
+
* @returns A function that processes unsolicited messages for the supplied worker.
|
|
206
|
+
* @throws Re-throws unexpected errors after logging.
|
|
207
|
+
*/
|
|
208
|
+
ProcessMessageHandlerFactory: (stsWorkerEx: IWorkerEx) => (data: any) => void;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=runnerLifecycleManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerLifecycleManager.d.ts","sourceRoot":"","sources":["../src/runnerLifecycleManager.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EAGH,SAAS,EACT,OAAO,EACP,SAAS,EAGZ,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC3C;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IAEnB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;CAClC;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IAC/B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IAEzD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmC;IAEtE;;;;OAIG;gBACS,OAAO,EAAE,8BAA8B;IAKnD;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,iBAAiB,CAqBvB;IAEF;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,gBAAgB,CAkBtB;IAEF;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,OAAO,CAAC,kBAAkB,CAwCxB;IAEF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,cAAc,GAAI,UAAU,SAAS,EAAE,QAAQ,OAAO,UAQpD;IAEF;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,gCAAgC,CAKtC;IAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,4BAA4B,GAAI,aAAa,SAAS,MAC1C,MAAM,GAAG,UAgBnB;CACL"}
|
|
@@ -1,6 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TelemetryProcessor
|
|
3
|
+
* ------------------
|
|
4
|
+
* Responsible for translating raw runner telemetry into updates for the
|
|
5
|
+
* observability instrumentation system.
|
|
6
|
+
*
|
|
7
|
+
* This class acts as the bridge between:
|
|
8
|
+
*
|
|
9
|
+
* - the internal runner telemetry model (`IRunnerTelemetry`)
|
|
10
|
+
* - the external observability instrumentation system
|
|
11
|
+
* (`PublishInstrumentController` from `@nsshunt/stsinstrumentmanagerclient`)
|
|
12
|
+
*
|
|
13
|
+
* The processor interprets telemetry values and updates the appropriate
|
|
14
|
+
* gauges, counters, and histograms defined in the observability model
|
|
15
|
+
* (`@nsshunt/stsobservability`).
|
|
16
|
+
*
|
|
17
|
+
* High-level responsibilities:
|
|
18
|
+
*
|
|
19
|
+
* 1. Convert runner telemetry fields into instrumentation updates
|
|
20
|
+
* 2. Push those updates to the PublishInstrumentController
|
|
21
|
+
* 3. Forward any telemetry log messages
|
|
22
|
+
* 4. Track whether any meaningful update occurred
|
|
23
|
+
*
|
|
24
|
+
* The processor is intentionally stateless. It simply transforms and forwards
|
|
25
|
+
* telemetry values.
|
|
26
|
+
*/
|
|
1
27
|
import { PublishInstrumentController } from '@nsshunt/stsinstrumentmanagerclient';
|
|
2
28
|
import { IRunnerTelemetry } from "./commonTypes";
|
|
29
|
+
/**
|
|
30
|
+
* Processes telemetry emitted by a runner and forwards it to the
|
|
31
|
+
* instrumentation subsystem.
|
|
32
|
+
*/
|
|
3
33
|
export declare class TelemetryProcessor {
|
|
34
|
+
/**
|
|
35
|
+
* Process telemetry data for a runner and publish it through the
|
|
36
|
+
* provided instrumentation controller.
|
|
37
|
+
*
|
|
38
|
+
* Behaviour:
|
|
39
|
+
*
|
|
40
|
+
* - Each telemetry field is mapped to one or more observability gauges.
|
|
41
|
+
* - Only fields with values are processed (except active request count,
|
|
42
|
+
* which is always updated).
|
|
43
|
+
* - Some telemetry values update gauges using:
|
|
44
|
+
*
|
|
45
|
+
* val → set absolute value
|
|
46
|
+
* Inc → increment existing metric
|
|
47
|
+
*
|
|
48
|
+
* - Histogram gauges are updated alongside standard gauges for
|
|
49
|
+
* latency and duration metrics.
|
|
50
|
+
*
|
|
51
|
+
* Logging behaviour:
|
|
52
|
+
*
|
|
53
|
+
* - Any telemetry messages present in `telemetry.message`
|
|
54
|
+
* are forwarded to the publish instrument controller via `LogEx`.
|
|
55
|
+
*
|
|
56
|
+
* Return value:
|
|
57
|
+
*
|
|
58
|
+
* - `true` if any telemetry fields were processed and published
|
|
59
|
+
* - `false` if no update occurred
|
|
60
|
+
*
|
|
61
|
+
* @param publishInstrumentController
|
|
62
|
+
* Controller responsible for publishing metrics/logs to the
|
|
63
|
+
* observability system.
|
|
64
|
+
*
|
|
65
|
+
* @param telemetry
|
|
66
|
+
* Raw telemetry snapshot generated by a runner execution cycle.
|
|
67
|
+
*
|
|
68
|
+
* @returns
|
|
69
|
+
* Boolean indicating whether telemetry updates were applied.
|
|
70
|
+
*/
|
|
4
71
|
ProcessTelemetry: (publishInstrumentController: PublishInstrumentController, telemetry: IRunnerTelemetry) => boolean;
|
|
5
72
|
}
|
|
6
73
|
//# sourceMappingURL=telemetryProcessor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetryProcessor.d.ts","sourceRoot":"","sources":["../src/telemetryProcessor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"telemetryProcessor.d.ts","sourceRoot":"","sources":["../src/telemetryProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAmFjD;;;GAGG;AACH,qBAAa,kBAAkB;IAE3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,gBAAgB,GACZ,6BAA6B,2BAA2B,EACxD,WAAW,gBAAgB,KAC5B,OAAO,CAkNT;CACJ"}
|
|
@@ -1,9 +1,136 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* WorkerTestCases
|
|
4
|
+
* ===============
|
|
5
|
+
*
|
|
6
|
+
* Concrete test worker implementation used to exercise and validate the
|
|
7
|
+
* runner framework.
|
|
8
|
+
*
|
|
9
|
+
* Purpose
|
|
10
|
+
* -------
|
|
11
|
+
* This class acts as a specialised worker-runtime host for framework tests.
|
|
12
|
+
* It extends {@link AbstractRunnerExecutionWorker} and provides concrete
|
|
13
|
+
* runner creation logic for known test-case runners.
|
|
14
|
+
*
|
|
15
|
+
* In other words, this class is the test implementation of the abstract
|
|
16
|
+
* worker-side execution host.
|
|
17
|
+
*
|
|
18
|
+
* It is responsible for:
|
|
19
|
+
* - receiving the transferred message port when used in mocked/manual setups
|
|
20
|
+
* - wiring incoming messages from that port into the standard worker message pipeline
|
|
21
|
+
* - creating the appropriate concrete test runner based on `runner.options.testType`
|
|
22
|
+
*
|
|
23
|
+
* Typical usage
|
|
24
|
+
* -------------
|
|
25
|
+
* This class is useful when validating that the runner framework correctly handles:
|
|
26
|
+
*
|
|
27
|
+
* - worker bootstrap
|
|
28
|
+
* - message routing
|
|
29
|
+
* - runner creation
|
|
30
|
+
* - start/stop/pause/resume/reset/update flows
|
|
31
|
+
* - telemetry flow
|
|
32
|
+
* - state transitions
|
|
33
|
+
* - multiple concrete runner implementations behind the same worker host
|
|
34
|
+
*
|
|
35
|
+
* Supported test runners
|
|
36
|
+
* ----------------------
|
|
37
|
+
* Currently this worker can create:
|
|
38
|
+
*
|
|
39
|
+
* - {@link TestCase01}
|
|
40
|
+
* - {@link TestCase02}
|
|
41
|
+
*
|
|
42
|
+
* The specific runner created is determined by:
|
|
43
|
+
*
|
|
44
|
+
* `runner.options.testType`
|
|
45
|
+
*
|
|
46
|
+
* Architecture note
|
|
47
|
+
* -----------------
|
|
48
|
+
* `WorkerTestCases` lives on the **worker-runtime side** of the framework.
|
|
49
|
+
* It is not the manager/controller. Instead, it is the concrete worker-host
|
|
50
|
+
* that runs inside the actual worker or mocked worker environment.
|
|
51
|
+
*/
|
|
52
|
+
import { IRunnerInstance, ITestRunnerTelemetryPayload } from './../index';
|
|
53
|
+
import { AbstractRunnerExecutionWorker } from './../abstractRunnerExecutionWorker';
|
|
2
54
|
import { JSONObject } from '@nsshunt/stsutils';
|
|
3
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Concrete test worker implementation for the runner framework.
|
|
57
|
+
*
|
|
58
|
+
* This class extends {@link AbstractRunnerExecutionWorker} and supplies
|
|
59
|
+
* concrete runner creation logic for framework test cases.
|
|
60
|
+
*/
|
|
61
|
+
export declare class WorkerTestCases extends AbstractRunnerExecutionWorker {
|
|
4
62
|
#private;
|
|
63
|
+
/**
|
|
64
|
+
* Construct the test worker.
|
|
65
|
+
*
|
|
66
|
+
* Behaviour:
|
|
67
|
+
* - delegates to {@link AbstractRunnerExecutionWorker} constructor
|
|
68
|
+
* - starts the inherited background cleanup/archive loop
|
|
69
|
+
* - prepares the worker to accept port/message bootstrap via `SetPort(...)`
|
|
70
|
+
*/
|
|
5
71
|
constructor();
|
|
72
|
+
/**
|
|
73
|
+
* Manually set and wire the communication port for this worker.
|
|
74
|
+
*
|
|
75
|
+
* Purpose
|
|
76
|
+
* -------
|
|
77
|
+
* This method is particularly useful in mocked or direct in-process test
|
|
78
|
+
* environments where the framework cannot rely on normal native worker
|
|
79
|
+
* bootstrap semantics.
|
|
80
|
+
*
|
|
81
|
+
* Behaviour
|
|
82
|
+
* ---------
|
|
83
|
+
* - extracts the transferred port from the supplied message payload
|
|
84
|
+
* - stores that port locally
|
|
85
|
+
* - attaches a message listener to the port
|
|
86
|
+
* - forwards inbound messages to the inherited `ProcessMessage(...)` pipeline
|
|
87
|
+
* - finally passes the original bootstrap message into `ProcessMessage(...)`
|
|
88
|
+
* so the base class can complete normal worker bootstrap handling
|
|
89
|
+
*
|
|
90
|
+
* Environment handling
|
|
91
|
+
* --------------------
|
|
92
|
+
* Node.js:
|
|
93
|
+
* - incoming data is passed directly to `ProcessMessage(data)`
|
|
94
|
+
*
|
|
95
|
+
* Browser:
|
|
96
|
+
* - incoming data is expected inside `data.data`
|
|
97
|
+
* - forwards `ProcessMessage(data.data)`
|
|
98
|
+
*
|
|
99
|
+
* Notes
|
|
100
|
+
* -----
|
|
101
|
+
* The supplied `message` is expected to contain:
|
|
102
|
+
*
|
|
103
|
+
* - `payload.port`
|
|
104
|
+
*
|
|
105
|
+
* and to otherwise resemble the framework's normal worker bootstrap message.
|
|
106
|
+
*
|
|
107
|
+
* @param message Bootstrap-style message containing the manager communication port.
|
|
108
|
+
*/
|
|
6
109
|
SetPort: (message: JSONObject) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Create a concrete test runner instance for the supplied runner payload.
|
|
112
|
+
*
|
|
113
|
+
* Behaviour
|
|
114
|
+
* ---------
|
|
115
|
+
* - inspects `runner.options.testType`
|
|
116
|
+
* - creates the matching concrete test runner implementation
|
|
117
|
+
* - returns that runner to the base worker host
|
|
118
|
+
*
|
|
119
|
+
* Supported values
|
|
120
|
+
* ----------------
|
|
121
|
+
* - `TestCase01` -> creates {@link TestCase01}
|
|
122
|
+
* - `TestCase02` -> creates {@link TestCase02}
|
|
123
|
+
*
|
|
124
|
+
* If the `testType` is not recognised, `null` is returned, indicating
|
|
125
|
+
* that no executable runner could be created.
|
|
126
|
+
*
|
|
127
|
+
* This method is the key test-specific extension point that makes this
|
|
128
|
+
* class a usable concrete implementation of
|
|
129
|
+
* {@link AbstractRunnerExecutionWorker}.
|
|
130
|
+
*
|
|
131
|
+
* @param testRunnerTelemetryPayload Runner creation payload from the framework.
|
|
132
|
+
* @returns Concrete test runner instance, or `null` if the requested test type is unsupported.
|
|
133
|
+
*/
|
|
7
134
|
CreateAsyncRunner: (testRunnerTelemetryPayload: ITestRunnerTelemetryPayload) => Promise<IRunnerInstance | null>;
|
|
8
135
|
}
|
|
9
136
|
//# sourceMappingURL=mockedWorkerTestRunner01.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockedWorkerTestRunner01.d.ts","sourceRoot":"","sources":["../../src/testing/mockedWorkerTestRunner01.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mockedWorkerTestRunner01.d.ts","sourceRoot":"","sources":["../../src/testing/mockedWorkerTestRunner01.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAQnF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,6BAA6B;;IAW9D;;;;;;;OAOG;;IAKH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,OAAO,GAAI,SAAS,UAAU,UAoB5B;IAEF;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACM,iBAAiB,GACtB,4BAA4B,2BAA2B,KACxD,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAYhC;CACL"}
|